Full lesson
Explore the full explanation, examples, and visuals at your own pace.
Part 1
Deleting web-7f9c doesn't kill it. It starts a countdown. The Pod is marked Terminating, the kubelet sends SIGTERM, and the app gets thirty seconds to drain. Only if it's still running after that does Kubernetes send SIGKILL.
Step 1: deletion is just a status change
When kubectl sends the delete, the API Server doesn't stop anything. It just sets a deletionTimestamp with a thirty second grace period, and the Pod shows as Terminating. Then it publishes watch events, and the Kubelet and the endpoint controller each react on their own.
Step 2: two paths run at once
Once the Pod is marked Terminating, two things start at the same time. The kubelet runs the preStop hook, then sends SIGTERM to web-7f9c. Meanwhile, the endpoint controller removes the Pod from the Service, and kube-proxy updates its rules. Neither path waits for the other.
The race: traffic can arrive after SIGTERM
Endpoint removal can lag behind SIGTERM. If web-7f9c exits the instant the signal arrives, kube-proxy may still hold a stale route. A client's GET to orders lands on a dead Pod and gets connection refused.
That gap is exactly why the grace period exists.
Your app exits the instant it gets SIGTERM, with no preStop hook. What might clients briefly see during deletion?
Your app exits the instant it gets SIGTERM, with no preStop hook. What might clients briefly see during deletion?
- Some requests fail with connection errors
- Nothing, because traffic always stops first
- The Pod restarts and serves again
Your app exits the instant it gets SIGTERM, with no preStop hook. What might clients briefly see during deletion?
Some requests fail with connection errors. Endpoint removal runs in parallel with SIGTERM, not before it. For a short window, kube-proxy may still route requests to the Pod after the process has already exited. Those requests fail until the routing rules catch up.
- Some requests fail with connection errors
- Nothing, because traffic always stops first
- The Pod restarts and serves again
On SIGTERM, a clean app should
First, keep serving briefly, or sleep in preStop, so endpoint updates catch up. Then stop accepting new connections and finish in-flight requests. Finally, close your resources and exit with code zero before the thirty seconds run out.
- Keep serving briefly or use preStop sleep
- Stop accepting new connections, finish in-flight
- Close resources and exit before 30s
preStop time counts against the grace period
The thirty second clock starts at deletion, and preStop runs inside it. Here, five seconds of sleep plus twelve seconds of draining leaves thirteen seconds unused. If your shutdown takes longer, raise terminationGracePeriodSeconds, because SIGKILL won't wait.
Chart values
| Phase | Seconds |
|---|---|
| preStop sleep | 5 |
| Draining | 12 |
| Unused buffer | 13 |
When the app ignores SIGTERM
Now the failure path. The kubelet sends SIGTERM, but web-7f9c keeps running, maybe because a shell PID 1 never forwarded the signal. When the grace period expires, the kubelet sends SIGKILL. The container exits with code 137, and any in-flight work may be dropped.
Signal, wait, then force
Signal, wait, then force. That's how Kubernetes deletes a Pod. So handle SIGTERM in your app, add a short preStop delay for endpoint removal to catch up, and size the grace period to your real shutdown time.




