Как вывести узел Kubernetes из-под нагрузки для обслуживания?

«Как вывести узел Kubernetes из-под нагрузки для обслуживания?» — вопрос из категории Kubernetes, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Безопасный вывод узла (Node) — это многоэтапный процесс, цель которого — обеспечить нулевой или минимальный downtime для приложений. Я действую по следующему алгоритму:

1. Пометить узел как неготовый к планированию (cordon). Это предотвращает размещение на нём новых подов.

kubectl cordon node-01

2. Аккуратно эвакуировать существующие поды (drain). Ключевая команда. Она gracefully завершает поды на узле и пересоздаёт их на других узлах (в соответствии с политиками Deployments/StatefulSets).

kubectl drain node-01 
  --ignore-daemonsets 
  --delete-emptydir-data 
  --timeout=300s
  • --ignore-daemonsets: Обязательный флаг, так как DaemonSet-поды (например, для логирования или сети) нельзя эвакуировать.
  • --delete-emptydir-data: Удаляет данные из томов типа emptyDir.
  • --timeout: Устанавливает лимит времени на graceful termination каждого пода.

3. Проверить PodDisruptionBudget (PDB). Перед drain я всегда проверяю, не нарушит ли эвакуация политики доступности приложений.

kubectl get poddisruptionbudgets --all-namespaces

Если PDB жёсткий (например, minAvailable: 2 при двух репликах), drain может зависнуть. В этом случае нужно координировать действия с разработчиками.

4. Выполнить обслуживание узла (обновление ОС, изменение конфигурации, апгрейд hardware).

5. Вернуть узел в строй (uncordon).

kubectl uncordon node-01

После этого планировщик снова сможет размещать на нём поды.

Важный нюанс для StatefulSet: Для StatefulSet с привязанными томами (PVC) простой drain не сработает. Необходимо вручную удалить каждый pod (с флагом --cascade=orphan), чтобы StatefulSet пересоздал его на другом узле, при этом том должен поддерживать режим ReadWriteMany или быть мигрирован с помощью специфичных для CSI-драйвера инструментов.