Гид по технологиям

Обслуживание узлов Kubernetes: cordon и drain

• 6 min read • Kubernetes • Обновлено 18 Nov 2025
Обслуживание узлов Kubernetes: cordon и drain
Обслуживание узлов Kubernetes: cordon и drain

Логотип Kubernetes на информативной графике

Быстрые ссылки

  • Применение cordon к узлу
  • Выполнение drain на узле
  • Принудительное завершение Pod без grace period
  • Решение типичных ошибок drain
  • Минимизация простоя с помощью Pod Disruption Budgets
  • Повторное включение узлов в кластер
  • Краткое резюме

Краткие определения

  • cordon — отметить узел как «недоступный для планировщика», чтобы на него не попадали новые Pod.
  • drain — эвакуировать (evict) текущие Pod с узла, чтобы освободить его для отключения или удаления.

Важно: cordon не завершает запущенные Pod; он только блокирует новые.

Применение cordon к узлу

Cordoning помечает узел как непригодный для новых размещений. Команда:

kubectl cordon 

Пример:

$ kubectl cordon node-1
node/node-1 cordoned

Проверка статуса узлов:

$ kubectl get nodes
NAME       STATUS                     ROLES                  AGE   VERSION
node-1     Ready,SchedulingDisabled   control-plane,master   26m   v1.23.3

Узлы с пометкой SchedulingDisabled не принимают новых Pod.

Выполнение drain на узле

Drain инициирует процедуру эвакуации Pod с указанного узла. Он сначала ставит cordon (если вы этого не сделали вручную), затем пытается безопасно завершить Pod и дать им возможность корректно завершиться перед удалением.

Запуск drain:

$ kubectl drain node-1

Пример вывода:

node/node-1 already cordoned
evicting pod kube-system/storage-provisioner
evicting pod default/nginx-7c658794b9-zszdd
evicting pod kube-system/coredns-64897985d-dp6lx
pod/storage-provisioner evicted
pod/nginx-7c658794b9-zszdd evicted
pod/coredns-64897985d-dp6lx evicted
node/node-1 evicted

После успешного drain вы можете безопасно выключать или удалять узел.

Примечание: drain не завершит Pod, защищённых PodDisruptionBudget без явного разрешения.

Принудительное завершение Pod: игнорирование grace periods

Если Pod имеют длинный grace period и вам нужно срочно вывести узел, используйте флаг --grace-period:

$ kubectl drain node-1 --grace-period 0

Важно: это принудительно остановит контейнеры без времени на очищающие операции. Используйте с осторожностью.

Решение типичных ошибок drain

Ниже — два распространённых сценария и способы их решения.

Нельзя удалить Pod, не управляемые контроллером

Ошибка появляется, если на узле есть «голые» Pod — созданные вручную и не принадлежащие Deployment/ReplicaSet/StatefulSet/Job. Kubernetes не может автоматически пересоздать такие Pod на других узлах.

Варианты решения:

  • Перевести Pod под управление контроллера (создать Deployment/ReplicaSet).
  • Удалить Pod вручную и затем выполнить drain.
  • Если вы понимаете риски, можно применить --force:
$ kubectl drain node-1 --force

--force удалит «голые» Pod, делая их недоступными.

Нельзя удалить Pod, управляемые DaemonSet

DaemonSet создаёт Pod на каждом узле и игнорирует SchedulingDisabled. При удалении такой Pod он сразу пересоздаётся на том же узле — поэтому drain завершится с ошибкой.

Решение: пропустить DaemonSet’ы при эвакуации:

$ kubectl drain node-1 --ignore-daemonsets

Даже системные компоненты в kube-system часто используют DaemonSet, поэтому флаг может понадобиться, даже если вы их явно не создавали.

Минимизация простоя: Pod Disruption Budgets (PDB)

Pod Disruption Budget — объект, который ограничивает количество одновременно недоступных Pod для набора ресурсов (Deployment, ReplicaSet, StatefulSet и т.д.).

