Why Does a Kubernetes Pod Stay in Terminating State for 30 Seconds?
This article explains why a Kubernetes pod may remain in the Terminating state for up to 30 seconds, detailing the graceful shutdown process, the role of terminationGracePeriodSeconds and preStop hooks, and how to modify startup scripts to ensure prompt pod deletion.
Normally, after running kubectl delete pod, a pod is removed immediately, but sometimes it stays in the Terminating state for a while before disappearing.
Understanding What Happens When a Pod Is Deleted
During graceful termination, the kubelet sends a SIGTERM (TERM) signal to the main process of each container, waits for the configured grace period, and then sends SIGKILL if the process is still running. The container runtime processes these signals asynchronously, and many runtimes respect the STOPSIGNAL defined in the image.
The process can be summarized in two steps:
kubelet sends kill 1 to the pod.
After terminationGracePeriodSeconds (default 30 s), if the pod is still alive, kubelet sends kill -9 1 to force termination.
The 30‑second wait exists because Kubernetes may need to run commands defined in a preStop hook before the pod is fully terminated. Kubernetes does not wait for the preStop hook to finish, so the grace period ensures the hook has time to complete.
Why a Pod Without a preStop Hook Still Waits 30 s
In many cases the issue is that the initial kill 1 does not terminate the actual business process because the signal is not propagated to child processes.
NAME READY STATUS RESTARTS AGE
nginx 1/1 Terminating 0 4m34sInspecting the container shows two processes:
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 08:58 ? 00:00:00 bash /start.sh
root 7 1 94 08:58 ? 00:00:13 python3 /server.pyThe start.sh script launches the real business process in a blocking way:
#!/usr/bin/env bash
python3 /server.pyBecause the script does not forward the SIGTERM to the child python3 process, the signal never reaches it, the child keeps running, and the pod cannot finish termination.
Some users start the business process via a script to perform initialization steps that cannot be done with an init‑container.
How to Avoid This Problem
Start the business process directly whenever possible, using init‑containers for initialization.
In the startup script, trap SIGTERM and forward it to the child process.
#!/usr/bin/env bash
exit_func() {
pkill python3
exit
}
trap 'exit_func' SIGTERM
python3 /server.py &
while true; do
sleep 1
doneWith this adjusted script, the SIGTERM is propagated to the child process, allowing the pod to terminate quickly.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
MaGe Linux Operations
Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
