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



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

重新创建的步骤:

  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 的规范方式。

链接

这 出现 自 是 一个 经常性 问题 和 没有 之 这些 资源 帮助。

Kubernetes bug

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

具有空终结器列表的 JSON:

~$ cat ns.json
{
"kind": "Namespace",
"apiVersion": "v1",
"metadata": {
"name": "delete-me"
},
"spec": {
"finalizers": []
}
}

使用curlPUT对象,而不使用有问题的终结器。

~$ 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

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

在一个终端中:

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 @-

在将两次出现的<NAME_OF_NAMESPACE>替换为 Terminate 中命名空间的实际名称后应用此命令可以解决此问题:

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 命名空间配置(不带终结器)注入 k8 中。

这是对用户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 -

这篇文章第二次把我带到这里,但这次我们使用的是Rancher(RKE2)Kubernetes版本

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

不要忘记更改持有者令牌

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 @-

我在 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>

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

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

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 具有正确的 finalize,如下所示,请注意 finalize 有[]

"spec": {
"finalizers":[
]

最新更新