Принцип: PDB гарантирует, что будет доступно минимальное количество Pod (или не более определённого процента будет недоступно) во время планируемых прерываний.

Пример YAML PDB:

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: demo-pdb
spec:
  minAvailable: 4
  selector:
    matchLabels:
      app: my-app

Эта политика требует минимум 4 запущенных Pod с меткой app=my-app. Drain, который приведёт к меньшему числу доступных Pod, будет заблокирован.

Параметры:

  • minAvailable: 4 — требовать как минимум 4 Pod.
  • maxUnavailable: 50% — разрешить до 50% Pod быть недоступными.

Только одно поле (minAvailable или maxUnavailable) может присутствовать.

Пересечение с drain: как обходить PDB

Если нужно немедленно вывести узел, можно обойти механизм эвакуации и напрямую удалять Pod:

$ kubectl drain node-1 --disable-eviction

Это удалит Pod, игнорируя PDB. Используйте только в крайних случаях.

Повторное включение узла в кластер

После завершения обслуживания включите или перезагрузите узел и снимите cordon:

$ kubectl uncordon node-1
node/node-1 uncordoned

После uncordon планировщик начнёт назначать на узел новые Pod.

Когда cordon+drain не сработают: типичные сценарии отказа

  • Недостаточно резерва в кластере: нет свободных ресурсов для переселения Pod.
  • “Голые” Pod без контроллера — они исчезнут при --force и не восстановятся.
  • Неправильно настроенные PDB блокируют планирование при массовых drain.
  • Стейтфулные приложения (StatefulSet) требуют специальных шагов для сохранения порядка и данных.

Контрпример: в кластере с тремя узлами и Deployment, где реплик ровно 3, drain одного узла может нарушить доступность, если PDB требует minAvailable:3.

Альтернативные подходы

  • Горизонтальное масштабирование кластера перед обслуживанием: добавить узел, дать кластерам перераспределиться, затем drain и удалить.
  • Использовать Rolling Update на уровне инфраструктуры (например, провайдерские инструменты), чтобы постепенно заменять узлы без одновременной потери вместимости.
  • Для критичных сервисов применять multi-zone/region кластеры.

Ментальные модели и эвристики

  • Модель “места и вместимости”: представьте, что все Pod — это чемоданы, а узлы — полки. Cordoning закрывает полку для новых чемоданов, drain аккуратно перекладывает чемоданы на другие полки.
  • Эвристика SRE: никогда не выводите более 10–20% узлов одновременно без проверки доступных ресурсов и PDB.

Быстрый набор команд (cheat sheet)

kubectl cordon NODE                  # заблокировать узел для новых Pod
kubectl drain NODE                   # эвакуировать Pod c NODE
kubectl drain NODE --ignore-daemonsets
kubectl drain NODE --force           # удалить "голые" Pod
kubectl drain NODE --grace-period 0  # форсированное завершение
kubectl drain NODE --disable-eviction# обойти PDB
kubectl uncordon NODE                # вернуть узел в планирование
kubectl get pods -o wide --all-namespaces
kubectl get pdb                      # список Pod Disruption Budgets
kubectl describe node NODE           # данные по узлу

Роли и чек-листы

Оператор (инженер поддержки):

  • Проверить свободную ёмкость кластера (CPU, RAM, диски).
  • Найти зависимости (PDB, StatefulSet, DaemonSet).
  • Запланировать maintenance window.
  • Выполнить cordon → drain → выключение → uncordon.

Разработчик приложения:

  • Убедиться, что Pod управляются контроллером (Deployment/StatefulSet).
  • Настроить корректный readinessProbe и livenessProbe.
  • Определить адекватный terminationGracePeriodSeconds.

SRE/руководитель смены:

  • Проверить PDB для критичных сервисов.
  • Координировать одновременные drains между зонами.
  • Иметь план отката в случае проблем.

