The pod
Kubernetes does not schedule containers. It schedules pods.
A pod is a group of containers that share a network namespace, share IPC, and can share volumes. They are always placed on the same node, always started together, and always terminated together.
What sharing a network namespace means
Every container in a pod sees the same IP address and the same port space. They
reach each other over localhost, and they cannot both bind the same port.
apiVersion: v1
kind: Pod
metadata:
name: web
spec:
containers:
- name: app
image: myapp:1.4
ports:
- containerPort: 8080
- name: metrics-proxy
image: proxy:2.0
ports:
- containerPort: 9090
The proxy scrapes http://localhost:8080 — no service discovery, no DNS, no
network hop. This is the sidecar pattern, and the shared namespace is the whole
reason it works.
Init containers
Init containers run to completion, in order, before any app container starts. If one fails, the pod restarts according to its policy and the sequence begins again.
spec:
initContainers:
- name: wait-for-db
image: busybox:1.36
command: ['sh', '-c', 'until nc -z db 5432; do sleep 1; done']
They are the correct place for migrations, waiting on a dependency, or fetching configuration — anything that must be finished before the app process begins.
Restart policy is per pod, not per container
restartPolicy applies to the pod as a whole: Always, OnFailure or Never.
Deployments require Always. Jobs require one of the other two.
A crashing container is restarted in place by the kubelet, with exponential backoff
up to five minutes. That backoff is what CrashLoopBackOff means — the pod is not
broken beyond repair, the kubelet is simply waiting before its next attempt.