Part 2

Networking between pods

In part 1 we managed to setup networking configuration to enable routing traffic from outside of the cluster to a container inside a pod. In Part 2 we'll focus on communication between pods.

Kubernetes includes a DNS service so communication between pods and containers in Kubernetes is pretty similar as it was with containers in Docker compose. Containers in a pod share the network. As such every other container inside a pod is accessible from localhost. For communication between Pods a Service is used as they expose the Pods as a network service.

The following service, taken from an exercise in last part, creates a cluster-internal IP which will enable other pods in the cluster to access the port 3000 of todo-backend application in http://todo-backend-svc:2345.

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: todo-backend-svc
spec:
  type: ClusterIP
  selector:
    app: todo-backend
  ports:
    - port: 2345
      protocol: TCP
      targetPort: 3000

Alternatively each Pod has an IP created by Kubernetes.

A debugging pod

Sometimes, the best way to debug is to manually test what is going on. You can just go inside a pod or send a request manually from another pod. You can use eg. busybox, that is a light weight Linux distro for debugging.

Let us start a busybox pod by applying the following yaml:

podfordebugging.yaml

apiVersion: v1
kind: Pod
metadata:
  name: my-busybox
  labels:
    app: my-busybox
spec:
  containers:
  - image: busybox
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
    name: busybox
  restartPolicy: Always

Now we can just exec a command:

$ kubectl exec -it my-busybox -- wget -qO - http://todo-backend-svc:2345

We used the wget command since our usual tool for the purposes, curl, is not readily available in busybox.

We can also open a shell to the pod with command kubectl exec to run several commands:

$ kubectl exec -it my-busybox -- sh
/ # wget -qO - http://todo-backend-svc:2345
<html>
   <body>
      <h1>Kube todo</h1>
      <img src="/picture.jpg" alt="rndpic" width="200" height="200">

      <form action="/create-todo" method="POST">
         <input type="text" name="todo" maxlength="140" placeholder="Enter todo">
         <button type="submit">Create</button>
      </form>

      <ul>
            <li>Buy milk</li>
            <li>Send a letter</li>
            <li>Pay bills</li>
      </ul>
   </body>
</html>/ #
$ exit

You get the same result by using the service cluster IP address. Let us check the address:

$ kubectl get svc
NAME               TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
todo-backend-svc   ClusterIP   10.43.89.182   <none>        2345/TCP   2d1h

The following shows the main page of the todo-app:

$ kubectl exec -it my-busybox -- wget -qO - http://10.43.89.182:2345

Let us try to access a pod directly. We can get the IP address with kubectl describe command:

$ kubectl describe pod todo-backend-dep-84fcdff4cc-2x9wl
Name:             todo-backend-dep-84fcdff4cc-2x9wl
Namespace:        default
Priority:         0
Service Account:  default
Node:             k3d-k3s-default-agent-0/192.168.176.5
Start Time:       Mon, 08 Apr 2024 23:27:00 +0300
Labels:           app=todo-backend
                  pod-template-hash=84fcdff4cc
Annotations:      <none>
Status:           Running
IP:               10.42.0.63

So one of the pods that is running the todo-app has cluster internal IP address 10.42.0.63. We can wget to this address, but this time we have to remember that the port in the pod is 3000:

$ kubectl exec -it my-busybox wget -qO - http://10.42.0.63:3000

Note that in contrast to the last part, we have now created a stand-alone pod in our cluster, there was no deployment object at all. Once we are done, we should destroy the pod, eg. with the command

$ kubectl delete pod/my-busybox

In general, these kinds of "stand-alone" pods are good for debugging but all application pods should be created by using a deployment. The reason for this is that if a node where the pod resides crashes, the stand-alone pods are gone. When a pod is controlled by a deployment, Kubernetes takes care of redeployment in case of node failures.

You have reached the end of this section! Continue to the next section: