情況:
Kubectl delete ns XXXX 後, namespace 一直處於 Terminating 狀態。
使用:
kubectl delete ns monitoring --grace-period=0 –force
後,也無法刪除。
原因分析:
刪除時,報錯:
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 " monitoring ": The system is ensuring all content is removed from this namespace. Upon completion, this namespace will automatically be purged by the system.
這是因爲 k8s 認爲當前命名空間內,還存在未釋放資源,它告訴咱們一旦該命名空間下,所以資源釋放操作完成,命名空間會自動被清除掉。
實際觀察,可以發現,該命令執行後,namespace也一直卡住,究其原因,應該是的確有部分資源未釋放。
解決思路:
1、首先查看該命名空間下所有資源:
kubectl api-resources -o name --verbs=list –namespaced
這條命令可以查看你聲明過的資源類型。
2、然後使用 kubectl get 資源類型 –n 命名空間
查看是否真的存在未釋放的資源。
3、最終結果是,命名空間下全部資源都是No Resources沒有!
網上這份資料提供了另一種解決思路:
https://my.oschina.net/u/4222205/blog/3113044
1、首先通過
kubectl get namespace monitoring -o json > monitoring.json
這條命令,將當前的命名空間以 json文件的形式導出。
2、將 spec 下的內容刪除:這一步驟的目的在於將內容清空後,以空內容的ns覆蓋原有ns,這樣保證了要刪除的ns內容爲空,刪除的命令也就無法阻塞了
3、將具體內容爲空的 namespace ,通過 api-server 接口,覆蓋到k8s集羣中
需要注意的是:由於當前我們k8s主節點使用了認證,如果你直接使用以下命令,調用虛擬IP的api-server接口,會發現請求發送成功,但是沒有響應的情況,如下:
4、針對有認證的情況,需要使用 kube-proxy 進行代理:
kubectl proxy --port=8081
通過這一條命令,可以在本機使用kube-proxy將 api-server代理到本地 8081端口上,這樣就繞過了k8s的認證。
需要注意的是,使用 kubectl proxy 命令沒有使用守護模式,一次一旦你 Ctrl+c 後,就會發現,netstat –nlp | grep 8081 監聽的端口也沒有了。
正確的做法是:打開k8s主節點的兩個窗口,
在一個窗口中執行 kubectl proxy
另一個窗口中執行:
curl -k -H "Content-Type: application/json" -X PUT --data-binary @monitoring.json http://127.0.0.1:8081/api/v1/namespaces/monitoring/finalize
最終效果如下:
這個辦法解決的原理與強制重啓pod的命令其實是一樣的:
kubectl get pod PODNAME -n NAMESPACE -o yaml | kubectl replace --force -f –
將現有狀態導出,再執行覆蓋