Pods

Pods

The smallest schedulable unit. Not a container - an environment for one or more containers.

graph TB subgraph pod [Pod - one IP, one network namespace] C1[container: app] C2[container: sidecar] V[(shared volume)] C1 --- V C2 --- V end

Containers in a Pod share the IP, ports and volumes, always run on the same node, and talk over localhost.

Minimal manifest

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: web
spec:
  containers:
    - name: nginx
      image: nginx:1.27
      ports:
        - containerPort: 80
      resources:
        requests: { cpu: "50m", memory: "64Mi" }
        limits:   { cpu: "200m", memory: "128Mi" }

Requests drive scheduling, limits are enforced at runtime - details on Day 3.

Lifecycle

Phase / stateMeaning
Pendingnot scheduled yet, or waiting for image / volume
ContainerCreatingplaced on a node; kubelet pulls image, mounts volumes
Runningat least one container runs
Succeeded / Failedall containers ended (exit 0 / non-zero)
CrashLoopBackOffcontainer keeps dying; kubelet waits longer each time
ImagePullBackOffimage name, tag or registry access is wrong

restartPolicy: Always (default), OnFailure, Never.

Init containers and sidecars

spec:
  initContainers:
    - name: wait-for-db
      image: busybox:1.36
      command: ["sh", "-c", "until nc -z db 5432; do sleep 2; done"]

Init containers run to completion, in order, before the app containers start. An init container with restartPolicy: Always is a native sidecar: it starts first and keeps running next to the app.

Pods are cattle

Most of the Pod spec is immutable and a bare Pod is never rescheduled when its node dies. Use a controller (next chapter). Bare Pods are for debugging:

kubectl run tmp --image busybox:1.36 --restart=Never -it --rm -- sh

References