Kubernetes Namespace 删除卡在 Terminating 状态的解决方案¶
问题概述¶
Kubernetes 删除 Namespace 时,如果一直卡在 Terminating 状态,通常是由于以下两个原因:
- Namespace 中还有未清理的资源
- 存在无法清理的 Finalizer(最常见原因)
根因分析¶
1. Rancher 管理的 Namespace Finalizer 问题¶
Rancher 管理的资源通常带有 Finalizer,例如:
controller.cattle.io/namespace-auth
controller.cattle.io/cleanup
当 Rancher 已经卸载或 controller 不存在时,这些 Finalizer 永远不会执行,导致 Namespace 一直卡在 Terminating 状态。
2. Admission Webhook 阻止修改¶
在尝试修改 Namespace 时,可能会遇到以下错误:
failed calling webhook "rancher.cattle.io.namespaces":
Post "https://rancher-webhook.cattle-system.svc:443/v1/webhook/validation/namespaces?timeout=10s":
service "rancher-webhook" not found
这表明 Rancher 的 webhook 配置仍然存在,但对应的服务已经不存在,导致任何 Namespace 修改操作都会失败。
诊断方法¶
检查 Namespace 的 Finalizer¶
kubectl get ns cattle-system -o json | jq '.spec.finalizers'
kubectl get ns cattle-fleet-system -o json | jq '.spec.finalizers'
kubectl get ns cattle-impersonation-system -o json | jq '.spec.finalizers'
如果输出包含类似内容:
[
"controller.cattle.io/cleanup"
]
则说明 Finalizer 是卡住的原因。
检查 Namespace 状态¶
kubectl describe ns cattle-system
查看状态信息,特别关注以下条件:
NamespaceDeletionDiscoveryFailureNamespaceDeletionGroupVersionParsingFailureNamespaceDeletionContentFailureNamespaceContentRemainingNamespaceFinalizersRemaining
检查 Rancher 相关的 Webhook¶
kubectl get validatingwebhookconfigurations | grep rancher
kubectl get mutatingwebhookconfigurations | grep rancher
检查 Namespace 内的残留资源¶
for r in $(kubectl api-resources --verbs=list --namespaced -o name); do
echo "--- $r ---"
kubectl get "$r" -n cattle-system 2>/dev/null
done
或者使用更简洁的脚本:
NS=cattle-system
echo "Checking resources inside namespace: $NS"
for r in $(kubectl api-resources --verbs=list --namespaced -o name); do
OUT=$(kubectl get "$r" -n "$NS" --ignore-not-found)
if [[ -n "$OUT" ]]; then
echo "---- $r ----"
echo "$OUT"
fi
done
解决方案¶
方案一:删除 Rancher Webhook 配置¶
首先删除所有 Rancher 相关的 webhook 配置:
kubectl delete validatingwebhookconfiguration rancher.cattle.io
kubectl delete validatingwebhookconfiguration rancher.cattle.io-namespaces
kubectl delete validatingwebhookconfiguration fleet.cattle.io
kubectl delete mutatingwebhookconfiguration rancher.cattle.io
kubectl delete mutatingwebhookconfiguration fleet.cattle.io
方案二:强制移除 Finalizer(推荐方式)¶
使用 /finalize API 跳过 Admission Webhook:
kubectl get ns cattle-system -o json | \
jq 'del(.spec.finalizers)' > /tmp/cattle-system.json
kubectl replace --raw "/api/v1/namespaces/cattle-system/finalize" -f /tmp/cattle-system.json
对其他命名空间执行相同操作:
kubectl get ns cattle-fleet-system -o json | jq 'del(.spec.finalizers)' > /tmp/cattle-fleet-system.json
kubectl replace --raw "/api/v1/namespaces/cattle-fleet-system/finalize" -f /tmp/cattle-fleet-system.json
kubectl get ns cattle-impersonation-system -o json | jq 'del(.spec.finalizers)' > /tmp/cattle-impersonation-system.json
kubectl replace --raw "/api/v1/namespaces/cattle-impersonation-system/finalize" -f /tmp/cattle-impersonation-system.json
方案三:手动编辑(如果没有 jq)¶
kubectl edit ns cattle-system
删除 spec.finalizers: 整段,例如:
spec:
finalizers:
- controller.cattle.io/namespace-auth
方案四:强制删除 Namespace¶
在删除 webhook 和 finalizer 后,可以使用以下命令强制删除:
kubectl delete ns cattle-system --force --grace-period=0
kubectl delete ns cattle-fleet-system --force --grace-period=0
kubectl delete ns cattle-impersonation-system --force --grace-period=0
完整解决流程¶
- 检查问题:确认是 Finalizer 还是 Webhook 导致的问题
- 删除 Webhook:移除所有 Rancher 相关的 webhook 配置
- 移除 Finalizer:使用
/finalizeAPI 强制删除 Finalizer - 验证删除:确认 Namespace 已成功删除
常见问题与解答¶
Q: 为什么 Namespace 一直处于 Terminating 状态?¶
A: 最常见的原因是 Rancher 的 Finalizer(如 controller.cattle.io/namespace-auth)卡住,因为 Rancher 已卸载,没有对应的 controller 来执行清理操作。
Q: 为什么不能直接编辑 Namespace?¶
A: 因为 Rancher 的 webhook 配置仍然存在,但对应的服务已经不存在,导致任何修改操作都会失败,并报错 "service not found"。
Q: 如何确认 Namespace 内是否还有资源?¶
A: 使用 kubectl api-resources 遍历所有资源类型,或使用提供的脚本进行检查。
Q: 删除 Finalizer 是否安全?¶
A: 在确认 Rancher 已卸载且不再需要的情况下,删除 Finalizer 是安全的。这只会跳过 Rancher 的清理逻辑,不会影响其他资源。
总结¶
Kubernetes Namespace 删除卡在 Terminating 状态,99% 的情况是由于:
- Rancher 被卸载或 controller 不存在
- Namespace 中有残留的 Finalizer
- K8s 无法执行 Finalizer,导致删除永远卡住
通过删除 Rancher 的 webhook 配置并手动移除 Finalizer,可以成功解决此问题。