尝试删除 Kubernetes 命名空间后,长时间停留在终止状态。 本文介绍如何解决命名空间处于终止状态的问题。

问题现象

尝试删除 Kubernetes 命名空间后,长时间停留在终止状态。
$ kubectl delete ns <namespacename>
Error from server (Conflict): Operation cannot be fulfilled on namespaces "<namespacename>": The system is ensuring all content is removed from this namespace. Upon completion, this namespace will automatically be purged by the system. 

$ kubectl describe ns <namespacename>
Name: <namespacename> 
Labels: <none> 
Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"<namespacename>","namespace":""}} 

Status: Terminating 

可能原因

通常是因为从集群中删除的这些命名空间下存在资源。

解决方案

删除命名空间的 finalizers。

该选项将会快速清除处于终止状态的命名空间,但可能会导致属于该命名空间的资源留在集群中,因为无法自动删除它们。在 finalizers 数组为空并且状态为终止之后,Kubernetes 将删除命名空间。

  1. 打开 shell 终端,为您的 Kubernetes 集群创建一个反向代理。
    kubectl proxy
    输出示例如下:
    Starting to serve on 127.0.0.1:8001
  2. 打开一个新的 shell 终端,通过定义环境变量来连接到 Kubernetes 集群,使用 cURL 测试连接性和授权。
    export TOKEN=$(kubectl describe secret $(kubectl get secrets | grep default | cut -f1 -d ' ') | grep -E '^token' | cut -f2 -d':' | tr -d '\t')
    curl http://localhost:8001/api/v1/namespaces --header "Authorization: Bearer $TOKEN" --insecure
  3. 获取命名空间定义的内容,以命令空间istio-system为例。
    kubectl get namespace istio-system -o json > istio-system.json
  4. 将 finalizers 数组置为空,并重新保存文件。
        "spec": {
            "finalizers": [
            ]
        },
  5. 执行以下命令去除 finalizers,以命令空间istio-system为例。
    curl -X PUT --data-binary @istio-system.json http://localhost:8001/api/v1/namespaces/istio-system/finalize -H "Content-Type: application/json" --header "Authorization: Bearer $TOKEN" --insecure