问题

删除namespace时,一直处于 terminating 状态。无法删除。

$ kubectl delete ns skynet
Error from server (Conflict): Operation cannot be fulfilled on namespaces "skynet": The system is ensuring all content is removed from this namespace. Upon completion, this namespace will automatically be purged by the system. 

$ kubectl describe ns skynet
Name: skynet 
Labels: <none> 
Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"skynet","namespace":""}} 

Status: Terminating 

根本原因

namespace删除卡住有很多原因,一般最常见的原因是namespace下有某些资源没有被删除导致namespace删除卡死。

解决方案

常见的有两种处理方案,根据我们的目的可以选择不同方案来删除卡死的namespace

  • 检查和定位namespace删除失败的原因,并手动清空namespace下无法自动删除的资源
  • 移除namespace的finalizers,让 kube-api直接删除namespace

方案1

删除namespace时,如果有些资源无法自动删除,会导致namespace无法删除,所以需要找到不能被删除的资源并手动删除,namespace就会被清理。

  1. 检查定位namespace下没有删除的资源
kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get -n namespace name
  1. 检测是否有外部注册的 apiservices 服务无法访问
kubectl get apiservice | grep False

方案2

删除namespace时,如果 namespace 字段 finalizers 不为空,且值是 kubernetes 时,apiserver 服务就会尝试清理该namespace下的所有资源,如果有部分资源无法被清理,则删除过程就会卡住。当把 finalizers 更新为空时,apiserver 就会跳过清理,直接删除namespace。但这种方案会有没有删除的资源遗留在集群。

  1. 获取namespace
$ NAMESPACE=skynet
$ kubectl get ns $NAMESPACE -o json > /tmp/${NAMESPACE}.json
$ cat /tmp/${NAMESPACE}.json
{
"apiVersion": "v1",
"kind": "Namespace",
"metadata": {
"creationTimestamp": "2019-02-04T16:15:06Z",
"name": "skynet",
"resourceVersion": "20879144",
"selfLink": "/api/v1/namespaces/skynet",
"uid": "0951bcf9-2898-11e9-8e38-0242ac11000b"
},
"spec": {
"finalizers": [
"kubernetes"
]
},
"status": {
"phase": "Active"
}
}
  1. 修改 finalizers 字段为空,如下
{
"apiVersion": "v1",
"kind": "Namespace",
"metadata": {
"creationTimestamp": "2019-02-04T16:15:06Z",
"name": "skynet",
"resourceVersion": "20879144",
"selfLink": "/api/v1/namespaces/skynet",
"uid": "0951bcf9-2898-11e9-8e38-0242ac11000b"
},
"spec": {
"finalizers": [
]
},
"status": {
"phase": "Active"
}
}
  1. 更新namespace对象
curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json https://kubernetes-cluster-ip/api/v1/namespaces/skynet/finalize