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

Как безопасно обслуживать узлы Kubernetes: cordon и drain

• 7 min read • Kubernetes • Обновлено 01 Dec 2025
Cordon и drain в Kubernetes — безопасное обслуживание узлов
Cordon и drain в Kubernetes — безопасное обслуживание узлов

Графика с логотипом Kubernetes

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

  • Применение cordon к узлу
  • Эвакуация (drain)
  • Игнорирование grace period у Pod
  • Решение ошибок при drain
  • Минимизация простоя с Pod Disruption Budget
  • Возвращение узлов в кластер
  • Контрольный список и playbook
  • Критерии приёмки

Kubernetes-узлы требуют периодического обслуживания: обновление ядра, изменение ресурсов в облаке, замена железа в собственной инфраструктуре. Для безопасного вывода узла из кластера используются механизмы cordon и drain. Они позволяют переселить рабочие нагрузки на другие узлы, чтобы затем выключить или удалить узел без простоя сервисов.

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

Cordon помечает узел как недоступный для планировщика Kubernetes. На такой узел не будут назначаться новые Pod’ы.

Выполните:

kubectl cordon <имя-узла>

Пример:

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

Уже запущенные Pod’ы на узле при cordon не прерываются — они остаются работать до завершения или удаления. Проверить состояние узлов можно командой:

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

У cordoned-узлов в столбце STATUS появляется метка SchedulingDisabled.

Важно: cordon — это только запрет на планирование новых Pod’ов, а не эвакуация существующих.

Эвакуация узла (drain)

Drain — это процесс, при котором текущие Pod’ы удаляются с узла и повторно создаются на других узлах кластера. Pod’ы позволяется корректно завершиться в рамках их grace period перед удалением.

Выполните:

$ 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

Если cordon не был установлен вручную, drain автоматически выполнит cordon перед началом эвакуации.

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

Когда drain может занять много времени

Если у Pod’ов установлены большие grace period, drain будет ждать их корректного завершения. При экстренном выводе узла это может быть неприемлемо — см. раздел об игнорировании grace period.

Игнорирование grace period у Pod

Чтобы принудительно удалить Pod’ы сразу, можно переопределить grace period:

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

Это форсирует немедленную эвакуацию, но может привести к повреждению данных или некорректному завершению задач. Используйте с осторожностью.

Важно: не применяйте –grace-period=0 для stateful-приложений без плана отката.

Решение ошибок при drain

Иногда drain завершится с ошибкой. Ниже — распространённые причины и способы обхода.

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

Сообщение вида “Cannot delete Pods not managed by ReplicationController, ReplicaSet, Job, or StatefulSet” означает, что на узле есть “голые” Pod’ы, созданные вручную, без контроллера. Kubernetes не может автоматически пересоздать их на других узлах.

Решения:

  • Вручную создать для этих Pod’ов контроллер уровня Deployment/ReplicaSet/StatefulSet.
  • Удалить или перенести Pod’ы вручную перед drain.
  • Форсировать удаление:
$ kubectl drain node-1 --force

Флаг –force удалит такие Pod’ы, но они станут недоступны, если их не будет кто-то восстанавливать.

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

DaemonSet запускает Pod на выбранных узлах независимо от их schedulable-статуса. При удалении Pod’а DaemonSet сразу создаст его снова, поэтому drain сигнализирует об ошибке и прерывается.

Решение: добавить флаг –ignore-daemonsets:

$ kubectl drain node-1 --ignore-daemonsets

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

Комбинирование флагов:

$ kubectl drain node-1 --force --ignore-daemonsets --grace-period=0

Это максимально агрессивный способ — используйте только в критичных случаях, например, при аварийном выводе узла.

Минимизация простоя с помощью Pod Disruption Budget

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

Pod Disruption Budget (PDB) позволяет задать минимальное число Pod’ов, которые должны быть доступны во время плановой или неплановой эвакуации. Kubernetes блокирует drain, если он приведёт к превышению допустимого уровня недоступности.

Пример PDB в YAML:

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

Эта политика требует как минимум четырёх доступных Pod’ов с меткой app=my-app. Альтернативно можно задать maxUnavailable:

  • minAvailable: 4 — требуется не менее 4 Pod’ов.
  • maxUnavailable: 50% — допускается потеря до 50% Pod’ов (в процентах от общего числа).

Только одно из полей minAvailable или maxUnavailable может присутствовать в одном объекте PDB.

Переопределение PDB в экстренных ситуациях

Если нужно срочно остановить узел, можно обойти эвакуацию через флаг –disable-eviction:

$ kubectl drain node-1 --disable-eviction

В этом режиме Pod’ы будут удалены напрямую, игнорируя PDB. Это рискованно и может привести к падению доступности.

Возвращение узлов в кластер

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

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

Kubernetes начнёт назначать новые Pod’ы на узел согласно политике планирования.

Контрольный список перед обслуживанием (оператор / SRE)

  • Проверить текущую нагрузку и запас ресурсов в кластере.
  • Убедиться, что целевые Pod’ы управляются контроллерами (Deployment/StatefulSet/ReplicaSet).
  • Проверить наличие PodDisruptionBudget для критичных приложений.
  • Очистить или переместить “голые” Pod’ы вручную.
  • Проверить, нет ли на узле важных DaemonSet-подов.
  • Сделать резервные копии данных для stateful-сервисов.
  • Согласовать окна обслуживания с владельцами сервисов.
  • Выполнить cordon, затем drain с необходимыми флагами.
  • После работ — uncordon и мониторинг состояния приложений.

