天天看点

Kubernetes 系列(十八)如何删除卡住的命名空间

作者:回首不堪的流年

大家看一下下图:

Kubernetes 系列(十八)如何删除卡住的命名空间

有两个命名空间处于 Terminating 状态,只要您愿意等待,这个讨厌的命名空间就一直在那里。是的,我尝试过等待

当然,我尝试了所有我知道的CLI技巧:

k delete ns cdi --force
warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.
namespace "cdi" force deleted           

再一次,并没有让它消失!

那么这些现象背后的原因是什么呢?为什么有时候命名空间会卡住?

Finalizers(终结器)

什么是 Finalizers?

Finalizers 是受命名空间控制的 keys,它告诉 Kubernetes 在”完全删除”被标记删除的资源之前等待,直到满足特定的条件。终结器提醒控制器清理被删除对象拥有的资源。

当你试图删除命名空间资源时,处理删除请求的API服务会注意到finalizers 中字段中的值,并做如下操作:

  • • 修改对象以添加一个 metadata.deletionTimestamp 字段,其中包含开始删除的时间。
  • • 阻止对象被删除直至 metadata.finalizers 字段为空
  • • 返回 202 状态码(HTTP “Accepted”)

我的下一个自然反应是通过手动将 finalizers 字段设置为空列表来修复问题:

kubectl patch ns/cdi -p '{"metadata":{"finalizers":[]}}' --type=merge
namespace/cdi patched           

Welp !这也无济于事。命名空间仍然停留在 terminating 状态。

Kubernetes 系列(十八)如何删除卡住的命名空间

然后我想到了我在 CKA 课程中学到的东西!我的意思是,我们都花了很多钱!应该有一个解决问题的方法? 想了想,通过创建一个本地代理服务器,可以直接与Kubernetes API服务器通信。

使用 finalize 端点服务

步骤非常简单,首先使用以下命令获取资源的JSON定义:

k get ns cdi -o json > cid.json           

打开JSON文件,从 finalizer 数组中删除kubernetes项,并保存文件。

Kubernetes 系列(十八)如何删除卡住的命名空间

现在,我们在机器和Kubernetes API服务器之间启动一个代理服务器或应用程序级网关。该代理将在http://127.0.0.1:8001 上提供服务

在新窗口中键入此命令:

k proxy
Starting to serve on 127.0.0.1:8001           

现在我们可以调用Kubernetes API : http://127.0.0.1:8001/api/v1/namespaces/{NAME_OF_STUCKED_NAMESPACE}/finalize 传入修改的 json文件,其中的 {NAME_OF_STUCKED_NAMESPACE} 变量替换为实际的命名空间:

curl -k -H "Content-Type: application/json" -X PUT --data-binary @cid.json http://127.0.0.1:8001/api/v1/namespaces/cdi/finalize


{
  "kind": "Namespace",
  "apiVersion": "v1",
  "metadata": {
    "name": "cdi",
    "uid": "6c957c91-1f1a-463f-99fe-04a121c48ec6",
    "resourceVersion": "37800934",
    "creationTimestamp": "2022-07-26T13:04:08Z",
    "deletionTimestamp": "2022-08-11T11:32:26Z",
    "labels": {
      "cdi.kubevirt.io": ""
    },
    "managedFields": [
      {
        "manager": "kubectl-create",
        "operation": "Update",
        "apiVersion": "v1",
        "time": "2022-07-26T13:04:08Z",
        "fieldsType": "FieldsV1",
        "fieldsV1": {"f:metadata":{"f:labels":{".":{},"f:cdi.kubevirt.io":{}}},"f:status":{"f:phase":{}}}
      },
      {
        "manager": "kube-controller-manager",
        "operation": "Update",
        "apiVersion": "v1",
        "time": "2022-08-11T11:32:32Z",
        "fieldsType": "FieldsV1",
        "fieldsV1": {"f:status":{"f:conditions":{".":{},"k:{\"type\":\"NamespaceContentRemaining\"}":{".":{},"f:lastTransitionTime":{},"f:message":{},"f:reason":{},"f:status":{},"f:type":{}},"k:{\"type\":\"NamespaceDeletionContentFailure\"}":{".":{},"f:lastTransitionTime":{},"f:message":{},"f:reason":{},"f:status":{},"f:type":{}},"k:{\"type\":\"NamespaceDeletionDiscoveryFailure\"}":{".":{},"f:lastTransitionTime":{},"f:message":{},"f:reason":{},"f:status":{},"f:type":{}},"k:{\"type\":\"NamespaceDeletionGroupVersionParsingFailure\"}":{".":{},"f:lastTransitionTime":{},"f:message":{},"f:reason":{},"f:status":{},"f:type":{}},"k:{\"type\":\"NamespaceFinalizersRemaining\"}":{".":{},"f:lastTransitionTime":{},"f:message":{},"f:reason":{},"f:status":{},"f:type":{}}}}}
      }
    ]
  },
  "spec": {


  },
  "status": {
    "phase": "Terminating",
    "conditions": [
      {
{
        "type": "NamespaceDeletionDiscoveryFailure",
        "status": "True",
        "lastTransitionTime": "2022-08-11T11:32:31Z",
        "reason": "DiscoveryFailed",
        "message": "Discovery failed for some groups, 2 failing: unable to retrieve the complete list of server APIs: subresources.kubevirt.io/v1: the server is currently unable to handle the request, subresources.kubevirt.io/v1alpha3: the server is currently unable to handle the request"
      },
      {
        "type": "NamespaceDeletionGroupVersionParsingFailure",
        "status": "False",
        "lastTransitionTime": "2022-08-11T11:32:32Z",
        "reason": "ParsedGroupVersions",
        "message": "All legacy kube types successfully parsed"
      },
      {
        "type": "NamespaceDeletionContentFailure",
        "status": "False",
        "lastTransitionTime": "2022-08-11T11:32:32Z",
        "reason": "ContentDeleted",
        "message": "All content successfully deleted, may be waiting on finalization"
      },
      {
        "type": "NamespaceContentRemaining",
        "status": "False",
        "lastTransitionTime": "2022-08-11T11:32:32Z",
        "reason": "ContentRemoved",
        "message": "All content successfully removed"
      },
      {
        "type": "NamespaceFinalizersRemaining",
        "status": "False",
        "lastTransitionTime": "2022-08-11T11:32:32Z",
        "reason": "ContentHasNoFinalizers",
        "message": "All content-preserving finalizers finished"
      }
    ]
  }
}           

然后,Boom !!! 命名空间消失了!

Kubernetes 系列(十八)如何删除卡住的命名空间

虽然花了些时间,但是我感觉是这样的:

Kubernetes 系列(十八)如何删除卡住的命名空间