Orchestration of Containers is one of the most discussed topics in the industry today. Undoubtedly, Docker changed the data center outlook and made way for microservices in the IT industry.
Kubernetes emerged as an amazing tool that has revolutionized the way we do things at work. Kubernetes provided a great deal of flexibility for orchestrating how containers behave and how they communicate with each other. It’s networking implementation is done differently when compared to Docker. Docker networking had limitation like, inter-host container communication was complicated.
So, before understanding Kubernetes networking across pods and hosts or how to reach a pod from an external network, we will have to first understand how is networking implemented in Docker.
Docker networking is limited within the host itself. By default, it creates a virtual bridge named as docker0 and for each container it allocates a virtual ethernet (veth) which gets attached to the bridge docker0. veth to eth0 mapping is done using Linux namespace. So, in Docker two containers can communicate with each other if they reside on the same host.
But, if we need pod communication across host, the containers must be allocated a host port and the packets are forwarded from host port to the containers. This too has its own limitations, two containers on same host cannot share the same host port.
Kubernetes tried to address these problems and categorized the basic container networking into 3 types:
- Intra pod communication of containers using docker0
- Cross node pod-to-pod communications with Service ClusterIP
- Cross node pod-to-pod communication with Service NodePort
The concept of pod was introduced with Kubernetes. Kubernetes defined a pod as a set of containers that share resources deployed on a single host and would be named as a pod. In case a container doesn’t have any sharing resources then pod is equivalent to that single container.
To understand it better I have done the pictorial representation of Host, Pod and Containers. Host has two pods deployed on it. Pod A has two containers running in it and Pod B has only one container.
Intra pod communication of containers:
All the containers in a pod will be assigned the same IP address. So, all containers can directly communicate with each other’s port on localhost within the pod as they share the same IP address and network namespace.So, this implies that containers within a pod will have to coordinate usage of port like VMs do. This is also called “IP-per-pod” model.
But, the drawback here is when a pod goes for reset, the IP address assigned to the pod would be released. Again, when the pod is deployed it can get scheduled on the same host or any other host. So, it would be difficult for other pods to communicate with each other as IP address of a pod is not persistent across reboots.
Hence, for Pod to Pod communication IP address of pods should be known and it’s difficult to maintain the IP address across reboots. To overcome this issue a new type of resource is introduced in Kubernetes named as Service.
A Service is a type of Kubernetes resource that acts as a proxy which forwards requests to a set of pods that provide same functionality. Based on the label and selector, the pod set is defined which will receive the forwarded traffic from the Service.
Service with ClusterIP:
This type of Service will provide discovery and load balancing across pods only inside the Kubernetes cluster, through a cluster-wide common ClusterIPaddress. ClusterIP is assigned out of a dedicated address range and will remain for the life of the Service. Through a set of iptables rule the ClusterIP maps to all the pod’s IPs belonging to the set.clusterIP- service.ymlclusterIP- service.yml12345678910111213kind: Servicemetadata:name: nginxlabels:run: nginxspec:ports:# this is the port we want the service to use- port: 8080# this is the port the container is listening ontargetPort: 80selector:run: nginx
ClusterIP exposes the service on a cluster-internal IP. This IP address makes the service only reachable from within the cluster. This is the default ServiceType.
$kubectl get svc nginx -o wide12Name CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTORnginx 10.98.12.115 <none> 8080/TCP 4m nginx
The above snippet shows that a service of type Cluster-IP is created which would accept traffic on port 8080 from other pods and forward the traffic on port 80 of the pods with nginx label. Pods expose endpoints which is maintained by the Service. If the pod resets, it’s endpoint is automatically removed. You can display the endpoints by describing the Service.
The disadvantage with this type of service is that, its only accessible within the cluster and if we want to reach the pods from outside the cluster we will have to use NodePort type of service.
Service with NodePort:
NodePort exposes the Service with a public IP of Node and a static defined port, so that the pod can be reached from the external network. A Service proxy is created both in case of ClusterIP and NodePort service types and that Service proxy load balances the traffic to the Service endpoints.nodePort-service.yml1234567891011121314kind: Servicemetadata:name: nginxlabels:run: nginxspec:ports:# this is the port we want the service to use- port: 8080# this is the port the container is listening ontargetPort: 80selector:run: nginxtype: NodePort
$kubectl get svc nginx -o wide12Name CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTORnginx 10.98.12.115 <none> 8080:31000/TCP 4m nginx
In the above snippet, port 8080 is the Service’s internal port which would be used for the communication within the cluster. Port 31000 is the NodePort, which is a system selected port from the predefined range. The Kubernetes master allocates a port from a pre-configured range (port range: 30000-32767) and each Node will proxy the same port to the created nginx service. With NodePort type of service configured we can access our Service through public IP address of any node hosting nginx pod and the allocated NodePort.
Hope this article gives a clear understanding about Docker networking and how in Kubernetes communication across pods and hosts is attained and also how to reach a pod from an external network in a Kubernetes cluster setup. So, with this we understand that Kubernetes provides a great deal of flexibility for orchestrating how containers behave, and how they communicate with each other.
You can learn more about Docker Containers and Container Orchestration with Kubernetes by enrolling for our below stated courses:
Please post your queries if any in the comments section below. Also, if you like the article please share it with others.