Playbook: пошаговое действие для безопасного обслуживания

  1. Оценка:
    • Проверить доступность ресурсов: CPU, RAM, PV.
    • Проверить PDB и статусы Deployment/StatefulSet.
  2. Подготовка:
    • Сообщить заинтересованным лицам и установить окно обслуживания.
    • Создать резервные копии (если нужно).
  3. Вывод узла:
    • kubectl cordon node-1
    • kubectl drain node-1 (при необходимости добавить флаги)
  4. Поддержка:
    • Выполнить обслуживание хоста/апдейты/замену железа.
  5. Возврат:
    • Включить узел.
    • kubectl uncordon node-1
  6. Проверка:
    • kubectl get pods –all-namespaces — проверить рестарты, готовность.
    • Мониторинг метрик (латентность, ошибки).

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

Оператор:

  • Проверить логи kubelet и kube-proxy после uncordon.
  • Убедиться, что компоненты kube-system работают.

SRE:

  • Проверить SLA и отклонения после обслуживания.
  • Проанализировать трекинг инцидентов.

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

  • Убедиться, что readiness/liveness-пробы настроены корректно.
  • Проверить, что приложения корректно восстанавливаются после SIGTERM.

Модель принятия решения (диаграмма)

flowchart TD
  A[Нужно вывести узел?] -->|Да| B{Есть PDB для критичных приложений?}
  A -->|Нет| Z[Ничего не делать]
  B -->|Нет| C[Установить cordon и drain]
  B -->|Да| D{PDB блокирует drain?}
  D -->|Да| E[Отложить или уменьшить масштаб обслуживания]
  D -->|Нет| C
  C --> F{Есть 'голые' Pod'ы или DaemonSet?}
  F -->|Да| G[Исследовать: создать контроллер/удалить/использовать --ignore-daemonsets]
  F -->|Нет| H[Выполнить drain и обслуживание]
  H --> I[uncordon и верификация]
  G --> C

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

  • После uncordon все приложения в Ready-состоянии (подходящее значение зависит от приложения).
  • Нет длительных перезапусков контейнеров и ошибок readiness/liveness.
  • Производительность и латентность в пределах допустимых отклонений.
  • Логи kubelet и системных компонентов не содержат критических ошибок.

Тесты и критерии приёмки для автоматизации

  • Автотест: выполнить cordon и drain на тестовом узле, убедиться, что для каждого Deployment количество Pod’ов в Ready не упало ниже допустимого.
  • Проверка интеграции: симулировать задержку старта контейнера и убедиться, что PDB препятствует drain при необходимости.
  • Регрессион: убедиться, что –ignore-daemonsets не приводит к удалению системных компонентов.

Риски и меры снижения

  • Риск: потеря данных при форсированном удалении stateful-приложений.

    • Митигирование: выполнять snapshot PV, корректное завершение сервисов, использовать StatefulSet с корректными preStop hook.
  • Риск: одновременный drain нескольких узлов приведёт к нехватке ресурсов.

    • Митигирование: контролируемые окна обслуживания, PDB, последовательный drain узлов.
  • Риск: DaemonSet-поды критичных компонентов будут перезапущены на другом узле или останутся незапущенными.

    • Митигирование: убедиться, что DaemonSet предназначен для cluster-wide сервисов; проверить nodeSelectors и tolerations.

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

  1. Оценить влияние на доступность (PDB, реплики).
  2. Планировать последовательность вывода узлов с учётом capacity.
  3. Применять cordon → drain (доп. флаги при необходимости).
  4. Верифицировать работоспособность сервисов после возврата.

Краткий глоссарий (1 строка)

  • cordon — пометка узла как неподходящего для планировщика; не удаляет запущенные Pod’ы.
  • drain — процесс эвакуации Pod’ов с узла с попыткой их безопасного пересоздания.
  • PDB — Pod Disruption Budget, ограничивает количество одновременно недоступных Pod’ов.
  • DaemonSet — контроллер, который запускает Pod на каждом (или выбранных) узле.

Примеры ситуаций, когда простой drain не подойдёт

  • У вас stateful-приложение без корректных стейт-механизмов и без резервных копий — форсированный drain может привести к потере данных.
  • Кластер находится на пределе capacity — drain может привести к невозможности запустить Pod’ы на других узлах.

Практические советы

  • Настройте readiness и liveness пробы корректно — это уменьшит вероятность плохих рестартов при drain.
  • Планируйте обслуживание групп узлов последовательно, а не параллельно.
  • Автоматизируйте проверку PDB перед запуском автоматических drain-операций.

Итог

Cordon и drain — базовые, но мощные инструменты для безопасного обслуживания узлов Kubernetes. Cordons предотвращают назначение новых Pod’ов, а drain обеспечивают перенос рабочих нагрузок. Для поддержания доступности используйте Pod Disruption Budget и заранее планируйте окна обслуживания. В экстренных случаях доступны флаги, позволяющие форсировать удаление, но они увеличивают риск простоев и потерь данных. Следуйте чек-листам, проверяйте критичные компоненты и проводите валидацию после возврата узла в кластер.

Поделиться: 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 быстро