Pods are the smallest and simplest unit of deployment in Kubernetes. A pod is a group of one or more containers that share the same network namespace, storage resources, and lifecycle. Pods allow you to run multiple containers together as a single unit, which is useful for applications that have tightly coupled components or dependencies.
In this blog post, we will cover the following topics:
- Containerization Process: How containers are created and isolated from the host system.
- Container Concepts: The basic concepts and terminology of containers and Kubernetes.
- Creating Pods: How to create pods using YAML manifests or kubectl commands.
- Listing Pods: How to list and filter pods using kubectl commands and labels.
- Pod Life Cycle Phases: The different phases of a pod’s lifecycle and how to monitor them.
- Rendering Pod Details: How to view detailed information about a pod using kubectl commands and flags.
- Accessing Logs of a Pod: How to access the logs of a pod’s containers using kubectl commands and flags.
- Deleting a Pod: How to delete a pod using kubectl commands and labels.
- Configuring Pods: How to configure various aspects of a pod such as resource limits, readiness probes, liveness probes, etc.
Containerization Process
Containers are lightweight and portable software packages that contain everything needed to run an application: code, libraries, dependencies, configuration files, etc. Containers are created from images, which are snapshots of the application and its dependencies at a specific point in time. Images are stored in registries, which are repositories of images that can be accessed by users or other systems.
Containers are isolated from the host system by using namespaces, cgroups, and other kernel features. Namespaces provide a virtualized view of the system resources such as network, filesystem, process IDs, etc. Cgroups limit the amount of resources such as CPU, memory, disk I/O, etc. that a container can use. Other kernel features such as seccomp, AppArmor, SELinux, etc. provide additional security and isolation for containers.
Container Concepts
Before we dive into pods, let’s review some basic concepts and terminology of containers and Kubernetes.
- Container Runtime: The software that runs and manages containers on a node. Examples of container runtimes are Docker, containerd, CRI-O, etc.
- Node: A physical or virtual machine that runs one or more pods. A node can have multiple CPUs, memory, disk space, network interfaces, etc.
- Cluster: A group of nodes that work together to run pods and provide services. A cluster can have one or more master nodes and worker nodes. Master nodes run the control plane components such as the API server, scheduler, controller manager, etc. Worker nodes run the kubelet and kube-proxy agents that communicate with the control plane and manage the pods on the node.
- Kubelet: The agent that runs on each node and communicates with the control plane. The kubelet is responsible for creating, starting, stopping, and deleting pods on the node based on the instructions from the control plane.
- Kube-proxy: The agent that runs on each node and provides network services for the pods. The kube-proxy is responsible for implementing the service abstraction by routing traffic to the appropriate pods based on their labels and selectors.
- Service: An abstraction that defines a logical set of pods and a policy to access them. A service provides a stable and consistent way to access pods regardless of their location or number. A service can have one or more endpoints, which are IP addresses and ports of the pods that match the service’s selector.
- Label: A key-value pair that is attached to an object such as a pod or a service. Labels are used to identify and group objects based on common attributes or criteria. For example, you can label pods with their app name, environment name, version number, etc.
- Selector: A query that matches objects based on their labels. Selectors are used to filter objects based on their labels. For example, you can select pods with the label app=nginx or services with the label environment=production.
Creating Pods
There are two main ways to create pods in Kubernetes: using a pod manifest file or using a pod template. A pod manifest file is a YAML or JSON file that defines the pod’s specifications, such as its name, labels, containers, volumes, etc. A pod template is a part of another resource definition, such as a deployment or a stateful set, that describes how to create pods for that resource.
To create a pod using a manifest file, you can use the kubectl create command and specify the file name as an argument. For example:
kubectl create -f my-pod.yaml
To create a pod using a template, you can use the kubectl apply command and specify the resource definition file as an argument. For example:
kubectl apply -f my-deployment.yaml
Listing Pods
To list all the pods in your cluster, you can use the kubectl get command and specify pods as the resource type. For example:
kubectl get pods
To list pods in a specific namespace, you can use the -n flag and specify the namespace name. For example:
kubectl get pods -n my-namespace
To list pods with more details, such as their status, IP address, node name, etc., you can use the -o wide flag. For example:
kubectl get pods -o wide
To list pods with custom columns, you can use the -o custom-columns flag and specify the column names and expressions. For example:
kubectl get pods -o custom-columns=NAME:.metadata.name,NODE:.spec.nodeName
Pod Life Cycle Phases
A pod can go through different phases during its life cycle. The current phase of a pod is stored in its status.phase field. The possible phases are:
- Pending: The pod has been accepted by the Kubernetes system, but one or more of its containers have not been created. This includes time before being scheduled as well as time spent downloading images over the network.
- Running: The pod has been bound to a node, and all of its 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 in success, and will not be restarted.
- Failed: All containers in the pod have terminated, and at least one container has terminated in failure. A container exits in failure if it returns a non-zero exit code when it terminates.
- Unknown: The state of the pod could not be obtained, typically due to an error in communicating with the node where it is running.
Rendering Pod Details
To view more information about a specific pod, you can use the kubectl describe command and specify the pod name as an argument. For example:
kubectl describe pod my-pod
This command will show you various details about the pod, such as its events, conditions, containers, volumes, etc.
Accessing Logs of a Pod
To view the logs of a specific container in a pod, you can use the kubectl logs command and specify the pod name and optionally the container name as arguments. For example:
kubectl logs my-pod
kubectl logs my-pod -c my-container
This command will show you the standard output and standard error of the container.
To view the logs of all containers in a pod, you can use the –all-containers flag. For example:
kubectl logs my-pod –all-containers
To view the logs of a previous instance of a container in a pod, you can use the –previous flag. This is useful when a container has crashed or restarted. For example:
kubectl logs my-pod -c my-container –previous
Deleting a Pod
To delete a specific pod from your cluster, you can use the kubectl delete command and specify the pod name as an argument. For example:
kubectl delete pod my-pod
This command will delete the pod and all its associated resources.
To delete multiple pods that match a label selector, you can use the -l flag and specify the label expression. For example:
kubectl delete pods -l app=my-app
This command will delete all pods that have the label app=my-app.
Configuring Pods
To configure a pod, you need to create a pod manifest file that specifies the metadata, containers, volumes, and other settings of the pod. You can use YAML or JSON format for the pod manifest file. The pod manifest file defines the desired state of the pod, such as what image to use, what ports to expose, what environment variables to set, etc.