Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kubernetes Communication between Frontend and Backend

Tags:

kubernetes

For local development I have a working minikube. There we have different services deployed. Now I want to connect the Frontend with the Backend.

The Frontend is a angular application and lives in its own service. The Backend is a node.js application also using a separate service and uses DNS to connect to other internal services like mongodb.

Now I want to communicate from the Frontend with the Backend. DNS is not working because the Frontend does not know how to resolve the named route. The problem is to tell the frontend which backend URL and port it should use to send requests to?

The only working state was approached 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 to me. Is there another approach to get the url for backend requests into the Frontend?

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

Edit(1): The 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 response when I request from the client with a fqn:

OPTIONS http://backend.default.svc.cluster.local:3000/signup/ net::ERR_NAME_NOT_RESOLVED
like image 951
Lunero Avatar asked Jul 18 '17 11:07

Lunero


People also ask

How do frontend and backend communicate in Kubernetes?

The frontend sends requests to the backend worker Pods by using the DNS name given to the backend Service. The DNS name is hello , which is the value of the name field in the examples/service/access/backend-service. yaml configuration file. Similar to the backend, the frontend has a Deployment and a Service.

How do you communicate with frontend and backend?

Frontend and backend communicate with each other - via Http requests. The frontend will, for example, send entered data to the backend. The backend might then again validate that data (since frontend code can be tricked) and finally store it in some database.

Can Kubernetes pods talk to each other?

Kubernetes assumes that pods can communicate with other pods, regardless of which host they land on. Kubernetes gives every pod its own cluster-private IP address, so you do not need to explicitly create links between pods or map container ports to host ports.


1 Answers

First I will try to address your specific questions

The only working state was approached 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 to me. Is there another approach to get the url for backend requests into the Frontend?

You have couple of options here 1) As you said, use type="LoadBalancer". OR 2) Proxy all your backend calls through your front end server

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

  1. Make it a 12-factor app (or 1 step closer to a 12-factor app :)) by moving the config out from your code to platform (let's say to k8s configmap or an external KV registry like consul/eureka)
  2. Even if it's left in code, as you said, the external IP will be referable and it's not going to change unless you do so. I don't see why you need another deployment

Proxy all your backend calls through your front end server

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

Since you have kubeDNS in your k8s cluster, and both frontend and backend services resides in same k8s cluster and same namespace, we can make use of k8s' inbuilt service discovery mechanism. Backend service and frontend service will be discoverable each other by it's name. That means, you can simply use the DNS name "backend" to reach your backend service from your frontend pods. So, just proxy all the backend request through your front end nginx to your upstream backend service. In the frontend nginx pods, backend service's IP will resolvable for the domain name "backend". This will save you the CORS headache too. This setup is portable, meaning, it doesn't matter whether you are deploying in dev or stage or prod, name "backend" will always resolve to the corresponding backend.

A potential pitfall of this approach is, your backend may not be able to scale independent of frontend; Which is not a big deal in my humble opinion; In a k8s environment, it is just a matter of spinning up more pods if needed.

Just curious- What is serving your front end (which server technology is delivering your index.html to user's browser)? is it static servers like nginx or apache httpd or are you using nodejs here?

like image 130
so-random-dude Avatar answered Sep 17 '22 12:09

so-random-dude