Процедура (SOP) — быстрый playbook

  1. Оповестить потребителей и команду (maintenance window).
  2. Проверить метрики кластера и available resources.
  3. Запустить kubectl cordon NODE.
  4. Запустить kubectl drain NODE (или с флагами при необходимости).
  5. Наблюдать за статусом Pod и Logs.
  6. Выполнить аппаратное обслуживание/обновление.
  7. Перезапустить узел и kubectl uncordon NODE.
  8. Проверить, что Pod успешно запустились и метрики в норме.

Критерии приёмки

  • Узел снят с обслуживания и снова возвращён в пул.
  • Все Pod целевых приложений восстановлены и в состоянии Ready.
  • Нет нарушений PDB (кроме тех случаев, где отключение было согласовано).
  • Латентность и ошибки приложения возвращены к предвиденным уровням.

Тестовые случаи / критерии приёмки

  1. Drain узла с Deployment (3 реплики) при наличии свободного места на других узлах — все Pod перезапускаются и доступны.
  2. Drain узла с “голыми” Pod без --force — drain должен завершиться с ошибкой.
  3. Drain узла с DaemonSet — при отсутствии --ignore-daemonsets операция должна предупредить.
  4. Принудительный drain с --grace-period 0 — Pod завершаются немедленно; приложение может потерять незавершённые транзакции (ожидаемое поведение).

Диаграмма принятия решения (Mermaid)

flowchart TD
  A[Начало обслуживания узла] --> B{Доступно ли место в кластере?}
  B -- Да --> C[cordon]
  B -- Нет --> D[Добавить узел или перенести нагрузку]
  C --> E{Есть ли Pod без контроллера?}
  E -- Да --> F[Перевести под контроллер или использовать --force]
  E -- Нет --> G{DaemonSet есть?}
  G -- Да --> H[Добавить --ignore-daemonsets]
  G -- Нет --> I[drain]
  I --> J[Отключить/обслужить узел]
  J --> K[uncordon и проверка]
  F --> I
  H --> I

Факты и подсказки

  • Cordoning — быстрый и безопасный шаг; он не прерывает трафик.
  • Drain может заблокироваться PDB, проверьте их заранее.
  • Stateful приложения требуют дополнительной осторожности (например, порядок остановки, сохранение состояний).

Безопасность и приватность

  • Убедитесь, что учетные записи и права (RBAC) соответствуют политикам безопасности: команды kubectl drain/cordon требуют соответствующих разрешений.
  • При использовании облачных API для удаления узлов не храните секреты в явном виде.

Локальные особенности и советы для разных провайдеров

  • В облаке: сначала масштабируйте группу узлов, дождитесь присоединения новых нод, затем drain.
  • На bare-metal: подготовьте план отказоустойчивости сети и хранение данных (SAN/NFS) перед выключением узла.

Резюме

Cordons и drains — стандартный и безопасный путь подготовки узла Kubernetes к обслуживанию. Cordons запрещают новые планирования, drain аккуратно переселяет Pod. В критичных системах сочетайте эти команды с Pod Disruption Budgets и тестами, чтобы избежать неожиданного простоя. Планируйте действия, соблюдайте роли и следуйте playbook, чтобы выполнение обслуживания было повторяемым и безопасным.

Важно: всегда тестируйте процедуру на стенде, прежде чем выполнять в production.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Несколько аккаунтов Skype: Multi Skype Launcher
Программное обеспечение

Несколько аккаунтов Skype: Multi Skype Launcher

Журнал для работы: повысить продуктивность
Productivity

Журнал для работы: повысить продуктивность

Персональные звуки уведомлений на Android
Android.

Персональные звуки уведомлений на Android

Скачивание шоу Hulu для офлайн‑просмотра
Стриминг

Скачивание шоу Hulu для офлайн‑просмотра

Microsoft Start: персонализированная новостная лента
Новости

Microsoft Start: персонализированная новостная лента

Как изменить имя в Epic Games быстро
Гайды

Как изменить имя в Epic Games быстро