This is the first part of three articles explaining and detailing the Kubernetes Network model with a hands-on approach. The series will discuss Pod-to-Pod communication, Pod-to-Service communication, and Ingress / Ingress Controllers. These articles are based on a repository I created which contains more examples and content. I invite you to review the repo at https://github.com/rafaelmnatali/kubernetes.
Pod-to-Pod communication
Because every pod gets a "real" (not machine-private) IP address, pods can communicate without proxies or translations within the Kubernetes cluster. Let's see this in action.
I will use NGINX as an example:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: default
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
initContainers:
- name: init
image: busybox
command: ['sh', '-c', 'echo "Welcome to the home page of host $(hostname)!" > /usr/share/nginx/html/index.html']
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
containers:
- name: nginx
image: nginx
ports:
- name: http-web-svc
containerPort: 80
protocol: TCP
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
emptyDir: {}
These are the Pods (shortened version) :
NAME READY STATUS RESTARTS AGE IP
nginx-6bfd886fb5-fvngf 1/1 Running 6 (30h ago) 9d 10.244.2.84
nginx-6bfd886fb5-n65xn 1/1 Running 6 (30h ago) 9d 10.244.2.82
nginx-6bfd886fb5-szz7q 1/1 Running 6 (30h ago) 9d 10.244.2.81
Use the nicolaka/netshoot image to execute network validations.
kubectl run tmp-shell --rm -i --tty --image nicolaka/netshoot -- /bin/bash
Using the Pod IP address
tmp-shell:~# ping -c1 10.244.2.84
PING 10.244.2.84 (10.244.2.84) 56(84) bytes of data.
64 bytes from 10.244.2.84: icmp_seq=1 ttl=64 time=0.544 ms
--- 10.244.2.84 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.544/0.544/0.544/0.000 ms
We successfully sent and received one request.
As NGINX is a web server, we can use the curl command to send an HTTP request.
tmp-shell:~# curl 10.244.2.84
Welcome to the home page of host nginx-6bfd886fb5-fvngf!
tmp-shell:~# curl 10.244.2.82
Welcome to the home page of host nginx-6bfd886fb5-n65xn!
We can see that both requests were successful. Each request connects to a different Pod and returns the web server's home page.
Using the Pod Name
If we try ping the Pod using their assigned name, we receive an error:
tmp-shell:~# ping -c1 nginx-6bfd886fb5-fvngf
ping: nginx-6bfd886fb5-fvngf: Name does not resolve
That's why a Pod has the following DNS resolution:
pod-ip-address.my-namespace.pod.cluster-domain.example.
This time, use ping and curl with the Pod DNS name:
tmp-shell:~# ping -c1 10-244-2-84.default.pod.cluster.local
PING 10-244-2-84.default.pod.cluster.local (10.244.2.84) 56(84) bytes of data.
64 bytes from 10.244.2.84 (10.244.2.84): icmp_seq=1 ttl=64 time=0.169 ms
--- 10-244-2-84.default.pod.cluster.local ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.169/0.169/0.169/0.000 ms
tmp-shell:~# curl 10-244-2-84.default.pod.cluster.local
Welcome to the home page of host nginx-6bfd886fb5-fvngf!
Both commands return the expected results.
Summary
In this article, I demonstrated two examples of how and why Pods communicate with each other in Kubernetes. These commands come in handy when troubleshooting communication issues, where we need to ensure that the Pods communicate independently of any other Kubernetes component, such as a Service.
However, if applications in different Pods need to communicate with each other, relying solely on the IP address is not the best practice. In such cases, we should use a Service instead. In the next article, I will provide some examples of how Pods can communicate with Services.
Commentaires