如何强制删除 Kubernetes 命名空间?

问题描述 投票:0回答:7

如何强制删除卡在 Terminating 中的命名空间?

重建步骤:

  1. 应用这个 YAML
apiVersion: v1
kind: Namespace
metadata:
  name: delete-me
spec:
  finalizers:
    - foregroundDeletion
  1. kubectl delete ns delete-me

  2. 无法删除

    delete-me
    .

我发现的唯一解决方法是销毁并重新创建整个集群。

我尝试过的事情:

这些都不起作用或修改命名空间。在任何这些之后,有问题的终结器仍然存在。

编辑 YAML 和
kubectl apply

申请:

apiVersion: v1
kind: Namespace
metadata:
  name: delete-me
spec:
  finalizers:
$ kubectl apply -f tmp.yaml 

namespace/delete-me configured

命令完成且没有错误,但命名空间未更新。

下面的 YAML 有相同的结果:

apiVersion: v1
kind: Namespace
metadata:
  name: delete-me
spec:

kubectl edit

kubectl edit ns delete-me
,取下终结器。同上完全删除列表。同上删除
spec
。同上用空列表替换
finalizers

$ kubectl edit ns delete-me 

namespace/delete-me edited

这不会显示错误消息,但不会更新命名空间。

kubectl edit
再次访问对象显示终结器仍然存在。

kubectl proxy &

  • kubectl proxy &
  • curl -k -H "Content-Type: application/yaml" -X PUT --data-binary @tmp.yaml http://127.0.0.1:8001/api/v1/namespaces/delete-me/finalize

如上,成功退出但什么都不做。

强制删除

kubectl delete ns delete-me --force --grace-period=0

这实际上会导致错误:

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.
Error from server (Conflict): Operation cannot be fulfilled on namespaces "delete-me": The system is ensuring all content is removed from this namespace.  Upon completion, this namespace will automatically be purged by the system.

然而,它实际上并没有做任何事情。

久等了

在我为了调试这个问题而设置的测试集群中,我已经等了一个多星期了。即使命名空间最终可能决定删除,我也需要它在一周内被删除。

确保命名空间为空

命名空间是空的。

$ kubectl get -n delete-me all

No resources found.

etcdctl

$ etcdctl --endpoint=http://127.0.0.1:8001 rm /namespaces/delete-me

Error:  0:  () [0]

我很确定这是一个错误,但我不知道如何解释它。它也不起作用。也尝试过

--dir
-r
.

ctron/kill-kube-ns

有一个强制删除命名空间的脚本。这也行不通。

$ ./kill-kube-ns delete-me

Killed namespace: delete-me

$ kubectl get ns delete-me 

NAME        STATUS        AGE
delete-me   Terminating   1h

POST
编辑资源到/finalize

返回 405。我不确定这是否是 POST 到 /finalize 的规范方式。

友情链接

这个 出现 be a 经常性 问题 这些 资源 帮助.

Kubernetes 错误

kubernetes kubernetes-namespace
7个回答
35
投票

kubectl proxy
尝试几乎正确,但不完全正确。可以使用 JSON 而不是 YAML 来解决问题,但我不确定。

终结器列表为空的 JSON:

~$ cat ns.json

{
  "kind": "Namespace",
  "apiVersion": "v1",
  "metadata": {
    "name": "delete-me"
  },
  "spec": {
    "finalizers": []
  }
}

使用

curl
PUT
没有问题终结器的对象。

~$ curl -k -H "Content-Type: application/json" -X PUT --data-binary @ns.json http://127.0.0.1:8007/api/v1/namespaces/delete-me/finalize

{
  "kind": "Namespace",
  "apiVersion": "v1",
  "metadata": {
    "name": "delete-me",
    "selfLink": "/api/v1/namespaces/delete-me/finalize",
    "uid": "0df02f91-6782-11e9-8beb-42010a800137",
    "resourceVersion": "39047",
    "creationTimestamp": "2019-04-25T17:46:28Z",
    "deletionTimestamp": "2019-04-25T17:46:31Z",
    "annotations": {
      "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Namespace\",\"metadata\":{\"annotations\":{},\"name\":\"delete-me\"},\"spec\":{\"finalizers\":[\"foregroundDeletion\"]}}\n"
    }
  },
  "spec": {

  },
  "status": {
    "phase": "Terminating"
  }
}

