Chapter 4 - Kubernetes Pods
Yusuf Isah
Posted on August 27, 2024
Introduction
In Kubernetes, the smallest and simplest unit of deployment is a Pod. Pods represent a single instance of a running process in your cluster. They encapsulate one or more containers, their storage resources, a unique network IP, and options that govern how the containers should run. This chapter will explore the concept of Pods, how to create and manage them, and how to ensure their health and performance in a Kubernetes cluster.
Table of Contents
- Pods in Kubernetes
- The Pod Manifest
- Running Pods
- Accessing Your Pod
- Health Checks
- Resource Management
- Persisting Data with Volumes
- Putting it all Together
- Conclusion
Pods in Kubernetes
In Kubernetes, a Pod is the basic execution unit that comprises one or more containers. The term, Pod, is a nod to the Docker whale theme, as it refers to a group of whales swimming together. Similarly, a Pod groups containers together to work as a single, cohesive unit that can share resources and dependencies, communicate with each other, and be co-scheduled.
Key Points About Pods:
Single Unit of Deployment: Pods are the smallest deployable units in Kubernetes.
Shared Context: Containers within a Pod share the same network namespace, Inter-Process Communication (IPC) namespace, and can share storage volumes.
Lifecycle: Pods are created, scheduled, and managed by the Kubernetes control plane.
The Pod Manifest
A Pod manifest is a YAML file that defines the desired configuration of a Pod, utilizing Kubernetes' declarative approach. This means you specify the ideal state of your Pod in the manifest file, and then Kubernetes works to ensure that the actual state matches your declared intentions.
Creating a Pod
You can create a Pod by defining a manifest in YAML and applying it to your Kubernetes cluster.
Creating a Pod Manifest
To create a Pod manifest:
Define the
apiVersion
,kind
, andmetadata sections
.Under
spec
, specify the containers that the Pod should run.
Example Manifest:
apiVersion: v1
kind: Pod
metadata:
name: greetings-pod
spec:
containers:
- name: greetings-container
image: dockeryu853/greetings:1.1
ports:
- containerPort: 8080
Let's name the manifest above greetings.yaml
. To apply the manifest to your Kubernetes cluster, run:
kubectl apply -f greetings.yaml
Running Pods
Once a Pod is created, you can perform various operations to manage and inspect it.
Listing Pods
Run the command below to list all Pods in your cluster:
kubectl get pods
You can see the name of the Pod (greetings-pod) that we gave it in the YAML file. In addition to the number of ready containers (1/1), the output also shows the status, the number of times the Pod was restarted, and the age of the Pod.
If you ran this command immediately after the Pod was created, you might see:
ContainerCreating
means that Kubernetes has received the YAML manifest and is in the process of creating the containers specified in the manifest. If what you see in the status field is Pending
, it means that the Pod has been submitted but hasn’t been scheduled yet. If a more significant error occurs, such as an attempt to create a Pod with a container image that doesn’t exist, it will also be listed in the status field.
To see a list of the pods running in your Kubernetes cluster and observe dynamic changes in real-time, run:
kubectl get pods -w
The command above allows you to observe the dynamic changes in your Pod landscape without needing to repeatedly run the kubectl get pods
command. Press Ctrl+C
to exit watch mode.
In addition, adding -o wide
to any kubectl command will print out slightly more information (while still keeping the information to a single line).
kubectl get pods -o wide
Pod Details
To get detailed information about a specific Pod, run:
kubectl describe pod <pod-name>
Deleting a Pod
To delete a Pod, run:
kubectl delete pod <pod-name>
NB: When you delete a Pod, any data stored in the containers associated with that Pod will be deleted as well. If you need to persist data across multiple instances of a Pod, you need to use Persistent Volumes, described at the end of this chapter.
Accessing Your Pod
Kubernetes provides several ways to interact with and troubleshoot Pods.
Getting More Information with Logs
To view the logs of a container in a Pod, run:
kubectl logs <pod-name> -c <container-name>
Running Commands in Your Containers with exec
To execute a command in a running container:
kubectl exec -it <pod-name> -- <command>
To exec
into the greetings-pod
, run the command below:
kubectl exec -it greetings-pod /bin/sh
To exit, simply run the exit
command inside the pod.
Copying Files to and From Containers
To copy files between your local system and a container:
kubectl cp <file-path> <pod-name>:/path/in/container
kubectl cp <pod-name>:/path/in/container <local-path>
Health Checks
Kubernetes allows you to define health checks to ensure your containers are running as expected.
Liveness Probe
The liveness probe checks if a container is still running. If the check fails, Kubernetes restarts the container.
Example Liveness Probe:
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 3
periodSeconds: 3
The Liveness Probe configuration above will:
Wait 3 seconds after the container starts.
Send an HTTP GET request to http://localhost:8080/healthz every 3 seconds.
If the request fails or returns an error, Kubernetes will consider the container unhealthy and restart it.
Readiness Probe
The readiness probe checks if a container is ready to serve traffic.
Example Readiness Probe:
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 3
periodSeconds: 3
The readiness Probe configuration above will:
Wait 3 seconds after the container starts.
Send an HTTP GET request to http://localhost:8080/ready every 3 seconds.
If the request succeeds (returns a 200 OK response), the container is considered ready to receive traffic.
If the request fails or returns an error, the container is not considered ready, and Kubernetes will not send traffic to it.
Resource Management
You can specify the resources that your Pod's containers require, ensuring they run efficiently.
Resource Requests: Minimum Required Resources
Resource requests define the minimum amount of resources a container needs. These requests serve as a hint to the Kubernetes scheduler to ensure the Pod is placed on a node with sufficient resources. If the node doesn't have enough resources, the Pod won't be scheduled to that node.
Example:
resources:
requests:
memory: "64Mi"
cpu: "250m"
The pod in the YAML manifest above is requesting:
At least 64 MB of memory to be allocated
At least 250 millicores (or 0.25 cores) of CPU processing power
Note that these are requests, not limits. The container can use more resources if available, but it's guaranteed to get at least the requested amount.
Capping Resource Usage With Limits
Resource limits specify the maximum resources a container can use. These limits prevent the container from consuming excessive resources and impacting other workloads running on the same node. If the container tries to use more resources than specified, Kubernetes will take action to enforce the limits, such as terminating the container if it exceeds the memory limit.
Example:
resources:
limits:
memory: "128Mi"
cpu: "500m"
The Pod in the YAML manifest above is restricted to:
Using no more than 128 MB of memory
Using no more than 500 millicores (or 0.5 cores) of CPU processing power
Persisting Data with Volumes
Kubernetes Volumes provide persistent storage to Pods, ensuring data is retained across restarts.
Using Volumes with Pods
apiVersion: v1
kind: Pod
metadata:
name: greetings-pod
spec:
containers:
- name: greetings-container
image: dockeryu853/greetings:1.1
ports:
- containerPort: 8080
volumeMounts:
- name: static-files
mountPath: /static
volumes:
- name: static-files
hostPath:
path: /home/yusbuntu/static
type: Directory
In the YAML manifest above, the VolumeMount is trying to achieve the following:
It's mounting a volume named
static-files
into the container at the path/static
.The static-files volume is defined in the volumes section and is of type hostPath, which means it's a directory on the host machine (the machine running the Kubernetes node).
The path field specifies the directory on the host machine (in this case, my Minikube Virtual Machine),
/home/yusbuntu/static
, which will be mounted into the container. Make sure to change/home/yusbuntu
to your home directory or any other path you prefer.
As stated earlier, if you are using Minikube, you have to create this directory inside Minikube and not on your computer. Below are the steps to follow to create the directory inside Minikube.
minikube ssh
sudo mkdir -p /home/your_user_name/static
Make sure to change your_user_name
to your actual user name.
Putting it all Together
Kubernetes offers a comprehensive set of features, including persistent volumes for data storage, readiness and liveness probes for health monitoring, and resource restrictions for efficient resource allocation, making it an ideal platform for running stateful applications with high reliability and consistency. The manifest below puts this all together.
apiVersion: v1
kind: Pod
metadata:
name: greetings-pod
spec:
containers:
- name: greetings-container
image: dockeryu853/greetings:1.1
ports:
- containerPort: 8080
volumeMounts:
- name: static-files
mountPath: /static
resources:
limits:
memory: "128Mi"
cpu: "500m"
requests:
memory: "64Mi"
cpu: "250m"
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 3
periodSeconds: 3
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 3
periodSeconds: 3
volumes:
- name: static-files
hostPath:
path: /home/yusbuntu/static
type: Directory
NB: Before applying the greetings.yaml
manifest above, make sure to change the path (/home/yusbuntu/static) in your manifest to the path you specified in your Minikube VM.
Next, apply the manifest:
kubectl apply -f greetings.yaml
Follow the steps below to see the contents of the container:
-
Once the container starts running, run the command below:
kubectl get pods -o wide
As you can see from the image above, my IP is 10.244.0.214
-
Next, SSH into Minikube:
minikube ssh
Run the command below to see the contents of the container running inside the pod:
curl http://10.244.0.214:8080
Conclusion
Understanding Pods is fundamental to working with Kubernetes. They encapsulate your application's containers, along with their storage, network, and configuration, into a single deployable unit. By mastering Pods and their associated operations, you can effectively manage your applications in a Kubernetes environment.
Feel free to leave comments and share this article. Follow my blog for more insights on Kubernetes!
Posted on August 27, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.