Москва: проверенные б/у ноутбуки с гарантией и проверкой перед оплатой
+7 906 722-94-45

Главная → Статьи → Cluster Autoscaler: масштабирование узлов кластера

Cluster Autoscaler: как Kubernetes добавляет и убирает узлы

Cluster Autoscaler: масштабирование по pending-подам, условия и задержки scale down, PodDisruptionBudget, аннотации и связка с HPA.

Прямой ответ

Cluster Autoscaler (CA) меняет число узлов кластера. В отличие от HPA, который управляет числом подов, CA управляет ёмкостью, на которой эти поды размещаются. Работает он в связке с планировщиком.

Масштабирование вверх. CA периодически проверяет наличие подов в состоянии Pending, которые не разместились из-за нехватки ресурсов. Если такие поды есть, CA выбирает группу узлов и увеличивает её размер. Новый узел регистрируется, и планировщик размещает ожидающие поды.

Масштабирование вниз. Узел считается кандидатом на удаление, если его загрузка ниже порога (по умолчанию 50 % от allocatable) и он остаётся в таком состоянии заданное время (по умолчанию 10 минут). Перед удалением CA вытесняет поды с узла, соблюдая PodDisruptionBudget.

Узел не будет удалён, если на нём выполняется хотя бы одно из условий:

Блокирующее условие Причина
Под с PodDisruptionBudget, который будет нарушен Защита от добровольных прерываний
Под kube-system без PDB Защита системных компонентов
Под с локальным хранилищем (emptyDir) Потеря данных
Под, который не может быть перемещён Отсутствие подходящего узла
Аннотация cluster-autoscaler.kubernetes.io/scale-down-disabled: "true" Явный запрет

Задержки защищают от колебаний: после добавления узла CA не удаляет узлы заданное время, после удаления — тоже. Без них кластер входил бы в цикл «добавили узел, нагрузка распределилась, узел стал пустым, удалили».

# запрет удаления конкретного узла
metadata:
  annotations:
    cluster-autoscaler.kubernetes.io/scale-down-disabled: "true"

Практика: настройка и эксплуатация

1. Связка HPA + CA. HPA поднимает число реплик по загрузке, новые поды попадают в Pending, CA добавляет узлы. Задержка полного цикла — от нескольких десятков секунд до нескольких минут, в зависимости от времени запуска узла в облаке. Планировать ёмкость нужно с учётом этой задержки — см. статью про capacity planning.

2. CA опирается на requests. Под без requests считается не требующим ресурсов и не провоцирует добавление узла. Заниженные requests приводят к размещению на узле, где фактически ресурсов нет, — см. статью про requests и limits.

3. Задавайте PodDisruptionBudget. Без PDB вытеснение при удалении узла может остановить все реплики сервиса одновременно. Это самый частый источник проблем при включённом CA.

4. Системные поды мешают scale down. Поды в kube-system без PDB делают узел неудаляемым. Либо задайте им PDB, либо размещайте на выделенной группе узлов, не участвующей в автомасштабировании.

5. Используйте несколько групп узлов. Разделение по типу нагрузки (рабочие поды, пакетные задачи, GPU) позволяет масштабировать каждую группу независимо и выбирать разные типы машин.

6. Следите за фрагментацией. Несколько частично заполненных узлов не удаляются, если на каждом остаётся под. Задержка scale down и правильный размер узла снижают расход.

7. Проверяйте поведение при исчерпании квоты облака. CA не может добавить узлы, если достигнут лимит виртуальных машин в регионе; событие об этом видно в логах CA, но не в статусе подов.

Рекомендации:

  1. Начните с ограниченного диапазона. Минимум один-два узла, максимум — исходя из бюджета. Без верхней границы ошибка в HPA приводит к неконтролируемому росту счёта.
  2. Разделяйте группы по критичности. Рабочие нагрузки и разовые задачи на одних узлах мешают друг другу: всплеск пакетных задач вытесняет рабочие поды.
  3. Мониторьте число pending-подов. Это опережающий индикатор: если поды ждут размещения дольше пары минут, CA не справляется либо упирается в лимит.
  4. Тестируйте вытеснение. Проверка, что сервис переживает удаление узла, важнее настройки самого автоскейлера.
  5. Согласуйте с бюджетом. Автомасштабирование без алерта на число узлов превращает ошибку конфигурации в счёт на крупную сумму.

Практический сценарий: узлы добавлялись, но не удалялись

Контекст: кластер в облаке вырос с 6 до 14 узлов за сутки и держался на этом уровне неделю, хотя нагрузка вернулась к обычной.

  1. Диагностика. kubectl get nodes показал 14 узлов, из них 8 с загрузкой ниже 20 %. Логи CA содержали сообщение о невозможности вытеснения подов.
  2. Проверка подов. На «пустых» узлах находились поды kube-system без PDB: сборщики метрик и агент логирования, развёрнутые как DaemonSet без исключений, и несколько подов мониторинга.
  3. Дополнительная причина. Часть рабочих подов использовала emptyDir для кэша, что делает узел неудаляемым по правилам CA.
  4. Действия. (а) Для подов kube-system задали PodDisruptionBudget, позволяющий вытеснение; (б) агенты мониторинга перевели в тип, допускающий перезапуск, и убрали блокирующее локальное хранилище там, где оно не было нужно; (в) для сервисов с emptyDir оценили необходимость кэша и заменили его внешним хранилищем у двух из трёх; (г) для оставшегося сервиса закрепили выделенную группу узлов, исключённую из scale down; (д) добавили метрику на число узлов и алерт на отклонение от ожидаемого диапазона.
  5. Результат. Через два часа CA сократил кластер до 6 узлов; недельный перерасход прекратился, а алерт на число узлов выявил бы подобную ситуацию в первые часы.

Вывод: масштабирование вниз блокируется конкретными подами, а не настройками CA. Проверка PodDisruptionBudget и локального хранилища важнее подбора порогов: без неё узлы остаются навсегда, а расход растёт незаметно.

FAQ

Чем Cluster Autoscaler отличается от HPA? HPA меняет число реплик внутри доступной ёмкости, CA меняет саму ёмкость. Они дополняют друг друга: без CA рост реплик упирается в пределы кластера.

Как быстро CA реагирует на всплеск? Проверка выполняется периодически, обычно каждые 10 секунд, плюс время запуска узла в облаке — от десятков секунд до нескольких минут. Для резких всплесков нужен запас ёмкости.

Что происходит с подами при удалении узла? CA вытесняет их с соблюдением PodDisruptionBudget; поды пересоздаются на других узлах. Если PDB запрещает вытеснение, узел не удаляется.

Можно ли использовать CA с локальным хранилищем? Можно, но поды с локальным хранилищем делают узел неудаляемым. Для таких нагрузок нужна выделенная группа узлов без автомасштабирования вниз.

Источники: Kubernetes docs (autoscaling, disruptions), Cluster Autoscaler FAQ — ссылки в шапке.