Pods
Topic 05

Pods

WorkloadCore

A Pod is the smallest thing Kubernetes runs. It is one or more containers that are always scheduled together, share a network identity and storage, and live and die as a unit. Everything that runs on a cluster runs inside a Pod.

The surprising part for newcomers: you almost never create a Pod directly. You create a controller — a Deployment, a Job, a StatefulSet — and it creates Pods for you. Understanding the Pod is still essential, because it is the object every controller ultimately manages.

The Pod Model

Shared network
One IP for the Pod; containers reach each other on localhost.
Shared storage
Volumes can be mounted into several containers at once.
Co-scheduled
Always the same node; the containers start, live, and die together.

A Pod wraps containers in a shared context. Every container in a Pod shares the same network namespace — the same IP address and port space, so they reach each other on localhost — and can share storage volumes. They are always placed on the same node and started and stopped together. The Pod is the unit of scheduling, of networking, and of co-location.

Each Pod gets its own cluster-internal IP address. Containers in different Pods talk over the network; containers in the same Pod talk over localhost. This is why a Pod, not a container, is the atom of Kubernetes: some things genuinely belong together, and the Pod is how you say so.

A minimal Pod
apiVersion: v1
kind: Pod
metadata:
  name: web
  labels:
    app: web
spec:
  containers:
    - name: web
      image: nginx:1.27
      ports:
        - containerPort: 80

Single vs Multi-Container Pods

Most Pods hold a single container. A multi-container Pod is for containers that are genuinely coupled — a main application plus a helper that supports it on the same host, sharing its network and disk. The classic shapes are the sidecar (a proxy or log shipper), the adapter (reshaping output), and the ambassador (proxying outbound connections).

The test is co-location: do these containers have to run on the same node, share an IP, or share a volume? If yes, one Pod. If they merely talk to each other over the network, they are separate Pods connected by a Service. Cramming unrelated containers into one Pod couples their lifecycles for no reason.

Lifecycle and Phases

A Pod moves through phases: Pending while it is scheduled and images pull, Running once containers start, and a terminal Succeeded or Failed for run-to-completion work. The phase is a coarse summary; the detail lives in each container's state (waiting, running, terminated) and the Pod's conditions.

Inside a running Pod, the restartPolicy governs individual containers. Always (the default, used by long-running services) restarts a container whenever it exits. OnFailure and Never suit Jobs. Note that restartPolicy restarts containers in place; it does not reschedule the Pod to another node — that is a controller's job.

PhaseMeaning
PendingAccepted but not yet running — scheduling or image pull in progress
RunningBound to a node, at least one container started
SucceededAll containers exited 0 and will not restart
FailedAll containers terminated, at least one in failure

Why You Don't Create Pods Directly

A bare Pod has no self-healing. If its node dies, the Pod is gone — nothing recreates it. Controllers exist precisely to add that missing reconcile loop: a Deployment keeps N Pods running and replaces any that vanish, a Job runs a Pod to completion and retries on failure, a DaemonSet keeps one per node. You declare the controller; it owns the Pods.

So the practical rule is that bare Pods are for debugging and one-off experiments. Anything that should survive a node failure belongs to a controller. The rest of this chapter is, in large part, the catalog of those controllers.

Pod vs container vs node

Container — a single isolated process from one image. The unit of packaging.

Pod — one or more containers sharing network and storage, scheduled together. The unit Kubernetes runs and schedules.

Node — a machine that runs many Pods. The unit of capacity.

Common Mistakes
  • Creating bare Pods in production — when the node fails, nothing brings them back; use a controller.
  • Packing unrelated containers into one Pod, coupling their scaling and lifecycle for no reason.
  • Assuming a Pod's IP is stable — Pods are recreated with new IPs, which is why Services exist.
  • Putting two services that merely talk over the network in one Pod instead of two Pods plus a Service.
  • Setting restartPolicy: Always on a Pod meant to run to completion, so it never reaches Succeeded.
Best Practices
  • Run Pods through controllers (Deployment, Job, StatefulSet, DaemonSet), never bare, outside of debugging.
  • Keep Pods single-container unless containers genuinely must share a node, IP, or volume.
  • Treat Pods as disposable and replaceable — design apps to start fast and tolerate being killed.
  • Set resource requests and limits on every container so scheduling and eviction behave (Topic 25).
  • Reach for a Service or DNS name, never a Pod IP, when one workload needs to address another.
RelatedDeployment / Job / DaemonSet — the controllers that actually create PodsService — the stable address in front of a changing set of Podsdocker run — the rough single-host analog of one container

Knowledge Check

What do containers in the same Pod share?

  • A network namespace (one IP, reachable over localhost) and optionally storage volumes
  • Nothing — they are fully isolated, each with its own IP and namespace, just like separate Pods
  • Only a single pooled CPU and memory limit split across them all
  • The same container image, pulled once and run as identical replicas

Why is creating a bare Pod (no controller) discouraged in production?

  • A bare Pod has no reconcile loop — if its node dies, nothing recreates it
  • Bare Pods cannot mount PersistentVolumes or any other storage
  • Bare Pods are always scheduled onto the tainted control-plane nodes
  • The API server outright rejects any bare Pod that lacks a controller owner reference

When should two containers share a single Pod rather than run as two Pods?

  • When they must be co-located — share a node, IP, or volume — like an app and its sidecar
  • Whenever they belong to the same application and simply talk to each other over the network
  • When each one needs to scale to a different replica count independently
  • When they are written in the same programming language and runtime

You got correct