Как удалить namespace kube-flannel в Terminating
Пошаговое руководство по удалению namespace kube-flannel, застрявшего в статусе Terminating после удаления pod flannel в Kubernetes. Удаление finalizers, проверка ресурсов, kubectl команды и отладка ошибок для безопасного решения проблемы.
Как удалить namespace kube-flannel, который застрял в статусе Terminating после удаления pod flannel?
Чтобы удалить namespace kube-flannel, который застрял в статусе Terminating, сначала проверьте и удалите зависшие ресурсы в этом kubernetes namespace (DaemonSet, pods, CR и т.п.), а затем снимите блокирующие finalizers у самого namespace через API (/finalize) или kubectl patch/replace. Обычно последовательность: сохранить JSON namespace, очистить spec.finalizers (пустой массив) и применить kubectl replace --raw '/api/v1/namespaces/kube-flannel/finalize' -f tmp.json — после этого namespace удалится.
Содержание
- Почему namespace kube-flannel застрял в Terminating
- Предварительная проверка: что посмотреть первым делом
- Пошаговая инструкция: безопасное удаление namespace kube-flannel
- Принудительное удаление через finalizers (подробно)
- Проверка CNI Flannel и последствия удаления
- Частые ошибки и отладка
- Источники
- Заключение
Почему namespace kube-flannel застрял в Terminating
Почему это вообще происходит? Kubernetes помечает namespace как Terminating, когда инициирована его удаление, но какой‑то контроллер или ресурс не завершил свою очистку. Чаще всего виновники:
- finalizers на объекте namespace (поле
spec.finalizers) — контроллеры должны убрать их после своей работы; если контроллер отсутствует или упал, namespace блокируется; - оставшиеся namespaced ресурсы (DaemonSet, Pod, CustomResource, PVC и т.п.), которые не удаляются;
- проблемы с API aggregation / apiservices или контроллерами (CRD контроллеры, которые должны удалить свои CR);
- сетевые/СNI артефакты (у Flannel — интерфейсы, правила iptables), которые мешают корректному завершению подов.
Официальный гайд Google по этой проблеме описывает проверку finalizers и ресурсо́в и варианты применения /finalize API: https://cloud.google.com/kubernetes-engine/docs/troubleshooting/terminating-namespaces. Практические примеры — в обсуждениях на StackOverflow и в статьях Red Hat и сообществ: https://stackoverflow.com/questions/52369247/namespace-stuck-as-terminating-how-do-i-remove-it, https://www.redhat.com/en/blog/troubleshooting-terminating-namespaces.
Предварительная проверка: что посмотреть первым делом
Перед принудительными выпилками сначала диагностируйте — возможно, достаточно удалить несколько ресурсов и namespace удалится сам:
- Посмотреть статус namespace и finalizers:
kubectl describe ns kube-flannel
kubectl get ns kube-flannel -o jsonpath='{.spec.finalizers}'
- Перечислить все (возможные) types и найти оставшиеся объекты в namespace:
kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get -n kube-flannel --ignore-not-found
Это покажет CR, ConfigMap, ServiceAccount, RoleBinding и т.д., которые стандартный kubectl get all может не отобразить.
- Сконцентрируйтесь на DaemonSet/Pod:
kubectl get daemonset -n kube-flannel kubectl get pods -n kube-flannel -o wide kubectl describe pod <имя-pod> -n kube-flannel
- Проверить API services / apiservice (если есть агрегированные APIs):
kubectl get apiservice | grep False || true
Если apiservice помечен как False/unavailable, это может блокировать удаление ресурсов (см. GKE-руководство).
Если вы видите просто “остаточные” объекты — удалите их обычным способом. Если объекты невозможно удалить, дальше — снятие finalizers.
Пошаговая инструкция: безопасное удаление namespace kube-flannel
Ниже — рекомендуемая последовательность. Выполняйте шаги аккуратно; некоторые операции нарушают работу сетевого плагина.
Шаг 0 — бэкап состояния namespace:
kubectl get namespace kube-flannel -o json > ns-kube-flannel.json
Шаг 1 — попытаться удалить зависшие ресурсы:
- Удалите DaemonSet (если он ещё существует):
kubectl delete daemonset <имя-daemonset> -n kube-flannel
- Принудительно удалить висящие pods (если они не завершаются):
kubectl delete pod <pod-name> -n kube-flannel --grace-period=0 --force
Повторите для всех найденных типов (deployments, daemonsets, serviceaccounts, roles, CRs).
Шаг 2 — если namespace всё ещё в Terminating — снять finalizers у namespace:
- Отредактируйте JSON (например через jq):
jq '.spec.finalizers = []' ns-kube-flannel.json > ns-kube-flannel-fixed.json
- Примените через команду, которая отправляет объект в endpoint finalize:
kubectl replace --raw "/api/v1/namespaces/kube-flannel/finalize" -f ns-kube-flannel-fixed.json
Если kubectl replace --raw недоступен, сделайте так:
kubectl proxy --port=8001 &
curl -k -H "Content-Type: application/json" -X PUT --data-binary @ns-kube-flannel-fixed.json http://127.0.0.1:8001/api/v1/namespaces/kube-flannel/finalize
Шаг 3 — проверка:
kubectl get ns kube-flannel
После успешного применения finalize namespace обычно удаляется в пределах секунд.
Альтернатива (иногда срабатывает быстрее, но осторожно):
kubectl patch namespace kube-flannel -p '{"spec":{"finalizers":[]}}' --type=merge
Некоторые кластеры/версии kubectl понимают metadata.finalizers=null, но это не универсально; предпочтительнее явно установить пустой массив в spec.finalizers.
Подсказка: подробные практические примеры есть на StackOverflow и в русскоязычных заметках: https://stackoverflow.com/questions/52369247/namespace-stuck-as-terminating-how-do-i-remove-it, https://varnote.ru/kubernetes/delete-namespace/.
Принудительное удаление через finalizers (подробно)
Что такое finalizer? Это метка, которая говорит API не удалять объект, пока указанная операция очистки не выполнена контроллером. Если контроллера нет — finalizer становится вечной блокировкой.
Почему лучше сначала удалять ресурсы вручную? Потому что finalizer действует как защитный механизм: он даёт контроллеру шанс убрать внешние ресурсы (IP, объекты в облаке и т.п.). Удаление finalizer вручную — экстренная мера: она удаляет namespace, но внешние артефакты могут остаться.
Когда использовать снятие finalizer:
- Контроллер мёртв (удалён) и невозможно восстановить его работу.
- Ресурсы в namespace явно удалять вручную вы не можете (контроллер зависает).
- Вы понимаете последствия (утечки IP, оставшийся CNI state и т.п.).
Процесс снятия finalizer — тот самый kubectl replace --raw .../finalize с JSON, где spec.finalizers = [].
Если у вас нет прав применять finalize через API (403), обратитесь к администратору кластера — действие требует доступа к API на запись namespace.
Проверка CNI Flannel и последствия удаления
Flannel — сетевой (CNI) плагин; удалить его namespace и daemonset легко, но что с сетью на нодах? Возможные последствия:
- Останутся интерфейсы типа
flannel.1, мостыcni0, правила iptables/NETMAP, маршруты — могут повлиять на сеть подов. - Если вы планируете полностью демонтировать Flannel и поставить другой CNI, сначала установите новый CNI или подготовьте ноды.
Проверки на нодах:
- Поиск интерфейсов:
ip link show | grep flannel || true
ip addr show
- Удаление сетевых артефактов требует действий на ноде: удаление интерфейсов, очистка iptables, перезапуск kubelet или перезагрузка ноды. Делайте это аккуратно — можно потерять связь с нодой.
Если вы удаляете только namespace как артефакт (например, после ручного удаления Flannel), то очистка finalizers безопасна, но проверьте ноды на остатки Flannel.
Частые ошибки и отладка
- Ошибка:
namespace still terminating after patch/finalize— вероятно остались CR в namespace; убедитесь, что вы перечислили все namespaced ресурсы черезkubectl api-resources ... | xargs .... - Ошибка: права (403) при обращении к
/finalize— нужен доступ к API; попросите админа или используйте аккаунт с cluster-admin. - apiservice/CRD контроллеры: если CRD контроллер отключён, CR не удаляются и finalizer остаётся. Проверьте
kubectl get apiserviceи логи контроллеров. - После удаления finalizers namespace исчез, но остались внешние ресурсы (IP, записи в облаке) — придётся чистить вручную.
- Если ничего не помогает и это продакшен‑кластер — сначала снимите снимок etcd или обратитесь в поддержку (для managed‑Kubernetes). Прямые правки в etcd — крайняя мера и рискованны.
Дополнительные руководства и объяснения есть в официальной документации GKE и на Red Hat: https://cloud.google.com/kubernetes-engine/docs/troubleshooting/terminating-namespaces, https://www.redhat.com/en/blog/troubleshooting-terminating-namespaces.
Источники
- Namespace “stuck” as Terminating. How do I remove it? — Stack Overflow
- Troubleshoot namespace stuck in the Terminating state — Google Cloud (GKE)
- How to fix Kubernetes namespaces stuck in the terminating state — Red Hat Blog
- Как удалить namespace в Kubernetes — Var Note
- Как принудительно удалить пространство имен (Namespace) в Kubernetes – IT is good
Заключение
Коротко: чтобы удалить kube-flannel namespace, сначала найдите и удалите зависшие ресурсы в kubernetes namespace (DaemonSet, pods, CR и т.п.), затем снимите finalizers у самого namespace (через /finalize или kubectl patch/replace). Снятие finalizers — рабочий способ закрыть зависший Terminating, но делайте его осознанно: finalizers служат для очистки внешних артефактов, и их принудительное удаление может оставить следы (сетевые интерфейсы, IP и т.д.).