How do I get one pod to network to another pod in Kubernetes? (SIMPLE) How do I get one pod to network to another pod in Kubernetes? (SIMPLE) kubernetes kubernetes

How do I get one pod to network to another pod in Kubernetes? (SIMPLE)


First of all, let's clarify some apparent misconceptions. You mentioned your front-end being a React application, that will presumably run in the users browser. For this to work, your actual problem is not your back-end and front-end pods communicating with each other, but the browser needs to be able to connect to both these pods (to the front-end pod in order to load the React application, and to the back-end pod for the React app to make API calls).

To visualize:

                                                 +---------+                                             +---| Browser |---+                                                                                              |   +---------+   |                                             V                 V+-----------+     +----------+         +-----------+     +----------+| Front-end |---->| Back-end |         | Front-end |     | Back-end |+-----------+     +----------+         +-----------+     +----------+      (what you asked for)                     (what you need)

As already stated, the easiest solution for this would be to use an Ingress controller. I won't go into detail on how to set up an Ingress controller here; in some cloud environments (like GKE) you will be able to use an Ingress controller provided to you by the cloud provider. Otherwise, you can set up the NGINX Ingress controller. Have a look at the NGINX Ingress controllers deployment guide for more information.

Define services

Start by defining Service resources for both your front-end and back-end application (these would also allow your Pods to communicate with each other). A service definition might look like this:

apiVersion: v1kind: Servicemetadata:  name: backendspec:  selector:    app: backend  ports:    - protocol: TCP      port: 80      targetPort: 8080

Make sure that your Pods have labels that can be selected by the Service resource (in this example, I'm using app=backend and app=frontend as labels).

If you want to establish Pod-to-Pod communication, you're done now. In each Pod, you can now use backend.<namespace>.svc.cluster.local (or backend as shorthand) and frontend as host names to connect to that Pod.

Define Ingresses

Next up, you can define the Ingress resources; since both services will need connectivity from outside the cluster (the users browser), you will need Ingress definitions for both services.

apiVersion: extensions/v1beta1kind: Ingressmetadata:  name: frontendspec:        rules:  - host: www.your-application.example    http:      paths:      - path: /        backend:          serviceName: frontend          servicePort: 80---apiVersion: extensions/v1beta1kind: Ingressmetadata:  name: backendspec:        rules:  - host: api.your-application.example    http:      paths:      - path: /        backend:          serviceName: backend          servicePort: 80

Alternatively, you could also aggregate frontend and backend with a single Ingress resource (no "right" answer here, just a matter of preference):

apiVersion: extensions/v1beta1kind: Ingressmetadata:  name: frontendspec:        rules:  - host: www.your-application.example    http:      paths:      - path: /        backend:          serviceName: frontend          servicePort: 80      - path: /api        backend:          serviceName: backend          servicePort: 80

After that, make sure that both www.your-application.example and api.your-application.example point to your Ingress controller's external IP address, and you should be done.


As it turns out I was over-complicating things. Here is the Kubernetes file that works to do what I want. You can do this using two deployments (front end, and backend) and one service entrypoint. As far as I can tell, a service can load balance to many (not just 2) different deployments, meaning for practical development this should be a good start to micro service development. One of the benefits of an ingress method is allowing the use of path names rather than port numbers, but given the difficulty it doesn't seem practical in development.

Here is the yaml file:

apiVersion: apps/v1beta1kind: Deploymentmetadata:  name: frontend  labels:    app: exampleappspec:  replicas: 3  selector:    matchLabels:      app: exampleapp  template:    metadata:      labels:        app: exampleapp    spec:      containers:      - name: nginx        image: patientplatypus/kubeplayfrontend        ports:        - containerPort: 3000---apiVersion: apps/v1beta1kind: Deploymentmetadata:  name: backend  labels:    app: exampleappspec:  replicas: 3  selector:    matchLabels:      app: exampleapp  template:    metadata:      labels:        app: exampleapp    spec:      containers:      - name: nginx        image: patientplatypus/kubeplaybackend        ports:        - containerPort: 5000---apiVersion: v1kind: Servicemetadata:  name: entryptspec:  type: LoadBalancer  ports:  - name: backend    port: 8080    targetPort: 5000  - name: frontend    port: 81    targetPort: 3000  selector:    app: exampleapp

Here are the bash commands I use to get it to spin up (you may have to add a login command - docker login - to push to dockerhub):

#!/bin/bash# stop all containersecho stopping all containersdocker stop $(docker ps -aq)# remove all containersecho removing all containersdocker rm $(docker ps -aq)# remove all imagesecho removing all imagesdocker rmi $(docker images -q)echo building backendcd ./backenddocker build -t patientplatypus/kubeplaybackend .echo push backend to dockerhubdocker push patientplatypus/kubeplaybackend:latestecho building frontendcd ../frontenddocker build -t patientplatypus/kubeplayfrontend .echo push backend to dockerhubdocker push patientplatypus/kubeplayfrontend:latestecho now working on kubectlcd ..echo deleting previous variableskubectl delete pods,deployments,services entrypt backend frontendecho creating deploymentkubectl create -f kube-deploy.yamlecho watching services spin upkubectl get services --watch

The actual code is just a frontend react app making an axios http call to a backend node route on componentDidMount of the starting App page.

You can also see a working example here: https://github.com/patientplatypus/KubernetesMultiPodCommunication

Thanks again everyone for your help.


To use ingress controller you need to have valid domain (DNS server configured to point your ingress controller ip). This is not due to any kubernetes "magic" but due to the way how vhosts work (here is an example for nginx - very often used as ingress server, but any other ingress implementation will work the same way under the hood).

If you can't configure your domain the easiest way for dev purpose would be creating kubernetes service. There is a nice short cut for doing it using kubectl expose

kubectl expose pod frontend-pod --port=444 --name=frontendkubectl expose pod backend-pod --port=888 --name=backend