
Статья подготовлена совместно с экспертом
Станислав Погоржельский, технологический евангелист VK Cloud&Data

Ночью кластер может держать десяток узлов под нагрузку, которой уже нет: поды простаивают, а счёт продолжает идти за заказанные ресурсы. Днём нагрузка растёт, планировщик не находит места, поды остаются в Pending, и дежурному приходится вручную добавлять узлы, пока очередь не разгребётся.
В обоих случаях проблема одна: размер группы узлов задан вручную и не связан с потребностями приложений. В простое платят за незанятые ядра, на пике — за срочные операции и нарушение обещанного времени отклика.
Автомасштабирование Kubernetes работает на трёх уровнях. За масштабирование узлов отвечает Cluster Autoscaler. В Managed Kubernetes от VK Cloud он предустановлен во всех кластерах, но по умолчанию выключен. Разберём, когда он добавляет узлы, почему пустой узел остаётся в кластере ещё пять минут, чем он отличается от HPA и VPA и почему группа может не вырасти.

Станислав Погоржельский, технологический евангелист VK Cloud&Data
Cluster Autoscaler не ориентируется на фактическую загрузку CPU. Он реагирует на неразмещаемые поды: планировщик не нашёл для них места, а добавление нового узла в одну из групп может решить проблему. Автоскейлер проверяет такие поды каждые 10 секунд. Этот интервал задаёт параметр --scan-interval.
Решение о росте принимается по requests, а не по фактическому потреблению ресурсов. Автоскейлеру важно, достаточно ли на новом узле ресурсов, которые запросили поды. Если поду нужны 100m CPU и 64 МБ памяти, планировщик ищет узел, где осталось не меньше 100m CPU и 64 МБ RAM.
Под без requests для автоскейлера почти не имеет веса. Он не создаёт повода увеличить группу и не мешает считать узел недозагруженным.
По этой же причине Cluster Autoscaler не масштабирует кластер просто по текущей загрузке CPU. Новый узел может появиться без подов, а существующий узел с системными компонентами, наоборот, может оказаться кандидатом на удаление.
Автомасштабирование включается вручную для каждой группы worker-узлов.
До включения проверьте квоты проекта. Если закончились квоты на вычислительные ресурсы, группа не сможет вырасти.
Для worker-группы можно задать от 1 до 500 узлов. Минимум ограничивает сжатие: автоскейлер не удалит узлы ниже этого значения. Максимум ограничивает рост.
После включения автомасштабирования вручную менять число узлов нельзя. Чтобы снова управлять размером группы вручную, автоматическое масштабирование нужно отключить.
Сжатие запускается, когда нагрузка снизилась и все поды можно разместить на меньшем числе узлов.
Автоскейлер работает в три шага:
В Managed Kubernetes от VK Cloud узел должен оставаться пустым пять минут. За это время на нём не должен появиться ни один новый под. Такая задержка защищает от лишних операций, когда кратковременный спад нагрузки быстро сменяется новым пиком.
Пять минут — настройка сервиса VK Cloud. В upstream Cluster Autoscaler 1.36 значение параметра --scale-down-unneeded-time по умолчанию составляет 10 минут, поэтому расчёты по стандартным таймингам Kubernetes нельзя переносить на сервис напрямую.
Статус узла можно проверить через kubectl describe node. Перед выселением подов автоскейлер устанавливает ToBeDeletedByClusterAutoscaler с эффектом NoSchedule. Узел-кандидат заранее получает более мягкое ограничение DeletionCandidateOfClusterAutoscaler с эффектом PreferNoSchedule.
В upstream Cluster Autoscaler подам по умолчанию даётся до 10 минут на корректное завершение. Непустые узлы удаляются по одному.

