Start your free 14-day ContainIQ trial

What is a Kubernetes Pod? | Tutorial

June 24, 2022

This article explains the basics of Kubernetes pods, from how they work to how they’re created and terminated. It also offers suggestions for dealing with common challenges.

Daniel Olaogun
Software Engineer

Kubernetes is used to deploy, manage, and scale containerized applications across multiple node servers. It offers an easier alternative to performing such operations manually or using custom scripts, making it increasingly popular among developers and DevOps engineers.

To get started with this tool, you’ll need to understand its basic concepts, such as Kubernetes pods. The pod, which is the smallest deployable unit in Kubernetes, contains one or more containers tightly coupled together and sharing the same resources.

In this article, you’ll learn about Kubernetes pods, how they work, and why you need to monitor them.

Why Are Pods Important?

Pods abstract one or more containers in your Kubernetes cluster. Each container in a pod shares resources provided by the pod, including IP and storage.

There are several tools you can use to containerize your application, such as Docker, rkt, and runC. Pods serve as an abstraction layer between your container and your cluster.

What Pods Offer

There are several essential features that pods provide to Kubernetes users.

They’re Disposable

Kubernetes pods can be created and deleted as needed. For example, you can add pods to handle an increase in your application traffic and discard them once the traffic returns to normal.

Your Kubernetes controller can delete pods when they’re done with their process execution, and they can also be deleted when your cluster doesn’t have enough resources to run the pod.

They’re Executed in a Node Environment

Kubernetes pods are tightly coupled to the node environment, such that if the node fails, all the pods associated with it die. Sometimes, a node can also evict pods from its environment if the pods exceed their memory limit consumption on the node. Furthermore, if a pod is using more CPU resources than normal, the node throttles the CPU resource consumption for that pod. This is done to ensure the node is healthy for a longer time.

They Can Run Multiple Containers

Pods can abstract multiple containers that share the resources provided by the pod, such as network, storage, and memory. It’s generally important to have a one-to-one relationship between a pod and a container, but there are scenarios where it’s necessary to run multiple containers in a pod.

For example, say you deployed an application on your Kubernetes cluster, and you configured a volume storage to save your application logs. However, it becomes difficult for you to view and analyze your application logs from your command-line terminal. Instead of manually exporting these logs to a log analyzer tool, you can create a separate service that extracts logs from the storage and sends them to a central log system for visualizing and analyzing the logs properly. This process can be done using a multi-container pod while taking advantage of the shared volume storage and network feature, which allows multiple containers in the same pod to share the same storage and network.

K8s Metrics, Logging, and Tracing
Monitor the health of your cluster and troubleshoot issues faster with pre-built dashboards that just work.
Start Free Trial Book a Demo

How Kubernetes Pods Work

Here’s what you need to know about how pods function and what their lifecycle looks like.

Single vs Multiple Container Pods

Pods can contain either a single container or multiple containers sharing the same resources.

A common option for shared container pods is the sidecar design, where the pod contains a main container and a helper, or sidecar, container that extends the functionality of the main container. For example, your main container could be a community forum application that allows users to upload photos, and your sidecar container could reduce photo sizes before they’re saved to your file storage.

Pods and Controllers

Kubernetes controllers make sure that the cluster always remains in the desired state. The controller replicates the pods in your cluster based on your application workload, and when a pod dies, it creates another pod and puts in a healthy node with the resources to run it. The controller also removes pods from the cluster when they’re no longer needed.

How Pods Are Created

There are several ways to create pods in your Kubernetes cluster. They include using the pod object, using the ReplicaSet, and using Deployments.

Using the Pod Object

Create a YAML file named <terminal inline>my_app_pod.yaml<terminal inline> and paste the code below:


apiVersion: v1

kind: Pod

metadata:
    name: my_app

spec:
   containers:
     - image: containeriq/my_app
        name: my_app
        ports:
        - containerPort: 8080

In your terminal, run the command <terminal inline>kubectl apply -f my_app_pod.yaml<terminal inline>, which automatically creates a pod in your cluster.

You can also create pods using the imperative approach:


kubectl run my_app --image= containeriq/my_app --labels=tier=db

Using the ReplicaSet

Create a YAML file named <terminal inline>my_app_replica_set.yaml<terminal inline> and paste the code below:


apiVersion: apps/v1

kind: ReplicaSet

metadata:
  name: my_app
  labels:
    app: gymmaster
    tier: backend

spec:
  replicas: 3
  selector:
    matchLabels:
      tier: backend
  template:
    metadata:
      labels:
        tier: backend
    spec:
      containers:
      - name: my_app
        image: containeriq/my_app

In your terminal, run the command <terminal inline>kubectl apply -f my_app_replica_set.yaml<terminal inline>. This creates a ReplicaSet in your cluster, which ensures that the <terminal inline>my_app<terminal inline> pod has a set number of pods always running.

Using Deployments

Create a YAML file named <terminal inline>my_app_deployment.yaml<terminal inline> and paste the code below:


apiVersion: apps/v1

kind: Deployment

metadata:
  name: my_app
  labels:
    app: gymmaster
    tier: backend

spec:
  replicas: 3
  selector:
    matchLabels:
      tier: backend
  template:
    metadata:
      labels:
        tier: backend
    spec:
      containers:
      - name: my_app
        image: containeriq/my_app

Run the command <terminal inline>kubectl apply -f my_app_deployment.yaml<terminal inline> in your terminal.

