记录一下那天晚上的排查过程。K8s 1.25 集群滚动更新时,一个 Java Pod 状态一直是 Terminating,kubectl describe 里只有一行 Failed to kill pod sandbox,节点上 docker ps 还能看到容器在运行。
刚开始盯着「Pod 挂了 finalizer,控制器没清掉就永远删不掉」,折腾了半个多小时,排掉了。
原因不止一个,得分开看。容器里的主进程是 PID 1 却不处理 SIGTERM,宽限期到了才被强杀,中间一直挂着。少数情况下是节点上的 kubelet 与容器运行时通信超时,sandbox 删除请求没有完成。
还有一种情况,挂载的 PVC 卸载卡住,kubelet 在等卷解绑才继续。
上来先看卡在哪个阶段和有没有 finalizer
kubectl get pod web-0 -o jsonpath='{.metadata.deletionTimestamp}{.metadata.finalizers}'
从事件里找具体失败动作
kubectl describe pod web-0 | sed -n '/Events/,$p'
进容器确认主进程有没有接 SIGTERM
kubectl exec web-0 -- ps -o pid,comm,args -p 1
剩下的就是清掉 finalizer 让删除流程继续
kubectl patch pod web-0 -p '{"metadata":{"finalizers":null}}' --type=merge
改完先别撤,确认这几项。Pod 从列表里消失,节点上 docker ps 看不到对应容器,同一批新 Pod 全部 Running 且就绪探针通过。
这里还有个坑。强删 finalizer 只是让 API 层放过,卷和网络可能还挂着;根治要让应用处理 SIGTERM 并配好 preStop 与 terminationGracePeriodSeconds。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。
