Kubernetes 101 — Pods & Controllers

Yitaek Hwang
5 min readJun 21, 2023

--

Kubernetes for Developers: Part III

Photo by Ian Taylor on Unsplash

Welcome to Part III of the “Kubernetes for Developer” series!

This week, we’ll finally dive into Kubernetes concepts, starting with the very basics. Kubernetes is often cited as having a steep learning curve. While that is true to a certain extent, as developers, you don’t need to learn everything to become a productive user of Kubernetes. In fact, we just need some of the tip of the iceberg type knowledge to start poking around and building/running/debugging our applications. In most organizations, the “hard” stuff will be handled by Kubernetes experts (presumably on infra teams) dealing with administration and provisioning.

So without further ado, let’s dive in!

This series is brought to you by DevZero.

DevZero’s platform provides cloud-hosted development environments. With DevZero, you can reuse your existing infrastructure configuration to configure production-like environments for development and testing.

Check out DevZero at devzero.io to get started today!

Pods & Nodes

A pod is the smallest deployable unit in Kubernetes. In more practical terms, it is simply a group of one or more containers with shared resources (e.g., storage, network) deployed and managed by Kubernetes. A pod defines which containers and resources are needed along with conditions to run them. In turn, Kubernetes controller takes those specifications and schedules a pod onto nodes.

A node is a virtual or physical machine managed by Kubernetes. When you are interacting with a cloud-based Kubernetes cluster, these are simply VMs like EC2 machines running Kubernetes components (we’ll cover these next week). As long as these nodes have available resources and are not bound by some conditions (e.g., taints and tolerations), pods may be scheduled to run on them. Just like in Docker, multiple pods can run on a single node.

Image credit: Kubernetes documentation

Even though pods can theoretically have unlimited number of containers, in practice, it’s most commonly used in the following ways:

  • One container per pod: most commonly, a pod is simply a wrapper around a container.
  • Container + “sidecar” per pod: some applications run with sidecar containers that provide helper functionality. Most commonly, these include log forwarding, networking proxy, or config management.
  • Tightly-coupled applications: tightly-coupled applications that need to share storage resources directly are sometimes deployed in a single pod.

There are also two special types of containers with intuitive names:

  • Init Containers: Init containers always run before the application containers are started. These are useful to run setup scripts (e.g., database migrations, config reload, etc).
  • Ephemeral Containers: Introduced in Kubernetes v1.25, ephemeral containers temporarily run inside existing pods for troubleshooting. This can be useful when exec-ing into the pod is not feasible (e.g., pod is crashing, container is running distroless images with no shell).

Pod Lifecycle

It’s important to note that like containers in Docker, pods are ephemeral by nature. When pods are created, they are given a unique ID and then scheduled to nodes. It then runs on that node until it stops due to job completion, error, or eviction. If the underlying node fails, the pod is not rescheduled, but deleted and a new pod with a new ID is scheduled.

Pods also follow simple, fairly self-explanatory phases:

  1. Pending: Pod is waiting to be scheduled or downloading artifacts needed to run (e.g., downloading the Docker image)
  2. Running: At least one of the containers in the pod is either running or restarting.
  3. Succeeded: All the containers in the pod exited in success. This is relevant for init containers or containers with defined end states such as cron jobs.
  4. Failed: At least one container has exited in failure.
  5. Unknown: Usually indicates that Kubernetes cannot communicate with the pod to determine the state

Kubernetes also exposes states of individual containers: Waiting, Running, and Terminated. Like Docker, each container can have a restartPolicy as well as probes to indicate pod health (similar to Docker healthcheck).

Pod Controllers

Aside from running ephemeral containers for debugging purposes, pods are almost never deployed directly. Instead, they are deployed and managed via controllers. Kubernetes borrows the concept of controllers from robotics where a controller regulates the state of a system. With respect to pods, controllers track the desired state that pods should be as defined by the specifications including replication, auto-scaling, scheduling preferences, and self-healing.

Most important types of controllers to know are:

For stateless applications, you will be dealing with Deployments. Deployments define the desired state for pods from the container image to the number of replicas. If you want to deploy a new version, deployment will create a new ReplicaSet and do a rolling deployment to the new version. This allows Kubernetes to rollback to a previous version if desired.

StatefulSets, as the name suggests, are for applications that need to preserve state. You’ll most likely encounter these if you are deploying databases within Kubernetes. StatefulSets are also useful if you need guaranteed ordering of pods or stable unique identifiers. You may run into these scenarios when you are dealing with consensus algorithms (e.g., blockchain).

Finally, DaemonSets are useful when you need to ensure that a pod runs on each node. These are most likely used by your Kubernetes admins to install log forwarders like fluentbit or some security plugin on every node.

Main Takeaways

Pods are fundamental to understanding how Kubernetes works. Thankfully, with our Docker knowledge, it’s easy to grasp how pods == one or more containers. The “Kubernetes” layer comes in at the controller level. Deployments, StatefulSets, and DaemonSets are how we define the orchestration details such as replication and self-healing properties to codify those behaviors.

Now that we understand the basic Kubernetes objects, next week, we’ll take a look at the Kubernetes architecture and some networking concepts that’s often misunderstood.

--

--

Yitaek Hwang
Yitaek Hwang

Written by Yitaek Hwang

Software Engineer at NYDIG writing about cloud, DevOps/SRE, and crypto topics: https://yitaekhwang.com

No responses yet