Kubernetes Pod 101

Kubernetes Pod 101

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.:

  1. 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.

  2. 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., port 80).

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

  1. 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.

  2. 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.

  3. 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 setting staticPodPath 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.

Did you find this article valuable?

Support Pratik Jagrut by becoming a sponsor. Any amount is appreciated!