Kubernetes Communication between Frontend and Backend

For local development, I have a working mini-cube. We deploy different services there. Now I want to link Frontend with Backend.

Frontend is an angular application and lives in its own service. Backend is a node.js application that also uses a separate service and uses DNS to connect to other back-end services like mongodb.

Now I want to communicate with Frontend using Backend. DNS doesn't work because Frontend doesn't know how to resolve the named route. The problem is to tell the interface which firewall url and port it should use to send requests?

The only working state was reversed when I first started the Backend service with type NodePort and copied the URL and port to the Frontends target URL. I think this is very unclean for me. Is there any other approach to get the url for backend requests in Frontend?

I know when we deploy a service on a production system with type = "LoadBalancer" that the service opens with an external IP and I can access the service and then from there. And that the external IP will be persistent across pod updates and so on. The problem I also see is that the backend IP needs to be injected into the docker container with an additional commit.

Edit (1): backend service

apiVersion: v1
kind: Service
metadata:
  name: backend
  labels:
    app: some-app
    tier: backend
spec:
  type: NodePort
  ports:
  - port: 3000
  selector:
    app: some-app
    tier: backend

      

Edit (2): I also get this answer when I ask the client using fqn:

OPTIONS http://backend.default.svc.cluster.local:3000/signup/ net::ERR_NAME_NOT_RESOLVED

      

+3


source to share


3 answers


It depends.

Are you proxying all your internal calls through your external server, or is Angular (running in the user's browser) going directly to your real backend? Are you using any templates like API gateway?

If you are routing (or willing to route) all your microservices / backend call through the backend of your frontend and if you are deploying both your front end and backend to the same k8s cluster in the same namespace then you can use the add-on KubeDNS (if not already available on your k8s cluster, you can check it with k8s admin) to resolve the backend service name to its IP. From your front end server, your backend service will always resolve by its name.

Just curious. What serves your interface (what server-side technology delivers your index.html to the user's browser)? are they static servers like nginx or apache httpd or are you using nodejs here?



Edit

Decision... Since you have kubeDNS in your k8s cluster, and both front-end and backend services are in the same k8s cluster and in the same namespace, we can use k8s's built-in discovery mechanism; the backend service and the external service must be open to each other by name. This means that you can simply use the "backend" DNS name to access your backend service from your front-end modules. So just a proxy for all backend requests through your nginx frontend in front of your backstream service. In the nginx frontend modules, the backend IP address will be resolved for the "backend" domain name. It will also save you the CORS headache. This setup is portable, meaning it doesn't matter if you deploy to dev or stage or prod, the name is "backend"will always be resolved for the corresponding backend.

A potential pitfall with this approach is that your backend cannot scale regardless of the interface. Which is not very important in my humble opinion; In a k8s environment, it is only about increasing the number of pods if necessary.

+3


source


We take a different approach than in the so-random-dude's answer (which is a good solution): we let the backend server serve external files. We have stripped docker images for both, but only use 1 module. The interface acts as an initialization container and copies files to the emptydir volume. The backend also mounts this volume and serves it on /

(all backend resources are served on different paths). This way the frontend and backend are served on the same host.

You can get the current host (which is also the base host now) in your Angular code with window.location.protocol + '//' + window.location.host

.

During development on the local dev machine, we run the frontend and backend on our separate servers. So we have a little helper function to get the correct internal url in all cases:



public getBackendUrl(): string {
  return this.getBackendUrlInternal(window.location.protocol, window.location.host);
}

private getBackendUrlInternal(protocol: string, host: string): string {
  if (host === 'localhost:3000') {
    // running in local dev server, connect to local dev backend
    return 'http://localhost:8585';
  } else {
    // running in docker compose or on k8s, backend is on same host and port as we are
    return protocol + '//' + host;
  }
}

      

(There are 2 methods because we have multiple tests for the second)

+2


source


I would try Kubernetes' own way of flexibly accepting rates with Ingress / IngressController. Havin login controller deployed in your cluster, you can easily create an Ingress definition so that the controller can expose the service under a specific url. All you need to do is point this name in DNS to loadbalancer Ingress Controllers (in most cloud settings, which will be with CNAME in LB fqdn).

https://kubernetes.io/docs/concepts/services-networking/ingress/ https://github.com/kubernetes/ingress

0


source







All Articles