一、通用排查思路:Terminating 的“内心独白”
当一个 Pod 卡在 `Terminating` 状态时,它其实在等待某些条件满足。常见的“拖延症”原因有:
-
节点异常:节点失联,kubelet 无法执行删除操作
-
容器无响应:容器内的进程不响应 `SIGTERM` 信号
-
Finalizers 卡住:资源上有 finalizers,且清理操作被阻塞
-
挂载点问题:NFS 等远程存储卸载失败
-
优雅退出时间过长:`terminationGracePeriodSeconds` 设置太长,或 `preStop` hook 卡住
二、实战案例一:Finalizers“阴魂不散”
2.1 故障现象
删除一个自定义资源(CRD)管理的 Pod 后,Pod 一直卡在 `Terminating` 状态,普通 `delete` 命令无效:
kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-pod-with-finalizer 1/1 Terminating 0 2d
kubectl delete pod myapp-pod-with-finalizer
pod "myapp-pod-with-finalizer" deleted
2.2 排查过程
Step 1:查看 Pod 详细信息
kubectl get pod myapp-pod-with-finalizer -o yaml
输出中发现关键字段:
metadata:
finalizers:
- kubernetes.io/pv-protection
- custom-finalizer/cleanup
问题定位:Pod 上存在 finalizers,且清理逻辑被卡住,导致 Kubernetes 认为资源还在使用中,无法完成删除。
Step 2:确认 finalizers 来源
通过 `describe` 查看事件,发现这个 Pod 挂载了 PVC,且有一个自定义控制器负责清理资源,但该控制器已不可用。
2.3 解决方案
方法一:直接移除 finalizers
kubectl patch pod myapp-pod-with-finalizer -p '{"metadata":{"finalizers":[]}}' --type=merge
方法二:若方法一无效,使用 JSON patch 格式
kubectl patch pod myapp-pod-with-finalizer --type=json -p '[{"op": "remove", "path": "/metadata/finalizers"}]'
结果验证
kubectl get pods | grep myapp-pod-with-finalizer
无输出,Pod 已删除
三、实战案例二:节点失联,Pod“无家可归”
3.1 故障现象
kubectl get nodes
NAME STATUS ROLES AGE VERSION
master-node Ready master 15d v1.22.2
worker-node1 NotReady
<none> 15d v1.22.2
kubectl get pods -o wide | grep worker-node1
app-pod-1 1/1 Terminating 0 3h 10.244.2.5 worker-node1
<none>
app-pod-2 1/1 Terminating 0 3h 10.244.2.6 worker-node1
<none>
3.2 排查过程
Step 1:确认节点状态
kubectl describe node worker-node1
Conditions:
Type Status LastHeartbeatTime
Ready Unknown ...
问题定位:节点失联超过 5 分钟,`kube-controller-manager` 尝试驱逐 Pod,将 Pod 标记为 `Terminating`。但由于 kubelet 无法执行实际的容器停止操作,Pod 卡在 `Terminating` 状态。
Step 2:检查节点上的 kubelet 日志(如果能登录节点)
由于节点失联,无法直接登录,只能从 master 端判断。
3.3 解决方案
Step 1:尝试修复节点
systemctl restart kubelet
Step 2:如果节点无法恢复,强制删除 Pod
kubectl delete pod app-pod-1 --grace-period=0 --force
kubectl delete pod app-pod-2 --grace-period=0 --force
Step 3:对于 StatefulSet 的 Pod 需谨慎
docker ps | grep <pod-name>
docker rm -f <container-id>
crictl pods | grep <pod-name>
crictl stopp <pod-id>
crictl rmp <pod-id>
结果验证
kubectl get pods | grep Terminating
无输出,所有 Terminating Pod 已清理
四、总结:Terminating 状态根因对照表
| 根本原因 | 典型特征 | 排查方向 | 解决方案 |
|---|---|---|---|
| Finalizers 阻塞 | metadata 中有 finalizers 字段 | `kubectl get pod -o yaml` 查看 finalizers | `kubectl patch` 移除 finalizers |
| 节点失联 | 节点状态 NotReady | 检查节点网络、kubelet 状态 | 修复节点或强制删除 Pod |
| 容器无响应 | 进程卡住,不响应 SIGTERM | 查看容器日志,检查进程状态 | 强制删除,或登录节点杀进程 |
| 存储卸载失败 | 挂载了 NFS/云盘 | `mount` 查看挂载点 | 手动卸载挂载点后强制删除 |
| preStop Hook 卡住 | 设置了 lifecycle preStop | 检查 preStop 脚本是否死循环 | 调整 preStop,或强制删除 |
五、最终总结
K8s 的 `Terminating` 状态其实并不可怕,它只是系统在等待某些条件满足。掌握了上面的方法,下次遇到“删不掉的 Pod”,你就能淡定解决:
-
查看 finalizers —— 可能只是需要你手动“松绑”
-
查看 节点状态 —— 可能是节点在“装死”
-
查看 存储挂载 —— 可能是盘片“粘住了”
(注:文档部分内容可能由 AI 生成)