<terminal inline>Deployment<terminal inline> performs similarly to <terminal inline>ReplicaSet<terminal inline>, ensuring that a specified number of pods is available in the cluster. However, <terminal inline>Deployment<terminal inline> offers the additional feature of rolling updates. This ensures that whenever you update your <terminal inline>Deployment<terminal inline> file, it gets to the desired state without causing downtime. For instance, in your YAML file, if you replace your container image with a new version, <terminal inline>Deployment<terminal inline> updates all the pods in your cluster with the new version one by one, so that if there is a bug with the new image, you can quickly roll back without causing downtime.

How Pods and Nodes Work Together

Nodes are either physical or virtual computing machines that run your pods’ processes. Managing your applications independently on multiple nodes can be a herculean task. Pods are an abstraction of your containerized applications, and the pods run on nodes in the Kubernetes cluster. Kubernetes uses the control plane to distribute workloads to the available nodes in the cluster in order to increase efficiency and performance.

How Pods and Containers Work Together

Containers are applications that are packaged with their execution environments. They bundle all the dependencies, libraries, and binaries required for your application to work, so that the difference in operating system distribution and the underlying infrastructure is abstracted away.

Pods were introduced so that Kubernetes wouldn’t be tied to a specific vendor. They abstract the containers in the cluster, meaning that you can package your application using any vendor recognized by Kubernetes.

Pod Networking

Each pod in the Kubernetes cluster has a unique IP address. The containers in a pod share network resources including the IP and port, and they can communicate with each other using localhost. However, if a container wants to communicate with another container in a different pod, it is advisable to use Kubernetes services for communication.

There are different service type options available depending on how you want to expose the pod communication, either internally available in the cluster or externally outside of the cluster. The service types include <terminal inline>ClusterIp<terminal inline>, <terminal inline>NodePort<terminal inline>, <terminal inline>LoadBalancer<terminal inline>, and <terminal inline>ExternalName<terminal inline>; more information about these service types can be found here.

Pod Lifecycle

Kubernetes pods go through different series of states from creation to termination. When you create a pod, the initial state is “pending,” or waiting for the network to download the application image. Once the image is downloaded, the container is ready to run and is bound to the pod. Now its state is “running,” meaning the pod is ready to receive and process requests.

Once the container has completed its process, the pod is terminated and the status changes to “succeeded.” If the pod is terminated due to an error, its status changes to “failed” and an event is recorded. An “unknown” status indicates that the pod status can’t be obtained, which typically means there is an error in communication between the running pod and the node.

Pod Conditions

Pods have a <terminal inline>PodStatus<terminal inline> that contains an array called <terminal inline>PodConditions<terminal inline>. <terminal inline>PodConditions<terminal inline> has a type and status field that shows the conditions causing its current status. Its conditions include:

  1. <terminal inline>PodScheduled<terminal inline>: This means the pod has been scheduled for a node.
  2. <terminal inline>Initialized<terminal inline>: This means that init containers have been completed successfully. These are containers that run before the main app containers. They must run completely before the next container can run. If the <terminal inline>init container<terminal inline> fails, it’s restarted until it succeeds.
  3. <terminal inline>ContainersReady<terminal inline>: This shows that all the containers are in a ready state.
  4. <terminal inline>Ready<terminal inline>: The pod is ready to receive and process requests.

Pod Termination

It’s better to gracefully terminate a pod when it’s no longer needed instead of terminating it abruptly. This ensures that the pod cleans up before it’s deleted completely. By default, Kubernetes provides a graceful termination period of thirty seconds from the time of the termination request initiation.

In order to override the default grace period when deleting a pod, add this <terminal inline>--grace-period<terminal inline> option:


kubectl delete pod my_app --grace-period=45

Pod Storage

Using the container’s file system for storage is ephemeral, meaning that the storage will be available as long as the container is running. If you end and restart your container, everything you’ve stored will disappear. For consistent storage that isn’t dependent on containers, use volumes.

Some volumes are available until the pod dies, while others aren’t dependent on pods. Kubernetes supports several types of volumes for storage.

Monitoring Pods

Monitoring the pods is important for the overall health and performance of the Kubernetes cluster. It allows you to see how your pods are functioning, spot bottlenecks, reduce wasted costs, and improve the performance of your application. You can check the number of pod instances available, the health of the pod, the memory usage of the pod, and the CPU consumption, among other factors.

There are several tools you can use to monitor your pods, including Prometheus, Metrics Server, and ContainIQ. ContainIQ is a Kubernetes native monitoring and observability platform.

ContainIQ Pod Metrics Dashboard

ContainIQ’s Pods dashboard is helpful for viewing core metrics, statuses, changes over time, and to associate events to each pod. Using ContainIQ, users are able to set alerts on events related to changes in pod status. For example, using ContainIQ, users are able to set events on pods restarting, memory issues, and also on significant changes in memory or CPU.

Final Thoughts

Pods are an essential part of using Kubernetes. Having a solid understanding of how pods function and how best to use them can help you better manage your Kubernetes clusters and your applications.

If you need a tool to monitor your Kubernetes cluster, consider ContainIQ. The platform offers pre-built dashboards for ease of use and helps you track memory, latency, events, and logs so that you can optimize your Kubernetes usage. For more info, see the documentation.

Start your free 14-day ContainIQ trial
Start Free TrialBook a Demo
No card required
Daniel Olaogun
Software Engineer

Daniel is a Software Engineer with 5 years of experience building software solutions in a variety of fields. Today, he works as the Lead Software Engineer at Whitesmith. Daniel has a Bachelor’s Degree in Computer Science from the University of Lagos.

READ MORE