A Pod is the smallest Unit of Kubernetes and it runs one or more containers inside it. It can be composed of Single Container or multiple tightly coupled containers. Multiple containers running in the same Pod shares the resources like storages, IP etc. In this article, we’ll delve into Kubernetes Pods, exploring single-container and multi-container deployments, and how Pods are deployed and managed in production environments.

Kubernetes, the ubiquitous container orchestration platform, relies on Pods as its fundamental building block for deploying and managing containerized workloads.

1. Understanding Kubernetes Pods

Imagine a Pod as a lightweight execution unit. Within this unit, you can encapsulate either a single container (functioning as a microservice) or multiple containers that collaborate to deliver a specific application or service.

  • A Pod is the basic building block of Kubernetes applications.
  • Inside a pod exists a group of one or more containers that share networking and storage resources.
  • Pods are ephemeral and disposable, making them ideal for running microservices-based applications.
  • Every pod is assigned an unique internal IP address, using which it can communicate with any other Pods as and when required.

2. Pods vs Containers:

Pods and containers are fundamental concepts in Kubernetes environments. While they are closely related, they serve different purposes and have distinct characteristics. Let’s explore the differences between Pods and containers:

  • Granularity: Containers are the individual units that encapsulate applications, while Pods group one or more containers that need to work together.
  • Scope: Containers are managed by container runtimes and provide process isolation, while Pods are managed by Kubernetes and provide an abstraction layer for container orchestration.
  • Networking: Containers have their own network namespace, while all containers within a Pod share the same network namespace and can communicate with each other using localhost.
  • Lifecycle Management: Containers have their own lifecycle, while Pods manage the lifecycle of all containers within them as a single unit.

Containers:

  • Definition: Containers are lightweight, portable, and self-contained units that encapsulate an application and its dependencies, including libraries and runtime environments.
  • Isolation: Containers provide process isolation, allowing multiple applications to run independently on the same host without interfering with each other.
  • Runtime Environment: Containers rely on container runtimes like Docker or containerd to manage their lifecycle, including starting, stopping, and resource management.
  • Resource Allocation: Containers have their own isolated resources, such as CPU, memory, and network interfaces, which are managed by the container runtime.
  • Networking: Containers typically have their own network namespace, enabling them to communicate with each other or external services through network interfaces.
  • Lifecycle: Containers are short-lived and can be easily created, started, stopped, and destroyed as needed. They are ephemeral and disposable.

Pods:

  • Definition: Pods are the smallest deployable units in Kubernetes, representing one or more containers that share the same network namespace and storage volumes.
  • Grouping: Pods group one or more tightly coupled containers that need to work together and share the same lifecycle, network, and storage.
  • Atomic Unit: Pods are an atomic unit of deployment in Kubernetes, and containers within the same Pod are scheduled and managed together on the same node.
  • Networking: All containers within a Pod share the same network namespace, allowing them to communicate with each other using localhost.
  • Shared Storage: Pods can share volumes mounted into their containers, enabling data sharing and communication between containers.
  • Lifecycle: Pods have a lifecycle independent of the containers they encapsulate. When a Pod is created, Kubernetes creates a unique network namespace and mounts the specified volumes into the containers.

3. Working with Pods in K8s

In this section, we will explore how to create a Pod. Check its status, Update it when required and how to Delete it. I am assuming you have a working Kubernetes Cluster and kubectl is configred and connected to the cluster. More about individual commands will be explained in a separate article.

3.1. Create a Pod

Step-1:
To create a Pod you need to create the yaml file named nginx-pod.yaml with the following content. This is a Single-Container Pod, which means the pod here encapsulates only a single container named nginx.

nginx-pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80

Step-2:
Use the kubectl to create the pod as below

$ kubectl apply -f nginx-pod.yml

Step-3:
Verify that the created Pod is running:

$ kubectl get pods

NAME        READY   STATUS    RESTARTS   AGE
nginx-pod   1/1     Running   0          1m

3.2. Get Pods: list the running pods

The kubectl get pods command is used to retrieve a list of all Pods in the current namespace. The output includes details such as the name of the Pod, the number of containers in the Pod, the status of the Pod, and the age of the Pod. Here is an example of the same.

$ kubectl get pods

NAME                              READY   STATUS    RESTARTS   AGE
my-app-5c6c48d477-6l7qw           1/1     Running   0          10m
my-app-5c6c48d477-7mp8n           1/1     Running   0          10m
my-app-5c6c48d477-8n9io           1/1     Running   0          10m

You can also use the kubectl get pods command with the -o wide flag to get more detailed information about each Pod, including the node on which it is running and its IP address.

$ kubectl get pods -o wide

NAME                              READY   STATUS    RESTARTS   AGE   IP           NODE
my-app-5c6c48d477-6l7qw           1/1     Running   0          10m   10.32.0.4    node-1
my-app-5c6c48d477-7mp8n           1/1     Running   0          10m   10.36.0.5    node-2
my-app-5c6c48d477-8n9io           1/1     Running   0          10m   10.44.0.6    node-3

