Как заставить удалить пространство имен Kubernetes?
Как принудительно удалить пространства имен, застрявшие в терминации?
Шаги для воссоздания:
- Применить этот YAML
apiVersion: v1
kind: Namespace
metadata:
name: delete-me
spec:
finalizers:
- foregroundDeletion
kubectl delete ns delete-me
Не возможно удалить
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
отредактированный ресурс для / финализации
Возвращает 405. Я не уверен, что это канонический способ POST / финализировать.
связи
Это, кажется , повторяющаяся проблема, и ни один из этих ресурсов не помог.
8 ответов
kubectl proxy
попробуй почти правильно, но не совсем. Можно использовать JSON вместо YAML, но я не уверен.
JSON с пустым списком финализаторов:
~$ cat ns.json
{
"kind": "Namespace",
"apiVersion": "v1",
"metadata": {
"name": "delete-me",
"selfLink": "/api/v1/namespaces/delete-me",
"annotations": {
"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Namespace\",\"metadata\":{\"annotations\":{},\"name\":\"delete-me\"},\"spec\":{\"finalizers\":[\"foregroundDeletion\"]}}\n"
}
},
"spec": {
"finalizers": [
]
},
"status": {
"phase": "Terminating"
}
}
использование curl
в PUT
объект без проблемного финализатора.
~$ 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 @-
kubectl get ns delete-me -o json | jq '.spec.finalizers = []' | kubectl replace --raw "/api/v1/namespaces/your-ns/finalize" -f -
Битовая модификация приведенной выше команды.
namespace=delet_ns && kubectl get ns $ namespace -o json | jq '.spec.finalizers = []' | kubectl replace --raw "/ api / v1 / namespaces / $ namespace / finalize" -f
Эта статья привела меня сюда во второй раз, но на этот раз мы используем редакцию Rancher (RKE2) Kubernetes.
Хитрость здесь заключается в том, чтобы напрямую вызвать API ранчера, чтобы передать запрос на удаление... (трюк с прокси не работает). Надеюсь, это поможет кому-то
Не забудьте сменить Bearer Token
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. Я пробовал все (свернуть API k8s, принудительно удалить и т. д.)
Там, где в пространстве имен не осталось ресурса.
Наконец, я удалил ключ из 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>
Конечно, это не лучший способ решить проблему. Но может быть в крайнем случае.
Чтобы узнать, какие ресурсы препятствуют прекращению выполнения вашего пространства имен:
kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get --show-kind --ignore-not-found -n <namespace_name>
Если ваше пространство имен находится в состоянии завершения, удалите значение финализатора в файле YAML: kubectl edit ns <namespace_name> (finalizers: [])
В дальнейшем вы можете использовать эту команду для принудительного удаления пространства имен
kubectl delete ns <namespace_name> --force --grace-period=0
Если вы не можете запустить команду и получаете ошибку синтаксического анализа:
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 есть [] :
"spec": {
"finalizers":[
]