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.