containers · level 3

Pod Anatomy

Containers grouped — sidecars, init containers, lifecycle.

150 XP

Pod Anatomy

Kubernetes does not schedule containers. It schedules pods. A pod is one or more containers that share a network and IPC namespace, get scheduled together, and live and die as a unit. In 90% of deployments a pod contains exactly one app container — but the primitive is a group, not a single.

Analogy

Think of a pod as a hotel room that a group of travellers books together. They share the same door number, the same Wi-Fi, the same mini-bar, and one of them usually has the key; if housekeeping evicts the room, everyone leaves at once. Most rooms hold a single traveller, but you can put a parent and a toddler in together when they genuinely need to share a bathroom (a sidecar). You never assign people to individual beds across the whole hotel — you book rooms.

What "shared" really means

Containers inside the same pod share:

  • Network namespace — same interfaces, same loopback, same set of listening ports. localhost:8080 is the same thing for every container in the pod.
  • IPC namespace — System V IPC and POSIX message queues work between them.
  • Optional volumes — any volume you declare on the pod can be mounted into multiple containers.

Containers in the same pod do not share:

  • Filesystem — each has its own root image and writable layer.
  • PID namespace by default (you can opt in with shareProcessNamespace: true).
  • Lifecycle beyond "same node" — they start in a defined order but each container has its own process and own liveness probes.

Init containers

Init containers run before any sidecar or main container. They must each succeed; if one fails, Kubernetes restarts the pod according to the pod's restartPolicy. Init containers are how you do:

  • Database schema migrations
  • Downloading bootstrap config from a private source
  • Waiting for a dependency (until dig backend; do sleep 1; done)
  • Setting filesystem permissions for mounted volumes
initContainers:
  - name: wait-for-db
    image: busybox
    command: ["sh", "-c", "until nc -z db 5432; do sleep 1; done"]

They run sequentially. Container 2 waits for container 1 to exit 0.

Sidecars

A sidecar is a helper container that runs alongside the main app for the pod's lifetime. It uses the shared network namespace to observe, transform, or augment the main container without modifying it.

Common sidecars:

  • Log shipper (Fluent Bit, Vector) — tails app logs from a shared emptyDir and forwards them.
  • Service mesh proxy (Envoy, linkerd-proxy) — all app traffic flows through this container, which handles mTLS, retries, and metrics.
  • Config reloader — watches a ConfigMap and signals the app when it changes.

Because they share localhost, the main container can call http://localhost:9901/metrics and hit the proxy's admin API without any service discovery.

Pod lifecycle

A pod moves through a small set of phases:

Phase Meaning
Pending Accepted by the API server, waiting for scheduling or image pull.
Running At least one container is still running.
Succeeded All containers exited 0 and will not restart.
Failed All containers terminated, at least one with non-zero exit.
Unknown Kubelet hasn't reported recently. Usually a node problem.

Alongside phase there are conditions (Initialized, Ready, ContainersReady, PodScheduled) and per-container states (Waiting, Running, Terminated). kubectl describe pod walks all of those top-down.

kubectl get pod web -o wide
kubectl describe pod web
kubectl logs web -c app        # main container
kubectl logs web -c sidecar    # helper container
kubectl exec -it web -c app -- sh

Probes

A pod declares three optional probes per container:

  • startupProbe — runs first, disables the others until success. For slow-starting apps.
  • livenessProbe — if it fails, kubelet restarts the container.
  • readinessProbe — if it fails, the pod is removed from Service endpoints until it recovers. The pod keeps running; it just stops receiving traffic.

Confusing liveness and readiness is one of the most common Kubernetes bugs. Liveness means "is this still alive?" — if not, restart. Readiness means "can this take traffic right now?" — if not, drain but don't kill.

When to put two containers in one pod

Ask: do these two containers need to live, die, and be scheduled together? If yes, one pod. Classic yeses: app + sidecar-proxy, app + log-shipper, DB + local-cache-of-DB.

Classic nos: two separate services, a web app and its database, a producer and a consumer on a queue. Those are separate pods talking over the network.

Tools in the wild

6 tools
  • kubectlfree tier

    The Kubernetes CLI — `describe pod`, `logs -c`, `exec -it` are your debugging staples.

    cli
  • k9sfree tier

    Terminal UI over kubectl with live tail, port-forward, and YAML editing built in.

    cli
  • sternfree tier

    Multi-pod log tail with regex filtering — much friendlier than `kubectl logs`.

    cli
  • Desktop IDE for Kubernetes; pod views, metrics, exec terminals — kid-glove for new operators.

    cli
  • Switch contexts and namespaces in one keystroke; pairs with fzf for fuzzy selection.

    cli
  • Helmfree tier

    Package manager for Kubernetes — templated YAML rendered into pods + sidecars.

    cli