Ответ
Чтобы безопасно вывести ноду из эксплуатации для обслуживания или замены, я использую стандартную процедуру cordon и drain. Это гарантирует нулевое время простоя для приложений (если кластер имеет достаточную емкость).
Пошаговый процесс:
-
Помечаю ноду как неготовую к планированию:
kubectl cordon <node-name>Это предотвращает планирование новых Pods на эту ноду. Существующие Pods продолжают работать.
-
Эвакуирую Pods с ноды:
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data --grace-period=300--ignore-daemonsets— игнорирую Pods, управляемые DaemonSets (например, агенты мониторинга или сетевые плагины), так как они должны остаться на каждой ноде.--delete-emptydir-data— удаляю данные из томовemptyDir, которые привязаны к жизненному циклу Pod.--grace-period=300— даю Pods до 5 минут на корректное завершение работы, отправляя сигнал SIGTERM перед принудительным завершением (SIGKILL).
Что происходит под капотом: Контроллеры (например, Deployment) обнаруживают, что Pod был удален с ноды, и немедленно создают его новую реплику на другой, доступной ноде, согласно правилам распределения ресурсов и anti-affinity.
Важные проверки перед drain:
- Убеждаюсь, что в кластере достаточно свободных ресурсов (CPU, Memory) на других нодах для размещения эвакуируемых рабочих нагрузок.
- Для StatefulSets с привязкой к конкретным томам (Persistent Volumes) проверяю политику обновления и, при необходимости, координирую действия с командой, отвечающей за хранилище.