Zombie Pods in Kubernetes: What They Are and How to Kill Them (for Good)
- Apr 11
- 3 min read
Table of Contents:

Overview
Kubernetes promises a self-healing, automated container orchestration utopia. But sometimes… things go off the rails. You’ve deleted a pod, but it's still showing up in kubectl get pods. Maybe the pod's containers are long gone, but the metadata remains. Or worse—the pod looks alive but doesn’t respond.
Welcome to the eerie world of Zombie Pods—the Kubernetes equivalent of undead containers.
What is a Zombie Pod?
A zombie pod is a Kubernetes pod that appears to be alive or stuck in a terminated state—but in reality:
The containers are no longer running
The pod object still exists in the API
Kubernetes may still think it's managing it
Sometimes, kubelet has lost track of it completely
These pods are often the result of Kubernetes and node-level desynchronization—where the control plane and the kubelet (or container runtime) are no longer on the same page.
Symptoms of Zombie Pods
Here’s how you know you’re dealing with a zombie:
kubectl get pods shows a pod as Running or Terminating, but the app is unresponsive
kubectl describe pod shows the container as still active, but logs return errors or nothing
Pod deletion hangs indefinitely
No resource cleanup (e.g., volumes, IPs)
The container is gone from the node, but the pod metadata persists
Common Causes
Node Crashes or Network Partitions
If the node hosting a pod crash or becomes unreachable, Kubernetes may not update the pod status correctly. The pod lingers in Running or Terminating.
Container Runtime Issues
If the kubelet fails to kill a container or loses communication with Docker/CRI-O/containerd, it may not clean up the pod properly.
Pod Finalizers Hanging
Finalizers (e.g., kubernetes.io/pvc-protection) prevent deletion until cleanup completes. If the finalizer logic hangs or fails, the pod sticks around like a ghost.
Improper PreStop Hooks or Long Grace Periods
If your pod takes too long to exit and doesn't respond to SIGTERM/SIGKILL properly, termination may stall.
How to Identify a Zombie Pod?
Step 1: Check Pod Status
kubectl get pod my-pod -o wide
kubectl describe pod my-pod
Watch for:
Status stuck in Terminating
Events showing no recent activity
Container status out of sync with reality
Step 2: Check Node and Kubelet Health
kubectl get nodes
kubectl describe node <node-name>
Look for:
NotReady status
Kubelet errors in logs
Network partitioning
Step 3: SSH into the Node
ssh <node>
crictl ps -a | grep <pod>
If no containers are running for that pod, but the pod still exists in Kubernetes—it’s a zombie.

How to Kill a Zombie Pod
Delete the Pod with a Grace Period
Try the normal way first:
kubectl delete pod my-pod --grace-period=30
Still stuck?
Force Delete
kubectl delete pod my-pod --grace-period=0 --force
If that doesn’t work…
Remove Finalizers Manually
kubectl get pod my-pod -o json > pod.json
Edit pod.json and remove the finalizers section:
"finalizers": []
Then:
kubectl replace --raw "/api/v1/namespaces/default/pods/my-pod/finalize" -f pod.json
Restart the Kubelet (Last Resort)
Sometimes the kubelet needs a reset.
sudo systemctl restart kubelet
Then try the deletion again.
Best Practices to Avoid Zombie Pods
✅ Use proper liveness and readiness probes
✅ Keep preStop hooks short and reliable
✅ Monitor node health with probes and alerts
✅ Use proper logging and metrics for kubelet and container runtime
✅ Don’t abuse finalizers—keep them fast and idempotent
✅ Automate cleanup with tools like Kured or custom controllers
Conclusion
Zombie pods are rare, but when they show up, they can block deployments, exhaust resources, and frustrate operators. Recognizing the signs early and knowing how to surgically remove them ensures your cluster stays clean and healthy.
Comentários