How it works
The explanation, with examples you can run.
One pod, three kinds of container
apiVersion: v1kind: Podmetadata: name: web labels: app: webspec: initContainers: - name: migrate # runs to completion before the app starts image: ghcr.io/acme/web:1.4.2 command: ["./migrate", "up"] - name: log-shipper # a native sidecar: an init container that keeps running image: fluent/fluent-bit:4.0 restartPolicy: Always volumeMounts: - { name: logs, mountPath: /var/log/app } containers: - name: app image: ghcr.io/acme/web:1.4.2 ports: - containerPort: 3000 volumeMounts: - { name: logs, mountPath: /var/log/app } volumes: - name: logs emptyDir: {}- Init containers run one after another, each to completion, before the app starts: migrations, waiting for a dependency, fetching config.
- Sidecars (an init container with
restartPolicy: Always) start in order with the init containers but keep running. They are ready before the app starts and are stopped after it, so a proxy or log shipper sees the app's last requests and log lines. This became stable in Kubernetes 1.33 (first available in 1.28). Before that, sidecars were ordinary containers with no ordering guarantees, which caused classic bugs such as Jobs that never finished because the proxy kept running. - App containers are the workload. The
emptyDirvolume is shared scratch space that lives as long as the pod.
Life of a pod
A pod is created, scheduled to a node once, runs, and ends. Its phase moves through Pending (not yet scheduled, or pulling images), Running, and Succeeded or Failed. Inside a running pod the kubelet restarts crashed containers according to restartPolicy (Always by default), with growing back-off delays, which shows up as CrashLoopBackOff.
What a pod never does is move. If its node dies, is drained or runs out of memory, the pod is gone. Its replacement is a new pod, with a new name and a new IP, created by whatever controller owns it. So:
- create pods through Deployments, StatefulSets, Jobs or DaemonSets, not by hand;
- never rely on a pod's IP or name staying the same; use a Service;
- keep state in volumes or external stores, not in the container filesystem.
Stopping a pod
Deleting a pod starts graceful termination: the pod is marked terminating, removed from Service endpoints, any preStop hook runs, and the kubelet asks the runtime to send each container SIGTERM. After terminationGracePeriodSeconds (30 by default), anything still running gets SIGKILL. This is the same PID 1 and signal handling as with docker stop, so the same rules apply: exec-form entrypoints, a SIGTERM handler, and shutdown work that finishes inside the grace period.
Check yourself
3 questions. Get them all right to finish this topic.
0 of 3 right so far. Get all three to finish this topic.