On this third post of the series I’m going to talk about Kubernetes Pods. Kubernetes documentation defines a pod as “a group of one or more containers (such as Docker containers), with shared storage/network, and a specification for how to run the containers“. Kubernetes Pods are the smallest unit of computing that can be deployed and managed by Kubernetes.
Deep-diving into Kubernetes Pods
In the first place let’s walk through few key aspect of the Kubernetes Pods. Later on we will move on to the hands on labs.
A Kubernetes pod runs on a given node, it means a single pod cannot be stretched across multiple nodes. You can deploy more of the same pod, but it will be tied to a node. Also, a pod cannot be live migrated to another node like happens with virtual machines.
You cannot set resources to Kubernetes pods. The resource configuration happens at the container level in your pod definition. In order to successfully deploy a pod, your namespace must have enough resources.
From network point of view a routable IP address is assign to a given pod. Containers within a pod share an IP address and port space, and can find each other via
localhost. You cannot have more than a container within the same pod listening on the same port. On the hands on section you will find an example.
In addition, containers in different pods have distinct IP addresses and can not communicate by IPC (inter-process communication)
The storage claimed by a pod is shared with all the containers within that pod. Once a persistent volume is claimed by a pod, it cannot be claimed/attached by another pod. Volumes enable data to survive container restarts and to be shared among the applications within the pod.
By default the kube-scheduler service ensures that pods are only placed on nodes that have sufficient free resources. Also, it tries to balance out the resource utilisation of nodes.
Since Kubernetes 1.6 it offers advanced scheduling features: node affinity/anti-affinity, taints and tolerations, pod affinity/anti-affinity, and custom schedulers.
The service kube-scheduler ensures a pod always is up and running in the event of a failure. If the Kubernetes node containing the pod fails, or your pod crashes, kube-scheduler will instantiate another pod for you.
With a single pod your availability is compromised if that fails. On a future post I’ll show you how to create replicas of your pod to improve its availability. ReplicaSet is the next-generation Replication Controller. A ReplicaSet ensures that a specified number of pod replicas are running at any given time. ReplicaSet should not be directly used, instead a deployment object as a high-level entity is recommended.
Kubernetes Pods Lifecycle
Before we start with the creation, read, update, and delete (CRUD) of Kubernetes pods, I’d like to highlight an important recommendation. You should not directly instantiate a pod ever. I’m doing it for the sake of the post. You should always use a Kubernetes controller like Deployments, Job, or StatefulSet.
Creating Kubernetes Pods
First thing to remember is how works the Kubernetes Namespaces. If you are not familiar with namespaces, I suggest you to read my post Hands-on: Kubernetes Namespaces. We are going to work with two namespaces to showcase the connectivity between pods on different namespaces.
Unlike namespaces, to create a Kubernetes pod you must use a manifest. On our example we are going to use the namespaces production and development. Let’s create our first namespace (production) and a pod with Nginx at the same time.
From any of your servers, master or nodes, you can check the Nginx container is accesible. Use curl and the IP address from the previous command.
Let’s create the second namespace development with a busybox container.
Now you will check the busybox container is able to open the Nginx site despite it is on a different namespace. The following command open a connection to a given container. Also, you will use wget to confirm the Nginx website is accessible from the busybox container. The IP address to use with wget can be gather listing the production namespace pods (kubectl -n production get pods -o wide)
Reading Kubernetes Pods
To read any given Kubernetes object you use the option describe.
Take a look to each of the pod settings. You can see they are not hard to understand.
Updating Kubernetes Pod
The update options are limited when you directly deploy a Kubernetes pod. For example you cannot add or remove containers from a pod. You can update a pod on different ways. You will learn how to update a pod using patch and replace.
With kubectl patch you modify on fly the pod configuration. Let’s patch the Nginx pod running in the production namespace with a different Nginx version. Important to realize the container is destroyed and re-created with the new version, it means the service has an outage. The pod uptime is not restarted.
First thing to do is to check the current Nginx version with kubectl exec. The double dash after -it is required when you have more than an argument (nginx -v)
Let’s downgrade the Nginx version to 1.12 using kubectl patch. For the patch argument you just use the JSON blob for the spec section of your pod manifest. You can see the image key value pair has been updated with nginx:1.12.
Check again the Nginx version.
Before you move to the next section, deleting Kubernetes Pods, let’s replace our busybox pod in the namespace development with a new pod with two containers. The objective is to showcase how the network traffic is within a pod when you have more than a container. Remember the containers within a pod communicate each other through localhost.
First let’s update the development.yaml file to include the new Nginx container.
Now you will replace the current busybox pod with the new version of the manifest file. Since add or remove containers in a pod is not possible, you will use the option ‐‐force to delete and re-create the namespace and pod. Delete the pod takes a while because a graceful shutdown of the pod is done.
If you run the following command will see the pod includes now two containers (kubectl -n development describe pod busybox)
Let’s check if the busybox container is able to get the web page provided by Nginx.
Deleting Kubernetes Pods
The command to delete a pod is the same than the one to delete a namespace but changing the kind of object. When you delete a pod Kubernetes will try gratefully terminate the pod. It is important when you have volumes attached to your pod.
Let’s destroy the busybox pod in the namespace development and later destroy the rest of objects you have created for this post.
Let’s delete the rest of objects
If you have survived until here, congratulations! It was a long post but I’ve wanted to cover the most important aspects of Kubernetes Pods. This is a good start point to get familiar with the pod architecture and lifecycle.
Pods are the meat of Kubernetes. You must practice as much as you can with pods in order to troubleshoot your container platform in case of failures.
On future posts I’ll show you how the pods can be abstracted on other high-level objects also know as controllers.