alex
alex

Reputation: 400

Problem when making frontend and backend communicate

i'm working with Minikube to make a full stack K8s application using React as a frontend and ASP NET Core as a backend. Here there are my configuration

Deployments and Services

apiVersion: v1
kind: ServiceAccount
metadata:
  name: web-frontend
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend-deployment
  labels:
    app: frontend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app:
          frontend
    spec:
      serviceAccountName: web-frontend
      containers:
      - name: frontend
        image: frontend
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: frontend-svc
spec:
  selector:
   app: frontend
  ports:
   - protocol: TCP
     port: 80
     targetPort: 80
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: backend
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend-deployment
  labels:
    app: backend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: backend
  template:
    metadata:
      labels:
        app:
          backend
    spec:
      serviceAccountName: backend
      containers:
      - name: backend
        image: backend
        ports:
        - containerPort: 5000
---
apiVersion: v1
kind: Service
metadata:
  name: backend
spec:
  selector:
   app: backend
  ports:
   - protocol: TCP
     port: 5000
     targetPort: 5000

Dockerfiles for the frontend


FROM node:alpine as build-image
WORKDIR /app
COPY package.json ./
COPY package-lock.json ./
RUN npm i
COPY . .
CMD ["npm", "run", "start"]

This is instead my Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: frontend-backend-ingress
  annotations:
#    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  ingressClassName: nginx
  rules:
    - http:
        paths:
          - path: /?(.*)
            pathType: Prefix
            backend:
              service:
                name: frontend-svc
                port:
                  number: 80
          - path: /api/?(.*)
            pathType: Prefix
            backend:
              service:
                name: backend
                port:
                  number: 5000

However, when I type minikube tunnel to expose the ingress IP locally I can reach the frontend, but when the frontend tries to get a fetch request to /api/something in the browser console I get GET http://localhost/api/patients/ 404 (Not Found) and an error SyntaxError: Unexpected token < in JSON at position 0.

Moreover, If I change the Ingress in this way

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: frontend-backend-ingress
  annotations:
#    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  ingressClassName: nginx
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: frontend-svc
                port:
                  number: 80
          - path: /api/
            pathType: Prefix
            backend:
              service:
                name: backend
                port:
                  number: 5000

Then I can issue curl localhost/api/something and I get the JSON result, but when the frontend tries to contact the backend I get

GET http://localhost/api/patients/ 500 (Internal Server Error)
SyntaxError: Unexpected end of JSON input
    at main.358f50ad.js:2:473736
    at s (main.358f50ad.js:2:298197)
    at Generator._invoke (main.358f50ad.js:2:297985)
    at Generator.next (main.358f50ad.js:2:298626)
    at Al (main.358f50ad.js:2:439869)
    at a (main.358f50ad.js:2:440073)

This looks strange because if I try the frontend and the backend outside kubernetes everything works fine and from the React application the result from the backend is correctly fetched (of course using the proxy inside the package.json)

Upvotes: 1

Views: 249

Answers (1)

Bguess
Bguess

Reputation: 2300

To contact or make links between apps you could use their kubernetes native FQDN ( try to ping or telnet it if you want to test the connection but here is how it works: Thr default FQDN of any service is:

 <service-name>.<namespace>.svc.cluster.local.

In your above example, you should be able to contact you backend service from your frontend one with:

backend.YOURNAMESPACENAME.svc.cluster.local:5000

For services in same namespace, you don't need to use the FQDN to access services, just the service name would be enough:

backend:5000

I don't know where you exactly configure the links between the frontend and backend but however, you should "variabilize" this link and add the variable definition in kubernetes manifest.

Upvotes: 1

Related Questions