k8s 命名空间Terminating产生原因及解决方法
为什么删除ns会出现Terminating的情况
当删除集群中的某个namespace之后,有时候namespace并没有按照我们的期望正常删除,而是一直卡在Terminating状态。
删除namespace后到底发生了什么
从kubectl delele namespace动作开始,当执行了删除命名空间的动作后,k8s并不会直接删除该命名空间,而是设置了namespace对象的metadata.deleteTimestasp字段,然后kube-controlller-manager组件中的namespace-controller开始工作,负责执行namespace删除的相关事宜,比如清理被删除命名空间下面的资源等,最后才会删除该命名空间,而如果namespace-controller有报错或者没有走到终止流程,就会一直卡在Terminating状态。
namespace-controller的工作流程,如图所示:
状态
使用kubectl delete -f xxx.yaml,再次执行 kubectl apply -f xxx.yaml,提示:
1 |
|
原因及解决方法
原因1:finalizer(main)
finalizer导致namespace Terminating一般主要集群中以下两种情况:
1. namespace资源对象的spec.finalizer[] 列表中不为空
rancher删除之后,有些namespace删除后就是这种情况.
解决办法:手动清理
- 查看cattle-system的namespace描述
1
➜ fb git:(master) kubectl get ns cattle-system -o json > cattle.json
- 编辑json文件,删除spec字段的内存,因为k8s集群需要认证
1
2
3
4
5
6
7
8
9➜ fb git:(master) vim cattle-system.json
将
"spec": { "finalizers": [ "kubernetes"
]
},
更改为:
"spec": {
}, - 新开一个窗口运行kubectl proxy跑一个API代理在本地的8081端口
1
2➜ ~ kubectl proxy --port=8081
Starting to serve on 127.0.0.1:8081 - check the status
1
2
3➜ fb git:(master) lsof -i:8081
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
kubectl 31323 leiyawu 3u IPv4 650617594 0t0 TCP localhost:tproxy (LISTEN) - 运行curl命令进行删除 注意:命令中的cattle.json是之前修改的json文件,cattle-system就是terminating的命名空间
1
➜ fb git:(master) curl -k -H "Content-Type:application/json" -X PUT --data-binary @cattle.json http://127.0.0.1:8081/api/v1/namespaces/cattle-system/finalize
- 再次查看namespace,发现cattle-system命名空间已经消失了。
如果出现多个命名空间无法删除的情况,循环遍历以上操作即可。
1 |
|
2. namespace资源对象的metadata.finalizer[] 列表不为空
比如:将集群托管到rancher管理后,rancher就会写finalizer到metadata.finalizer[] 列表,而当集群脱离rancher管理之后,手动删除namespace,往往就会发生Terminating
解决办法:
1 |
|
或者直接通过tke 控制台YAML编辑对应的NS
原因2:资源发现(minor)
k8s的api组织形式
k8s使用的是声明式API,其中API是通过分组、版本、资源名组成,而谈论某个资源,必须要属于某个API分组/版本,比如通过yaml创建对象时,除了要声明Kind外,还需要声明apiVersion对象。
1 |
|
聚合层扩展kubernetes api
聚合层通常用于扩展k8s api-server,允许添加新的API分组/版本。用户通过创建apiService对象来注册API,并声明自定义的扩展apiserver,当请求到该API分组/版本的时候,k8s apiservice会代理转发到后端自定义的apiserver来处理。比如,TKE集群中的hpa-metrics-server,就实现了metrics.k8s.io/v1beta1 这个API分组/版本(用户也可以部署promethues的metrics-adapter进行替换)。
在资源发现这里,会先获取API分组/版本信息,然后再获取各个API分组/版本的资源信息,从而罗列出集群中的所有资源。如果罗列资源发生报错,也有可能导致namespace卡主Terminating状态,常见于聚合层扩展kubernetes api。
- 查看是namespace 卡住Terminating的原因
1
2
3
4
5
6
7
8
9$ kubectl get namespace <name> -o yaml
conditions:
- lastTransitionTime: "2021-03-12T12:46:17Z"
message: 'Discovery failed for some groups, 1 failing: unable to retrieve the
complete list of server APIs: webhook.cert-manager.io/v1beta1: the server is
currently unable to handle the request'
reason: DiscoveryFailed
status: "True"
type: NamespaceDeletionDiscoveryFailure - 查看apiservice的状态
1
2
3
4
5
6
7
8➜ fb git:(master) kubectl get apiservice
NAME SERVICE AVAILABLE AGE
v1. Local True 484d
v1.admissionregistration.k8s.io Local True 484d
v1.apiextensions.k8s.io Local True 484d
v1.apps Local True 484d
v1.authentication.k8s.io Local True 484d
... - 将异常的apiservice状态恢复成True或者删除不需要的apiservice,即可恢复
参考文献:
https://cloud.tencent.com/developer/article/1802531
https://cloud.tencent.com/developer/article/1678604
https://medium.com/%E8%BC%95%E9%AC%86%E5%B0%8F%E5%93%81-pks%E8%88%87k8s%E7%9A%84%E9%BB%9E%E6%BB%B4/%E7%A7%BB%E9%99%A4%E8%A9%B2%E6%AD%BB%E7%9A%84terminating-namespace-c6594ebe351
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!