日常 K8s 运维中,很多朋友都会遇到一个高频痛点:执行kubectl delete删除 Pod、PV、PVC、Namespace 时,资源长期卡在Terminating 终止状态,怎么删都删不掉。
出现该问题大多是 finalizer 终结器锁定、节点离线、存储依赖未释放、优雅删除超时导致,常规删除命令完全失效。本文基于实战整理全套可直接复制的强制删除方案,快速清理卡死资源。
资源 Terminating 的核心原因
Kubernetes 默认采用优雅删除机制,删除资源时会预留宽限期,等待业务进程正常退出、关联资源释放、执行 finalizer 后置清理逻辑。
当节点失联、存储插件异常、控制器故障时,finalizer 无法正常执行完成,资源就会被永久锁定。普通删除命令无法绕过 K8s 原生保护机制,自然一直处于终止状态。
其中 Pod、PV/PVC 卡死相对简单,Namespace 命名空间卡死是最棘手、线上最常见的顽固问题。
常规资源强制删除
针对 Pod、持久卷 PV/PVC 这类常规资源,我们可以优先使用 kubectl 原生的强制参数,跳过优雅删除的等待过程。
强制删除 pod
nginx
# 推荐做法:先缩容,再扩容(StatefulSet 尤其推荐)
kubectl scale deployment/DEPLOY -n NS --replicas=0
kubectl scale deployment/DEPLOY -n NS --replicas=N
# 若确实要删单个 Pod
kubectl delete pod $podName -n $namespaces --force --grace-period=0
强制删除其他资源
apache
# pv
kubectl patch pv PV_NAME -p '{"metadata":{"finalizers":null}}' --type=merge
# pvc
kubectl patch pvc PVC_NAME -n NS -p '{"metadata":{"finalizers":null}}' --type=merge
# 其他crd
kubectl patch milvus -p '{"metadata":{"finalizers":null}}'
Namespace 顽固卡死
Namespace 有特殊的保护机制,不能直接通过 patch 清空 finalizer,必须通过 API 接口来完成收尾操作,标准的操作步骤如下:
1. 导出卡死的命名空间配置:
cs
kubectl get ns dead-ns -o json > ns.json
2. 编辑 json 文件中的 finalizers 字段,设置为空数组
json
"finalizers"
:
[]
3. 开启本地 kubectl 代理
nginx
kubectl proxy
4. 新开一个终端调用 Kubernetes API 完成 finalize 清理
bash
curl -k -H "Content-Type: application/json" -X PUT --data-binary @ns.json http://127.0.0.1:8001/api/v1/namespaces/$namespace/finalize
另外还有一种直接从 etcd 删除元数据的极端方案,这种方法风险很高,要谨慎使用,很容易造成集群元数据错乱、导致集群故障,不是紧急情况绝对不要尝试。
bash
# 找到 etcd 对应 key(不同版本 key 前缀不同,这里示意)
etcdctl get /registry/namespaces/NAMESPACE --prefix --keys-only
# 删除(极度危险:只应该在测试环境,或在厂商支持下进行)
etcdctl del /registry/namespaces/NAMESPACE
总结
强制删除属于生产环境中的应急运维手段,不是首选操作。日常工作中应该优先排查节点、存储和控制器异常,让资源能够正常释放。只有确认某个资源彻底没用了、无法正常下线时,才使用本文提到的方案来清理 Terminating 卡死资源,避免业务数据丢失和集群异常。欢迎关注我的小绿书《老卢聊运维》