Pod Anatomy
Containers grouped — sidecars, init containers, lifecycle.
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:8080is 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
emptyDirand 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- clikubectlfree tier
The Kubernetes CLI — `describe pod`, `logs -c`, `exec -it` are your debugging staples.
- clik9sfree tier
Terminal UI over kubectl with live tail, port-forward, and YAML editing built in.
- clisternfree 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.
- clikubectx / kubensfree tier
Switch contexts and namespaces in one keystroke; pairs with fzf for fuzzy selection.
- cliHelmfree tier
Package manager for Kubernetes — templated YAML rendered into pods + sidecars.