Introduction
With Kubernetes, our main goal is to run our application in a container. However, Kubernetes does not run the container directly on the cluster. Instead, it creates a Pod that encapsulates the container.
A Pod is the smallest object that you create and manage in Kubernetes.
A Pod consists of one or more containers that share storage and network resources, all running within a shared context. This shared context includes Linux namespaces, cgroups, and other isolation mechanisms, similar to those used for individual containers.
In a Kubernetes cluster, Pods use two models to run containers.:
One-container-per-Pod model: This is the common use case in Kubernetes. A Pod acts as a wrapper for a container, with Kubernetes managing the Pod instead of the individual container. Refer to diagram POD-A.
Multi-containers Pod model: Pods can run multiple containers that work closely together. These Pods hold applications made up of several containers that need to share resources and work closely. These containers operate as a single unit within the Pod. Refer to diagram POD-B.
Anatomy of a Pod
Containers
Main Container
Primary Role: This is the application's primary container.
Example: If you have a web application, the main container will run the web server that serves your application.
Sidecar Containers
Supporting Role: These auxiliary containers support the main container, often used for logging, monitoring, or proxying tasks.
Example: For the same web application, a sidecar container might handle logging by collecting and storing log data generated by the web server.
Storage (Volumes)
Pods can include storage resources known as volumes, which enable data persistence across container restarts. Volumes in a Pod are shared among all containers in that Pod, allowing for data exchange between them.
Types of Volumes:
emptyDir: A temporary directory that is created when a Pod is assigned to a node and deleted when the Pod is removed.
hostPath: Maps a file or directory from the host node’s filesystem into a Pod.
persistentVolumeClaim: A request for storage by a user that binds to a PersistentVolume (PV) in the cluster.
configMap: Provides configuration data, command-line arguments, environment variables, or container files.
secret: Used to store sensitive data such as passwords, OAuth tokens, and SSH keys.
Network
Each Pod is assigned a unique IP address
. Containers within the same Pod share the network namespace, which means they can communicate with each other using localhost
. Pods can communicate with each other using their assigned IP addresses.
Pod IP: A unique IP address assigned to each Pod.
DNS: Kubernetes automatically assigns DNS names to Pods and services, facilitating network communication within the cluster.
Pod Lifecycle
Like individual application containers, Pods are considered to be relatively temporary (rather than permanent) entities. Understanding the lifecycle of a Pod is crucial for effective management and troubleshooting.
Pods can be in one of several phases during their lifecycle. A Pod's status
field is a PodStatus
object, which has a phase
field. The phase of a Pod is a simple, high-level summary of where the Pod is in its lifecycle.
Pending: The Pod has been accepted by the Kubernetes system but one or more container images have not been created.
Running: The Pod has been bound to a node, and all of the containers have been created. At least one container is still running or is in the process of starting or restarting.
Succeeded: All containers in the Pod have terminated successfully, and the Pod will not be restarted.
Failed: All containers in the Pod have terminated, and at least one container has terminated in failure.
Unknown: The state of the Pod cannot be obtained, typically due to an error in communicating with the node where the Pod resides.
Pod Conditions
Pods have a set of conditions that describe their current state. These conditions are used to diagnose and troubleshoot the status of Pods.
PodScheduled: Indicates whether the Pod has been scheduled to a node.
Initialized: All init containers have been completed successfully.
Ready: The Pod can serve requests and should be added to the load-balancer pools of all matching Services.
ContainersReady: All containers in the Pod are ready.
PodReadyToStartContainers: (beta feature; enabled by default) The Pod sandbox has been successfully created and networking configured.
Pod creation
A Pod can be created using two methods. The first method is by using the kubectl run
command.
kubectl run --image nginx nginx-pod
The second method is declarative. In this approach, you create a Pod configuration file in YAML and apply it using the kubectl create
or kubectl apply
command. This method is widely used because it allows you to manage multiple versions of an application easily.
Create a configuration file named nginx-pod.yaml
with the following content.
apiVersion:
kind:
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx-container
image: nginx:latest
ports:
- containerPort: 80
kubectl apply -f nginx-pod.yaml
You can list the pods using kubectl get pods
command.
❯ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-pod 1/1 Running 0 5s
Let's break down the Pod manifest
When writing any object in Kubernetes, you need to include certain required fields: apiVersion
, kind
, metadata
, and spec
.
apiVersion
This field specifies the version of the Kubernetes API that your object adheres to, ensuring compatibility with your Kubernetes cluster (e.g., v1
).
kind
This field defines the type of Kubernetes object being created. In our YAML file, it indicates that we are creating a Pod.
metadata
This section provides essential information about the Pod:
name
: This uniquely identifies the Pod within its namespace (e.g.,nginx-pod
).namespace
: Assigns a specific namespace to the Pod for resource isolation.labels
: These are key-value pairs used to organize and select resources (e.g.,app: nginx
).annotations
: These key-value pairs offer additional details about the Pod, useful for documentation, debugging, or monitoring.ownerReferences
: Specifies the controller managing the Pod, establishing a relationship hierarchy among Kubernetes resources.
spec
The spec
section defines the desired state of the Pod, including its containers and their configurations:
containers
: This list defines each container within the Pod.name
: Identifies the container (e.g.,nginx-container
).image
: Specifies the Docker image to use (e.g.,nginx:latest
).ports
: Indicates which ports should be exposed by the container (e.g., port80
).
Additional Optional Fields: For more advanced setups, you can include additional fields within the spec
section:
resources
: Manages the Pod's resource requests and limits.volumeMounts
: Specifies volumes to be mounted into the container's filesystem.env
: Defines environment variables accessible to the container.volumes
: Describes persistent storage volumes available to the Pod.
Static pods
In Kubernetes, Static Pods offer a way to directly manage Pods on a node without the need for the Kubernetes control plane. Unlike regular Pods that are managed by the Kubernetes API server, Static Pods are managed directly by the Kubelet daemon on a specific node.
How Static Pods Work
Static Pods are defined by creating Pod manifest files on the node itself. These manifest files are usually located in a directory monitored by the Kubelet, such as /etc/kubernetes/manifests
, or a directory specified in the Kubelet's configuration (kubelet.conf
).
Key Characteristics of Static Pods
Node-Specific Management: Each node runs its instance of the Kubelet, which monitors a designated directory for Pod manifests. When a manifest file is detected or updated, the Kubelet creates, updates, or deletes the corresponding Pod on that node.
No Kubernetes API Interaction: Unlike regular Pods that are part of the Kubernetes API and etcd datastore, Static Pods are not managed via the API server. They do not appear in Kubernetes API responses and are not visible through tools like
kubectl
.Use Cases: Static Pods are useful in scenarios where Pods need to run directly on a node, independent of the Kubernetes control plane. This can include bootstrapping components required for Kubernetes itself, or running critical system daemons that must be available even if the control plane is offline.
Creating Static Pods
To create a Static Pod:
Create a Manifest File: Write a Pod manifest YAML file specifying the Pod's metadata and spec, similar to how you define regular Pods.
Place in Watched Directory: Save the manifest file in the directory monitored by the Kubelet (
/etc/kubernetes/manifests
by default). This directory can be configured in the Kubelet configuration file by settingstaticPodPath
to the pod manifests path. Alternatively, it can also be passed to Kubelet through the--pod-manifest-path
flag, but this flag is deprecated.If needed restart the kubelet:
systemctl restart kubelet
Static Pods in Kubernetes are managed directly by the Kubelet and are automatically restarted if they fail. The Kubelet ensures that each Static Pod's state aligns with its specified manifest file. Despite this direct management, Kubelet also attempts to create a mirror Pod on the API server for each Static Pod. This makes the static pod visible to the API server, however, the API server cannot control the pod.
Conclusion
Pods are the core units in Kubernetes, encapsulating containers with shared storage and network resources. They can run single or multiple containers, providing flexibility in application deployment. Understanding Pods' anatomy, lifecycle, and creation methods, including static Pods, is crucial for efficient and scalable application management in Kubernetes environments.
Pods in Kubernetes are inherently ephemeral and can be terminated at any time. Kubernetes uses controllers to effectively manage Pods, ensuring their desired state is maintained. ReplicationSet controllers ensure a specified number of Pod replicas are running. Other controllers like Deployments, StatefulSets, and DaemonSets cater to different use cases.
Thank you for reading this blog; your interest is greatly appreciated, and I hope it helps you on your Kubernetes journey. In the next blog, we'll explore Kubernetes controllers that are used to manage Pods.