Often you need to pass additional parameters like namespaces, output format etc. Here are some example:

  • -o or --output: This flag is used to specify the output format. For example, you can use -o wide to display additional information about each pod, such as the node it is running on.
  • You can also use -o yaml or -o json to output the information in YAML or JSON format, respectively.
  • -n or --namespace: This flag is used to specify the namespace where you want to retrieve the pods from. For example, kubectl get pods -n kube-system will retrieve all the pods in the kube-system namespace.
  • -A or --all-namespaces: This flag is used to retrieve all the pods from all the namespaces in the cluster.
  • kubectl get pods -n kube-system: This command will display a list of all the pods in the kube-system namespace.
  • kubectl get pods -A: This command will display a list of all the pods in all the namespaces in the cluster.

3.3. Update or replace Pods

You can not directly update a running Pod in Kubernetes, however you can delete the running one and create a new one instead. For simplicity, you can update the nginx-pod.yml file and run kubectl apply command again. As an example, I will rollback the nginx:version to nginx:1.25.3 instad of latest.

nginx-pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
  - name: nginx
    image: nginx:1.25.3
    ports:
    - containerPort: 80

Please note the output below, now it says the pod is configured instead of created.

$ kubectl apply -f nginx-pod.yml

pod/nginx-pod configured

3.4. Delete pods

Just like the kubectl apply command, there are also several optional paramaters to specify like namespace etc. To delete a running Pod, you can use the kubectl delete command. Here’s an example:

$ kubectl delete pod nginx-pod

pod "nginx-pod" deleted

To delete all Pods in the current namespace.

$ kubectl delete pods --all

4. Pod Lifecycle

The lifecycle of a Pod in Kubernetes refers to the various phases and transitions that a Pod undergoes from its creation to termination. Understanding the Pod lifecycle is essential for managing containerized workloads effectively in Kubernetes environments. Here’s an overview of the Pod lifecycle stages:

  1. Pending: The Pod has been accepted by the Kubernetes system, but one or more of the container images has not been created.
  2. 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 the Pod is in the process of restarting or being terminated.
  3. Succeeded: All containers in the Pod have terminated in success, and will not be restarted.
  4. Failed: All containers in the Pod have terminated, and at least one container has terminated in failure.
  5. Unknown: The state of the Pod could not be obtained, typically due to an error in communicating with the host of the Pod.

Note: When a Pod is being deleted, it is shown as Terminating by some kubectl commands. This Terminating status is not one of the Pod phases. A Pod is granted a term to terminate gracefully, which defaults to 30 seconds. You can use the flag –force to terminate a Pod by force.

In addition to Pod, there are 3 state of a Container running inside pod: Waiting, Running and Terminating:

  • Waiting: The container has been created but not yet started. This is the default state for a new container.
  • Running: The container is currently executing.
  • Terminated: The container has completed its execution and will not be restarted.

5. Types of Pods in Kubernetes:

On a high level there are 2 types of Pods, Single-Container pods and Multi-container pods. We will learn them in details in a later article. Lets us understand them on a High Level here.

1. Single Container Pods:

The most common Kubernetes Pod is one that runs a single container. It’s the smallest and simplest unit in the Kubernetes object model that you create or deploy.

Here is an example of a single container pod. Feel free to run

spring-petclinic-pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: spring-petclinic
  labels:
    zone: prod
    version: 3.2.0
    project: spring-pod-demo
    application: spring-petclinic-3.2.0
spec:
  containers:
    - name: spring-petclinic
      image: dockerbikram/spring-petclinic:3.2.0
      imagePullPolicy: Always
      ports:
        - containerPort: 8080

2. Multi-Container Pods:

To handle auxillary tasks like Service-Mesh, Proxy, tasks like Logging or Monitoring, it might be necessary to run multiple containers within the same Pod. There are several types of Multi-Container Pods:

  • Sidecar Pattern
  • Adapter Pattern
  • Ambassador Pattern
  • Init Container Pattern

Here is an example of the multi-container Pod:

sidecar-pods-example.yml
apiVersion: v1
kind: Pod
metadata:
  name: git-sync
  labels:
    app: sidecar-pods-example
spec:
  containers:
    - name: ctr-webpage
      image: nginx
      volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/
    - name: ctr-sync
      image: k8s.gcr.io/git-sync:v3.1.6
      volumeMounts:
        - name: html
          mountPath: /tmp/git
      env:
        - name: GIT_SYNC_REPO
          value: https://github.com/jstobigdata/sample-html.git
        - name: GIT_SYNC_BRANCH
          value: main
        - name: GIT_SYNC_DEPTH
          value: "1"
        - name: GIT_SYNC_DEST
          value: "html"
  volumes:
    - name: html
      emptyDir: {}

Deploying and Managing Pods in Production:

Do not use static pod in Production environments.

  • Make use of Deployments controllers to deploy and manage Pods in Productions.
  • Utilize Horizontal Pod Autoscaler (HPA) to automatically scale Pods based on CPU or custom metrics.
  • Implement monitoring solutions like Prometheus and Grafana to monitor Pod health and resource utilization.
  • Configure centralized logging with tools like Fluentd and Elasticsearch to collect and analyze Pod logs.
  • Perform rolling updates to Pods to apply changes without downtime, using strategies like RollingUpdate.
  • Implement security best practices such as container image scanning, Pod network policies, and RBAC (Role-Based Access Control) to secure Pods and cluster resources.

Conclusion:

Kubernetes Pods serve as the foundational unit for deploying and managing containerized applications. Whether single-container or multi-container, Pods enable flexible and scalable application deployments in Kubernetes clusters. We will be exploring more details in the later part of this tutorials.

By |Last Updated: April 14th, 2024|Categories: Kubernetes|