DevOps

Как удалить namespace kube-flannel в Terminating

Пошаговое руководство по удалению namespace kube-flannel, застрявшего в статусе Terminating после удаления pod flannel в Kubernetes. Удаление finalizers, проверка ресурсов, kubectl команды и отладка ошибок для безопасного решения проблемы.

1 ответ 1 просмотр

Как удалить 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

Почему это вообще происходит? 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 удалится сам:

  1. Посмотреть статус namespace и finalizers:
bash
kubectl describe ns kube-flannel
kubectl get ns kube-flannel -o jsonpath='{.spec.finalizers}'
  1. Перечислить все (возможные) types и найти оставшиеся объекты в namespace:
bash
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 может не отобразить.

  1. Сконцентрируйтесь на DaemonSet/Pod:
bash
kubectl get daemonset -n kube-flannel
kubectl get pods -n kube-flannel -o wide
kubectl describe pod <имя-pod> -n kube-flannel
  1. Проверить API services / apiservice (если есть агрегированные APIs):
bash
kubectl get apiservice | grep False || true

Если apiservice помечен как False/unavailable, это может блокировать удаление ресурсов (см. GKE-руководство).

Если вы видите просто “остаточные” объекты — удалите их обычным способом. Если объекты невозможно удалить, дальше — снятие finalizers.


Пошаговая инструкция: безопасное удаление namespace kube-flannel

Ниже — рекомендуемая последовательность. Выполняйте шаги аккуратно; некоторые операции нарушают работу сетевого плагина.

Шаг 0 — бэкап состояния namespace:

bash
kubectl get namespace kube-flannel -o json > ns-kube-flannel.json

Шаг 1 — попытаться удалить зависшие ресурсы:

  • Удалите DaemonSet (если он ещё существует):
bash
kubectl delete daemonset <имя-daemonset> -n kube-flannel
  • Принудительно удалить висящие pods (если они не завершаются):
bash
kubectl delete pod <pod-name> -n kube-flannel --grace-period=0 --force

Повторите для всех найденных типов (deployments, daemonsets, serviceaccounts, roles, CRs).

Шаг 2 — если namespace всё ещё в Terminating — снять finalizers у namespace:

  1. Отредактируйте JSON (например через jq):
bash
jq '.spec.finalizers = []' ns-kube-flannel.json > ns-kube-flannel-fixed.json
  1. Примените через команду, которая отправляет объект в endpoint finalize:
bash
kubectl replace --raw "/api/v1/namespaces/kube-flannel/finalize" -f ns-kube-flannel-fixed.json

Если kubectl replace --raw недоступен, сделайте так:

bash
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 — проверка:

bash
kubectl get ns kube-flannel

После успешного применения finalize namespace обычно удаляется в пределах секунд.

Альтернатива (иногда срабатывает быстрее, но осторожно):

bash
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 или подготовьте ноды.

Проверки на нодах:

  • Поиск интерфейсов:
bash
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.


Источники

  1. Namespace “stuck” as Terminating. How do I remove it? — Stack Overflow
  2. Troubleshoot namespace stuck in the Terminating state — Google Cloud (GKE)
  3. How to fix Kubernetes namespaces stuck in the terminating state — Red Hat Blog
  4. Как удалить namespace в Kubernetes — Var Note
  5. Как принудительно удалить пространство имен (Namespace) в Kubernetes – IT is good

Заключение

Коротко: чтобы удалить kube-flannel namespace, сначала найдите и удалите зависшие ресурсы в kubernetes namespace (DaemonSet, pods, CR и т.п.), затем снимите finalizers у самого namespace (через /finalize или kubectl patch/replace). Снятие finalizers — рабочий способ закрыть зависший Terminating, но делайте его осознанно: finalizers служат для очистки внешних артефактов, и их принудительное удаление может оставить следы (сетевые интерфейсы, IP и т.д.).

Авторы
Проверено модерацией
Модерация
Как удалить namespace kube-flannel в Terminating