Sysdig
Learn Cloud Native

Sign up to receive our newsletter

What is a Kubernetes Pod?

Pods, as the smallest type of object you can deploy inside a Kubernetes cluster, are the fundamental building blocks of Kubernetes workloads.That’s why Pods are one of the most basic concepts you’ll need to master to use Kubernetes

In this article, we walk through everything you need to know about Kubernetes Pods – including what they are, how they work, how to deploy them, and how to manage them.

What Is a Kubernetes Pod?

In Kubernetes, a Pod is one or more containers that share storage and network resources.

Put another way, a Kubernetes Pod is a set of containers that perform an interrelated function and that operate as part of the same workload. In addition to defining the containers themselves that run within a given workload, each Pod also defines storage and networking configurations for the workload.

Although you could add all the containers for your application into the same Pod, it is a good practice to have one container per Pod. Then, group all the Pods that conform one application into a Namespace.

The option to have more than one container per Pod is meant for auxiliary containers that act as sidecars. For example, a secondary container that extracts metrics from the main container, and exposes it to a Prometheus server.

Put yet another way, a Kubernetes Pod is the object that hosts a container and all its related resources in Kubernetes. One application is often made of several Pods grouped in a separated Namespace.

Pod configurations are defined using YAML files (for more on these, see the following section). Each Pod runs inside the same Kubernetes namespace and on the same physical or virtual machine within your cluster.

Kubernetes Pod YAML Examples

As an example of a basic Pod, here is a YAML file that defines a single-container Pod:

apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80
Code language: CSS (css)

This Pod runs NGINX based on a specific version of the NGINX container image (specifically, 1.14.2). The Pod YAML configuration also defines which port (80) of the container should be accessible.

As another example, consider this multi-container Pod definition:

apiVersion: v1 kind: Pod metadata: name: multi-container-pod spec: containers: - name: container1 image: nginx - name: container2 image: ubuntu

This Pod includes both NGINX and Ubuntu containers.

Single-Container vs. Multi-Container Pods

Single-container Pods are the simplest and most common way to deploy a workload on Kubernetes.

However, multi-container Pods are useful in situations where you want to deploy a primary container (such as one that hosts an application) alongside a secondary container that provides some type of auxiliary functionality (like log aggregation or monitoring) for the primary container.

It’s unusual to deploy two separate applications using a single Pod, unless the applications are interdependent in some low-level way. Although you theoretically could deploy as many independent applications as you want in just one Pod, it would make more sense to use Pods to isolate the applications. 

Distinct Pods can easily interact with each other, especially if they run in the same namespace, and creating a separate Pod for each application helps ensure that problems with one application won’t disrupt other applications. Besides, all containers within a Pod must run on the same node, which can be an issue when it is required to scale the number of Pods.

Pods vs. Nodes

If you’re new to Kubernetes, it’s easy to confuse Pods with nodes. Both of these objects are among the most basic building blocks in Kubernetes.

However, they’re fundamentally different types of resources. A Kubernetes node is a physical or virtual machine that operates as part of a Kubernetes cluster. Pods can run on nodes, but the purpose of a node is to provide host infrastructure, not define and deploy applications. Pods do the latter.

Thus, while Pods are the fundamental building blocks of Kubernetes workloads, nodes are the fundamental building blocks of Kubernetes infrastructure. You need nodes to host Pods (indeed, without nodes, you can’t have a Kubernetes environment at all), but you don’t need Pods to create a node.

Pods vs. Containers

It’s also a mistake to conflate Pods with containers.

As we’ve noted, Pods include containers; in fact, you can’t define or run a Pod without a container. However, Pods include more than just containers. They also define networking and storage configurations, and they can optionally specify commands for Kubernetes to run when it starts a Pod.

Kubernetes Pod Logs

By default, each container generates log data. You can collect the log data from the containers inside a Pod with a command such as:

kubectl logs pod-name

This command will dump log data for the container inside a Pod named pod-name to the CLI. In case the Pod contains multiple containers, a parameter specifying the container name could be added to the command, although it is also possible to extract the logs from all containers at once.

For more advanced logging, you’ll probably want to use a logging technique such as deploying sidecar containers inside each Pod to collect its logs and aggregate them to a central location. That way, you can collect and manage log data centrally and automatically, rather than having to pull it manually from each Pod on the CLI. The Kubernetes documentation offers a detailed overview of advanced logging techniques for Pods and other Kubernetes objects.

Working with Kubernetes Pods

Now that you know how Pods work and how they fit within a Kubernetes environment, let’s look at how to manage Pods.

On most Kubernetes distributions, you’ll use kubectl to interact with Pods. Certain distributions (like OpenShift, which uses the oc utility instead of kubectl by default) have their own tools, although generally these tools accept the same commands as kubectl with regard to Pod management.

Create and Deploy a Pod

To create a new Pod, first create a YAML file that defines it and save that file to the system you use to manage your Kubernetes cluster.

Then, deploy the YAML with a command like:

kubectl apply -f /path/to/pod.yaml

In most cases, you can also grab and deploy Pod YAML files directly from a URL. For example:

kubectl apply -f https://k8s.io/examples/pods/simple-pod.yaml
Code language: JavaScript (javascript)

Alternatively, you can generate a basic YAML file in the CLI with a command like:

kubectl run pod-name --image=nginx --dry-run=client -o yaml > pod.yaml

List Pods

To see which Pods are running, use:

kubectl get pods
Code language: JavaScript (javascript)

Stop a Pod

To stop a Pod that is running, use the following command (where pod-name is the name of the Pod you want to delete):

kubectl delete pod pod-name
Code language: JavaScript (javascript)

If you want to delete all running Pods, use:

kubectl delete pods --all
Code language: JavaScript (javascript)

View Pod Logs

As noted above, you can dump Pod logs to the CLI with:

kubectl logs pod-name

Assigning Pods to Nodes

By default, Kubernetes automatically decides which nodes should host your Pods, unless you specify otherwise.

But in certain cases, you may want to control which nodes in your cluster host a particular Pod. You may want to avoid running production Pods on nodes that you plan to drain and shut off, for example, or you may want to avoid nodes that are experiencing hardware issues.

There are two possible ways to control which nodes host a given Pod:

  • Using nodeSelector: You can specify a nodeSelector definition when writing the YAML for a Pod. NodeSelector tells Kubernetes which node or nodes it can use to host a Pod.
  • Using DaemonSets: DaemonSets are objects that associate Pods with specific nodes. You define them in YAML, and Kubernetes automatically enforces the rules you specify as nodes come and go from your cluster.

Specifying a nodeSelector is the simplest way to assign a Pod to a given node. DaemonSets are a more scalable – albeit also more complex – solution for associating sets of Pods with nodes, as well as maintaining the associations as your cluster scales up or down in size.

Deployments vs. StatefulSets vs. DaemonSets

Kubernetes supports multiple ways of defining how Pods should be deployed: Deployments, StatefulSets and DaemsonSets.

You can use any of these objects to create a template that facilitates Pod deployment and scaling. Deployments are the simplest way to describe a Pod, but StatefulSets are useful if you need to maintain unique Pods. DaemonSets, as noted above, can be used to associate Pods with specific nodes.

Conclusion

Although you could theoretically run a Kubernetes cluster without Pods, you wouldn’t be able to do much with it, because you need Pods to deploy workloads in Kubernetes. And while the YAML files used to control Pods may seem a bit intimidating at first, they’re simple enough to understand once you learn the basics of Pod definitions.

Pods are also easy to manage with basic kubectl commands – but for more complex setups, you’ll also want to teach yourself about features like DaemonSets to help manage Pods effectively at scale.