Pods
Pods
The smallest schedulable unit. Not a container - an environment for one or more containers.
Containers in a Pod share the IP address, ports, IPC and volumes, and always run
on the same node. They talk over localhost. This is the --network container:
mode from Docker, made into a first-class object.
Minimal manifest
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
resources:
requests: { cpu: "50m", memory: "64Mi" }
limits: { cpu: "200m", memory: "128Mi" }
Requests decide where the Pod is scheduled - the scheduler subtracts them from the node’s allocatable capacity. Limits decide what happens under pressure: CPU over the limit is throttled, memory over the limit is an OOM kill. A Pod without requests is a scheduling gamble.
Lifecycle
Pending -> Running -> Succeeded / Failed, plus CrashLoopBackOff when a
container keeps dying. restartPolicy defaults to Always.
Pending means the scheduler has not placed it (no capacity, unbound PVC, a
taint). ContainerCreating means it is placed and the kubelet is working - image
pull, volume mount.
Init containers and sidecars
spec:
initContainers:
- name: wait-for-db
image: busybox
command: ["sh", "-c", "until nc -z db 5432; do sleep 2; done"]
Init containers run to completion, in order, before the app containers start. That is how you express “do not start until the database answers”.
In practice
You rarely create bare Pods. A bare Pod is never rescheduled when its node dies - use a Deployment. Bare Pods are for debugging and one-shot tasks.
kubectl run tmp --image busybox --restart=Never -it --rm -- sh