Ответ
Безопасный вывод узла (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-драйвера инструментов.