跳转至

Kubernetes Namespace 删除卡在 Terminating 状态的解决方案

问题概述

Kubernetes 删除 Namespace 时,如果一直卡在 Terminating 状态,通常是由于以下两个原因:

  1. Namespace 中还有未清理的资源
  2. 存在无法清理的 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

查看状态信息,特别关注以下条件:

  • NamespaceDeletionDiscoveryFailure
  • NamespaceDeletionGroupVersionParsingFailure
  • NamespaceDeletionContentFailure
  • NamespaceContentRemaining
  • NamespaceFinalizersRemaining

检查 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

完整解决流程

  1. 检查问题:确认是 Finalizer 还是 Webhook 导致的问题
  2. 删除 Webhook:移除所有 Rancher 相关的 webhook 配置
  3. 移除 Finalizer:使用 /finalize API 强制删除 Finalizer
  4. 验证删除:确认 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% 的情况是由于:

  1. Rancher 被卸载或 controller 不存在
  2. Namespace 中有残留的 Finalizer
  3. K8s 无法执行 Finalizer,导致删除永远卡住

通过删除 Rancher 的 webhook 配置并手动移除 Finalizer,可以成功解决此问题。

回到页面顶部