postStart and preStop Hooks

Where do postStart and preStop actually sit in a container life, and why do they behave so differently? Drawn on one timeline, postStart opens on the same tick as the ENTRYPOINT with no ordering guarantee between them, while preStop holds back any signal until it returns or the grace window ends, and the SIGTERM drain gets what is left of that window. Kubelet owns both slots, and it is the runtime that runs an exec handler inside the container.

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

postStart and preStop Hooks diagram: Container lifecycle hooks on one container timeline

postStart and preStop Hooks, step by step

  1. A container may declare two lifecycle handlers of its own. The lifecycle.postStart field is bound to the moment the container is created, and lifecycle.preStop to the moment it is asked to stop. Each handler is one of exec, a command run inside the container, httpGet, a request Kubelet issues against the Pod IP by default, or sleep, a fixed pause. Neither slot has run yet.

    Play from step 1
  2. The runtime creates the container and starts the ENTRYPOINT as PID 1. Kubelet fires postStart on that same moment, so the handler and the entrypoint run at once with no guarantee about which of them starts or finishes first. A handler that assumes the entrypoint is already listening is a race you wrote yourself.

    Play from step 2
  3. The handler returns and Kubelet reads the exit code. Only now does the container report Running, because a postStart that hangs holds it out of that state. A non-zero exit makes Kubelet kill the container, and the Pod restartPolicy decides what happens next.

    Play from step 3
  4. A delete opens the termination grace window. Kubelet runs preStop and waits until it returns or the window runs out: the signal comes after this handler, where the ENTRYPOINT never waited for postStart. PID 1 is still running and has had nothing delivered to it. Whatever preStop spends comes out of the same window the stop itself has to finish in.

    Play from step 4
  5. The handler returns, and only then does Kubelet ask the runtime for StopContainer, which delivers SIGTERM to PID 1, unless the image defines a different STOPSIGNAL. The signal lands where the hook left off, so a slow handler leaves the app less of the window to drain in. Graceful Pod Shutdown owns the rest of that window and the SIGKILL if anything is still alive at zero.

    Play from step 5

Sources