Pod Lifecycle Phases

What single field tells you where a Pod is in its life? The status.phase field moves through Pending while any container has yet to start, scheduling and image pulls included, Running once every container exists and one is running, and then Succeeded or Failed once they have all exited and none will be restarted. It is deliberately coarse, so a container crash-looping inside a Running Pod never changes it. Phase says where a Pod is, not whether it is healthy.

Play the animation 5 steps, animated, best on a wide screen

Pod Lifecycle Phases, Kubernetes diagram

Pod Lifecycle Phases, step by step

  1. The Pod is bound to a Node, so Kubelet picks it up, creates the sandbox and pulls the image, and the container sits in Waiting with reason ContainerCreating. The status.phase field stays Pending while any container is still waiting for its first start. The machine does not move at all on this step.

    Play from step 1
  2. Every container has been created and at least one is running, so status.phase takes its one healthy edge and moves from Pending to Running. A container crash-looping inside the Pod will not move the phase again, however long the loop lasts. A RestartAllContainers rule is the exception, it can send the Pod back to Pending. Running says where the Pod is in its life, not its health.

    Play from step 2
  3. The container exits with a non-zero code, Kubelet restarts it inside the same sandbox, and repeated fast failures push it into Waiting with reason CrashLoopBackOff while a backoff timer ticks. CrashLoopBackOff is a container-level waiting reason and never a phase of its own, so it is drawn inside Running. The machine has not moved and status.phase still reads Running.

    Play from step 3
  4. The backoff timer elapses, Kubelet starts the container again and this time it runs, so the container state returns to Running and restartCount records how many restarts it took. The status.phase field never left Running through the whole episode. A reader watching only the phase would have seen nothing happen at all.

    Play from step 4
  5. The container exits 0 and OnFailure does not restart a success, so every container is Terminated and status.phase becomes Succeeded. Under restartPolicy Never, with no container-level override, a non-zero exit is not restarted and the machine takes the edge to Failed. Both are terminal and absorbing, the Pod will not run again, and the fifth value Unknown was deprecated in 1.22.

    Play from step 5

Sources