删除K8s中卡在Terminating状态的命名空间

删除Kubernetes中卡在Terminating状态的命名空间

一、问题背景

在Kubernetes集群中,命名空间(Namespace)长时间处于 Terminating 状态且无法删除,是一个经典的“删库跑路”式难题。即使使用 --grace-period=0 --force 强制删除,依然可能会卡住。这种现象通常由以下原因导致:

  1. 残留资源:命名空间内存在未被清理的Kubernetes资源(如自定义资源CRD、Finalizers锁)。
  2. API资源不可用:依赖的APIService(如metrics-server)异常导致资源发现失败。
  3. Finalizers死锁:控制器未正确清理Finalizers,导致删除流程无法完成。

二、常规删除操作(失败场景复现)

1. 普通删除命令
kubectl delete ns rook-ceph

现象:命令长时间挂起,最终只能 Ctrl+C 强制退出。

2. 强制删除命令
kubectl delete ns rook-ceph --grace-period=0 --force

现象:依然无法删除,并提示 Some content in the namespace has finalizers remaining


三、根本原因分析

通过 kubectl get ns rook-ceph -o json 查看命名空间详情,关键问题在于:

  • Finalizers未释放spec.finalizers 包含锁机制(如默认的 kubernetes),需手动解除。
  • 残留资源未清理:存在未删除的CRD资源(如Ceph相关资源)或孤儿对象。

四、终极解决方案:绕过Finalizers强制删除

1. 导出命名空间配置
kubectl get ns rook-ceph -o json > rook-ceph.json
2. 编辑JSON文件,清空Finalizers
{
  "spec": {
    "finalizers": []  // 删除原有finalizers内容,改为空数组
  }
}
3. 启动本地API代理
kubectl proxy --port=8001
4. 调用K8S API强制删除
curl -X PUT \
  -H "Content-Type: application/json" \
  --data-binary @rook-ceph.json \
  http://localhost:8001/api/v1/namespaces/rook-ceph/finalize
5. 验证结果
kubectl get ns  # 观察命名空间已消失

五、生产环境注意事项

  1. 风险预警
    强制删除是最后手段! 直接移除Finalizers可能导致:

    • 残留资源(如PV、CRD)未被清理,引发后续部署冲突。
    • 依赖Finalizers的控制器(如Operator)出现异常。
  2. 前置检查清单

    • 确认命名空间内所有资源已删除:
      kubectl api-resources --verbs=list --namespaced -o name | xargs -n1 kubectl get -n rook-ceph
      
    • 检查APIService是否正常(如metrics.k8s.io):
      kubectl get apiservice | grep "False"
      
  3. 备选方案

    • 手动清理残留资源
      若命名空间内存在未删除的CRD,需先手动清理:
      kubectl -n rook-ceph delete <resource-type> <resource-name> --force --grace-period=0
      
    • 修复APIService
      若因metrics-server异常导致删除失败,重新部署metrics-server:
      kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
      

六、总结

通过API强制删除是解决Terminating命名空间的终极方案,但务必谨慎使用。生产环境中,建议优先排查残留资源、修复APIService,并确保所有控制器已正确释放资源。若仍无法解决,再使用本文方案“破釜沉舟”。

技术冷知识
Finalizers是Kubernetes的“安全锁”机制,确保资源在依赖项清理完成后才被删除。常见的Finalizers包括kubernetes(默认命名空间锁)和CRD控制器自定义锁(如ceph.rook.io/disaster-protection)。

posted on 2025-03-23 09:10  Leo-Yide  阅读(277)  评论(0)    收藏  举报