Cluster Autoscaler уже предустановлен в кластере — задайте минимум и максимум в настройках группы за пару кликов.
VK Cloud указывает экономию на вычислительных мощностях до 60%. Но минимальный размер worker-группы нельзя установить равным нулю: допустимый диапазон начинается с одного узла.
Минимум стоит выбирать не по принципу «как можно меньше», а по количеству реплик, которые приложение должно пережить. Один узел не даёт отказоустойчивости, два и более — дают.
Если дополнительные ресурсы могут понадобиться сразу, используют два подхода.
Можно создать PriorityClass со значением value: -10 и Deployment для overprovisioning. Такой Deployment держит пустые поды с requests, сопоставимыми с размером узла.
Когда появляется реальная нагрузка, она вытесняет поды-заглушки. Они становятся неразмещаемыми, и автоскейлер заранее добавляет новый узел.
Значение -10 совпадает со стандартным порогом --expendable-pods-priority-cutoff в upstream Cluster Autoscaler. Под-заглушка не запускает рост сама по себе и не мешает сжатию группы.
Экспандер priority задаёт порядок, в котором Cluster Autoscaler выбирает группы для роста.
Часть параметров Cluster Autoscaler в Managed Kubernetes управляется платформой. Перед настройкой стоит проверить, доступен ли Deployment автоскейлера и разрешено ли менять его аргументы. Для изменения --expander может понадобиться согласование с технической поддержкой.
Три уровня автомасштабирования решают разные задачи, но опираются на requests.
HPA рассчитывает утилизацию как процент от запроса ресурса. Cluster Autoscaler также ориентируется на запросы подов, когда решает, добавлять или удалять узлы.
Ошибка в requests одновременно ломает оба контура. Заниженные значения не создадут повода для роста группы, а завышенные не позволят убрать недозагруженные узлы.
| Уровень | Что меняет | Чем настраивается | Статус в Managed Kubernetes от VK Cloud |
| HPA | Число реплик Deployment или StatefulSet | Манифест HorizontalPodAutoscaler, API autoscaling/v2 | Руководство относится к кластерам второго поколения. Metrics Server предустановлен платформой |
| VPA | requests и limits контейнеров | Объект VerticalPodAutoscaler | По документации доступен только для кластеров первого поколения |
| Cluster Autoscaler | Число узлов в группе | Настройки группы узлов в личном кабинете | Предустановлен во всех кластерах, включается вручную для каждой группы |
Ограничение VPA важно учитывать при планировании. Связка HPA, VPA и Cluster Autoscaler доступна не во всех кластерах.
Upstream-документация также не рекомендует одновременно использовать HPA и VPA для одной и той же метрики — CPU или памяти. Их можно совместить, если они масштабируются по разным метрикам.
При изменении ресурсов VPA пересоздаёт под, поэтому он может оказаться на другом узле.
Если под остаётся в Pending, а автомасштабирование не срабатывает, причина обычно относится к одному из пяти сценариев.
Логи автоскейлера находятся в поде с именем, начинающимся на cluster-autoscaler, в пространстве имён kube-system:
kubectl logs -f <ИМЯ_ПОДА> -n kube-system
Это первая причина, которую указывает документация VK Cloud. Автоскейлер рассчитывает рост по resources.requests, поэтому под без запросов не создаёт давления на группу.
Добавьте requests всем контейнерам рабочей нагрузки. Увеличение максимального размера группы само по себе проблему не исправит.
Группа уже содержит максимально разрешённое число узлов. В личном кабинете сравните поля «Максимальное количество узлов» и «Количество узлов».
В логах ищите сообщение:
max size reached
В Cluster Autoscaler 1.36.1 событие на поде выглядит так:
pod didn't trigger scale-up: 1 max node group size reached
Чтобы группа могла вырасти, увеличьте максимум в настройках масштабирования.
У пода могут быть требования, которым не соответствует ни существующий, ни потенциальный новый узел. Обычно это nodeSelector, nodeAffinity или отсутствие подходящей toleration.
В логах автоскейлера появляется predicate failed. В выводе kubectl describe pod — сообщения вроде:
node(s) had untolerated taint {ключ: значение}
или:
node(s) didn't match Pod's node affinity/selector
Проверьте, что nodeSelector и tolerations пода совпадают с метками и ограничениями подходящей группы. Если нет, скорректируйте правила размещения или создайте отдельную группу узлов.
В проекте могут закончиться квоты на vCPU, RAM или виртуальные машины. В логах такой отказ обычно отмечается как:
quota exceeded
В upstream-коде встречается сообщение:
exceeded quota: …
Освободите ресурсы или увеличьте квоты. Поэтому их и нужно проверять ещё до включения автомасштабирования.
Cluster Autoscaler не отвечает за скорость создания виртуальной машины. Время провижининга в основном зависит от облачного провайдера.
Вupstream Cluster Autoscaler новый узел ожидается до 15 минут — это значение --max-node-provision-time. После этого автоскейлер перестаёт учитывать его в симуляции и может попытаться использовать другую группу.
Если эти причины не подходят, проверьте ещё два сценария:
Недозагруженный узел может остаться в кластере по нескольким причинам.
kubectl describe node <ИМЯ> | grep scale-down-disabled
scale-down: node <ИМЯ> is not marked as unneeded for deletion
Upstream Cluster Autoscaler также не удаляет узлы с подами, использующими локальное хранилище: hostPath и emptyDir без medium: Memory. Удаление может блокировать и аннотация:
cluster-autoscaler.kubernetes.io/safe-to-evict: "false"
Для точечного исключения локальных томов используют аннотацию:
cluster-autoscaler.kubernetes.io/safe-to-evict-local-volumes
В её значении перечисляют все локальные тома пода, которые допустимо учитывать при выселении.
Cluster Autoscaler добавляет узел в конкретную группу, поэтому правила размещения нагрузки нужно настроить заранее.
Taints действуют на уровне worker-узлов и запрещают планировщику размещать на них поды. Tolerations позволяют отдельным подам запускаться на узлах с такими ограничениями.
Для адресации нагрузки используют:
В личном кабинете параметры группы находятся в разделе «Labels и Taints».
Типичный пример — группа с GPU. Чтобы дорогие узлы не занимали обычные процессы, на группу можно установить taint. Тогда запускать на ней поды смогут только workload с подходящей toleration.
Шаблоны конфигурации с GPU доступны только для worker-узлов и подключаются по заявке на сервис Cloud GPU.
При работе с метками и ограничениями важно учитывать два ограничения:
Cluster Autoscaler в Managed Kubernetes от VK Cloud поддерживает число worker-узлов в пределах, заданных для группы. Он добавляет узлы, когда в кластере появляются неразмещаемые поды, и удаляет их при устойчивом снижении нагрузки.
Он не заменяет планирование ёмкости и не ускоряет создание виртуальных машин. При росте узким местом обычно становится время провижининга в облаке, а не работа автоскейлера.
Перед включением автомасштабирования нужно:
Диагностику начинайте с логов автоскейлера и сравнения полей «Максимальное количество узлов» и «Количество узлов» в личном кабинете.
Порядок настройки автомасштабирования групп, ограничения и причины отказов описаны в документации Managed Kubernetes.
Cluster Autoscaler предустановлен во всех Kubernetes-кластерах, но включается вручную для каждой группы worker-узлов. Это позволяет владельцу кластера самостоятельно определить минимум и максимум группы, от которых напрямую зависят расходы на инфраструктуру.
VK Cloud указывает среди причин, блокирующих удаление, PodDisruptionBudget и поды без контроллера, но отдельно не описывает локальное хранилище.
В upstream Cluster Autoscaler узлы с подами, использующими hostPath или emptyDir без medium: Memory, по умолчанию не удаляются.
Надёжная защита не должна зависеть только от типа тома. Для базы данных лучше выделить отдельную группу узлов с минимумом, рассчитанным по числу необходимых реплик, и настроить PodDisruptionBudget, который не позволит вытеснить кворум.
Да, но не силами Cluster Autoscaler. Вертикальное автомасштабирование master-узлов работает для всех кластеров и не отключается. Cluster Autoscaler управляет только группами worker-узлов. Уменьшить шаблон master-узла можно только вручную.
Наши специалисты свяжутся с вами в ближайшее время и ответят на все вопросы.

Будем держать в курсе новостей и облачных трендов