命名空间被删除!

~$ kubectl get ns delete-me

Error from server (NotFound): namespaces "delete-me" not found

34
投票

我喜欢从这里提取的这个答案

在一个终端中:

kubectl proxy

在另一个终端:

kubectl get ns delete-me -o json | \
  jq '.spec.finalizers=[]' | \
  curl -X PUT http://localhost:8001/api/v1/namespaces/delete-me/finalize -H "Content-Type: application/json" --data @-

16
投票

在 Termination 中将两次出现的

<NAME_OF_NAMESPACE>
替换为命名空间的实际名称后应用此命令可以解决问题:

kubectl get ns <NAME_OF_NAMESPACE> -o json | jq '.spec.finalizers = []' | kubectl replace --raw "/api/v1/namespaces/<NAME_OF_NAMESPACE>/finalize" -f -

说明:

大多数回复似乎在这里做同样的事情;从命名空间中删除终结器。在这种情况下,这是分三步完成的:

  1. kubectl get ns <NAME_OF_NAMESPACE> -o json
    返回 json 格式的命名空间配置。这是管道到下一个命令:
  2. jq '.spec.finalizers = []'
    从 json 配置中删除所有终结器。然后将生成的 json(没有终结器)通过管道传输到下一个命令:
  3. kubectl replace --raw "/api/v1/namespaces/<NAME_OF_NAMESPACE>/finalize" -f -
    ,将更新的 json 命名空间配置(没有终结器)注入 k8s。

11
投票

这里是对用户 Ushakov Roman 提供的命令的修改(详细说明见那里)。与 Ushakov Roman 的解决方案相比,在开头定义

namespace
变量有助于减少实际必须键入名称空间名称的地方的数量:

namespace=<NAME_OF_NAMESPACE> && kubectl get ns $namespace  -o json | jq '.spec.finalizers = []' | kubectl replace --raw "/api/v1/namespaces/$namespace/finalize" -f -

2
投票

这篇文章让我第二次来到这里,但是这次我们使用的是Rancher (RKE2) Kubernetes edition.

这里的技巧是直接调用 rancher api 以传递删除请求...(代理技巧不起作用)。希望这对某人有帮助

别忘了更改 Bearer Token

export NS='delete-me';
export YOURFQDN='rancher2.dev.prod.local';
export YOURCLUSTER='c-xxxx1';

kubectl get ns ${NS} -o json | jq '.spec.finalizers=[]' | \
curl -X PUT https://${YOURFQDN}/k8s/clusters/${YOURCLUSTER}/api/v1/namespaces/${NS}/finalize \
-H "Accept: application/json" \
-H "Authorization: Bearer token-xxxx:xxxxYOURxxxxTOKENxxxx" \
-H "Content-Type: application/json" --data @-

0
投票

我在 rke2/Harvester 集群中遇到了同样的问题。我尝试了一切(卷曲 k8s API、强制删除等)

命名空间中没有资源。

最后我从 etcd 中删除了密钥:

ETCDCTL_API=3 etcdctl \
  --cert=/var/lib/rancher/rke2/server/tls/etcd/client.crt \
  --key=/var/lib/rancher/rke2/server/tls/etcd/client.key \
  --cacert=/var/lib/rancher/rke2/server/tls/etcd/server-ca.crt \
  del /registry/namespaces/<NAMESPACE_TO_DELETE>

当然不是解决问题的最佳方法。但可能是最后的手段。


0
投票

如果您无法运行命令并且遇到任何解析错误:

curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json http://127.0.0.1:8001/api/v1/namespaces/[your-namespace]/finalize

然后确保您拥有的 json 具有如下所示的正确定稿,请注意定稿具有 [] :

"spec": {
"finalizers":[
]
© www.soinside.com 2019 - 2024. All rights reserved.