k8s删除namespace之后状态一直为Terminating
文章发布较早,内容可能过时,阅读注意甄别。
使用 k8s 时,执行如下命令删除一个 namespace:
$ kubectl delete ns local
1
随后查看该 ns 的状态,可以看到该 ns 始终保持在 Terminating 状态:
$ kubectl get ns local
NAME STATUS AGE
local Terminating 3d1h
1
2
3
4
2
3
4
如果出现这种问题,一般情况下都是finalizers
字段捣的鬼。
参看这篇文章:熟悉又陌生的 k8s 字段:finalizers (opens new window) 可以了解到:
Finalizers 字段属于 Kubernetes GC 垃圾收集器,是一种删除拦截机制,能够让控制器实现异步的删除前(Pre-delete)回调。其存在于任何一个资源对象的 Meta (opens new window) 中,在 k8s 源码中声明为
[]string
,该 Slice 的内容为需要执行的拦截器名称。
通常删除不掉可能是因为集群内有某些 webhook,从而导致这个问题,如果此时该 webhook 并不能确定是否可以删除,那么网上提到的,直接编辑 ns,删除 finalizers 的值是无法解决的,仍旧会遇到如下报错:
$ kubectl edit ns local
error: namespaces "local" could not be patched: Internal error occurred: failed calling webhook "rancherauth.cattle.io": Post "https://rancher-webhook.cattle-system.svc:443/v1/webhook/validation?timeout=10s": no endpoints available for service "rancher-webhook"
You can run `kubectl replace -f /tmp/kubectl-edit-550962354.yaml` to try this update again.
1
2
3
4
2
3
4
这个时候,可以参考此文档的方案解决:移除該死的 Terminating Namespace (opens new window)
上边文档最后留了一个脚本,用于删除这种状态的 namespace 的 finalizers 字段,因为脚本还缺了一些内容,因此调整之后补充如下:
#!/bin/bash
if [[ $# -ne 1 ]]; then
echo "Please input only namespace name"
exit 1
fi
ns=$1
kubectl get ns ${ns} -o json > tmp.json
cat ./tmp.json | jq 'del(.spec.finalizers[])' > ./modify.json
cat ./tmp.json | jq 'del(.metadata.finalizers[])' > ./modify.json
kubectl replace --raw "/api/v1/namespaces/${ns}/finalize" -f ./modify.json
rm -f tmp.json modify.json
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
然后执行脚本,将名称空间放在第一个位置参数即可:bash remove-ns.sh local
。
上次更新: 2024/11/19, 23:11:42