Содержание
  1. Что такое автомасштабирование и два его направления
  2. Цикл решения: сигнал, сравнение, расчёт, границы, действие
  3. Учебная таблица решений: вход, расчёт, граница, число
  4. Округление вверх и соблюдение min/max
  5. Что меняет реальное применение расчёта
  6. Требования к политике перед включением
  7. Очередь и latency как альтернативный сигнал
  8. Частые вопросы
Гайды

Автоматическое масштабирование: как выбрать размер

5 ноября 2026 · 11 минут чтения

Автоматическое масштабирование: как выбрать размер — это перевод измеренной нагрузки в целевое число реплик по формуле desired = ceil(currentReplicas × currentMetricValue / desiredMetricValue), после чего результат удерживается в границах min и max. Ниже — учебная шкала решений на пяти строках, проверка округления вверх и соблюдения границ, а также условия, которые меняют применение расчёта в живом кластере.

Что такое автомасштабирование и два его направления

В документации Kubernetes автоматическое масштабирование описано так: HorizontalPodAutoscaler обновляет ресурс рабочей нагрузки, например Deployment или StatefulSet, чтобы ёмкость соответствовала спросу. Горизонтальное масштабирование означает, что на рост нагрузки отвечают развёртыванием большего числа Pod. Вертикальное масштабирование в Kubernetes означает выделение большего объёма ресурсов, например памяти или CPU, уже работающим Pod.

Различие важно для выбора размера. Горизонтальный путь меняет число экземпляров: было четыре реплики, стало шесть. Вертикальный путь меняет ёмкость одной единицы: тот же Pod получает больше CPU или памяти. Microsoft в обзоре Azure Monitor пишет, что автомасштабирование работает по горизонтали и не поддерживает вертикальное масштабирование, а вертикальный путь ограничен доступностью более крупного оборудования и может требовать перезапуска виртуальной машины.

Google в руководстве по Compute Engine описывает автомасштабирование как добавление и удаление виртуальных машин в управляемой группе экземпляров по мере изменения нагрузки. Горизонтальное масштабирование дополняет вертикальное: часть задач решается только увеличением ёмкости отдельного экземпляра.

Для выбора размера это даёт первую развилку. Если приложение легко делится на независимые экземпляры, работает горизонтальный путь с числом реплик. Если экземпляр нельзя размножить, остаётся вертикальный путь с более крупной машиной.

Цикл решения: сигнал, сравнение, расчёт, границы, действие

Цикл решения состоит из пяти шагов. Сигнал — измеренное значение метрики. Сравнение с целью — отношение текущего значения к желаемому. Расчёт — формула, дающая сырое число реплик. Границы — приведение результата к диапазону min и max. Действие — изменение числа реплик у целевого ресурса.

В документации Kubernetes контроллер HPA работает как цикл управления, который запускается периодически. Интервал задаётся параметром --horizontal-pod-autoscaler-sync-period у kube-controller-manager, значение по умолчанию — 15 секунд. За каждый период контроллер запрашивает утилизацию ресурса по метрикам, указанным в описании HorizontalPodAutoscaler, находит целевой ресурс через scaleTargetRef, выбирает Pod по меткам .spec.selector и получает метрики из resource metrics API либо custom metrics API.

Для метрик на Pod, например CPU, контроллер берёт метрики из resource metrics API по каждому Pod. Если задано целевое значение утилизации, контроллер считает утилизацию как процент от эквивалентного resource request на контейнерах каждого Pod. Затем берётся среднее по всем целевым Pod и получается отношение, используемое для расчёта желаемого числа реплик.

Google описывает тот же цикл для групп экземпляров: автомасштабирование постоянно собирает данные об использовании по выбранной метрике, сравнивает фактическую утилизацию с целевой и решает, удалять или добавлять экземпляры. При нескольких сигналах в политике автомасштабирование считает рекомендованное число машин по каждому сигналу и берёт наибольшее.

Microsoft описывает правила иначе: автомасштабирование масштабирует наружу, если выполнено любое из правил, и внутрь — только если выполнены все правила. В терминах логических операторов для масштабирования наружу применяется OR, для масштабирования внутрь — AND.

Учебная таблица решений: вход, расчёт, граница, число

Ниже — учебный пример с условными значениями. Политика: четыре готовые реплики, средняя утилизация CPU от request, цель 60%, min=2, max=8, метрики полные, стабилизация и tolerance не учитываются. Формула: desired = ceil(currentReplicas × currentMetricValue / desiredMetricValue).

Вход: реплики, утилизация Сырой расчёт Граница Ожидаемое число
4, 90% ceil(4×90/60) = ceil(6.0) = 6 в диапазоне 2..8 6
4, 30% ceil(4×30/60) = ceil(2.0) = 2 на нижней границе 2
4, 180% ceil(4×180/60) = ceil(12.0) = 12 выше max 8
4, 55% ceil(4×55/60) = ceil(3.67) = 4 в диапазоне 2..8 4
4, 0% ceil(0) = 0 ниже min 2

Строка 1 даёт шесть реплик: рост утилизации до 90% при цели 60% требует полуторного увеличения числа реплик. Строка 2 даёт две реплики: падение до 30% вдвое сокращает число реплик, и результат попадает точно на нижнюю границу. Строка 3 показывает работу верхней границы: сырой расчёт даёт 12, применяется 8. Строка 5 показывает работу нижней границы: сырой расчёт даёт 0, применяется 2.

Таблица служит эталоном для проверки. Строки 1, 2, 3 и 5 должны совпасть с расчётом и границами. Строка 4 даёт 4 исключительно из-за округления вверх, без применения tolerance.

Округление вверх и соблюдение min/max

Две приёмки проверяют учебный результат. Первая: нецелый результат округляется вверх. Строка 4 даёт 3.67, после округления — 4. Вторая: границы соблюдаются. Строка 3 даёт сырые 12, применяется max=8; строка 5 даёт 0, применяется min=2.

Округление вверх встроено в формулу: в документации Kubernetes желаемое число реплик вычисляется как ceil от произведения текущего числа реплик на отношение текущего значения метрики к желаемому. Пример из той же документации: при текущем значении 200m и желаемом 100m число реплик удваивается, поскольку отношение равно 2.0; при текущем 50m число реплик уменьшается вдвое, поскольку отношение равно 0.5.

Округление вверх объясняет поведение строки 4. Отношение 55/60 равно примерно 0.917, произведение на четыре реплики даёт 3.67. Округление вверх превращает это в 4, и число реплик не меняется. При ошибочном отбрасывании дробной части получилось бы 3, то есть сокращение на одну реплику.

Границы min и max применяются после расчёта. В документации Kubernetes указано, что если нагрузка снижается, а число Pod выше заданного минимума, HorizontalPodAutoscaler даёт команду масштабировать вниз. Верхняя граница задаётся в описании политики. В примере команды kubectl autoscale rs foo --min=2 --max=5 --cpu=80% создаётся автомасштабирование для ReplicaSet foo с целевой утилизацией CPU 80% и числом реплик от 2 до 5.

Практический вывод: проверяйте политику на строках, где сырой расчёт выходит за границы, и на строках с нецелым результатом. Эти два случая дают наибольшее расхождение между сырой арифметикой и применяемым числом.

Что меняет реальное применение расчёта

Учебная арифметика описывает идеализированный случай. В живом кластере Kubernetes на применение расчёта влияют готовность Pod, неполные метрики, стабилизация и tolerance.

Готовность Pod. В документации Kubernetes указано, что перед проверкой tolerance и определением итоговых значений контроллер учитывает, есть ли отсутствующие метрики и сколько Pod находятся в состоянии Ready. Для метрик на Pod все Pod с меткой удаления игнорируются, а все отказавшие Pod отбрасываются. Если Pod ещё не стал готовым или последняя точка метрики была до того, как он стал готовым, этот Pod откладывается. Для CPU-метрик контроллер не может точно определить первый момент готовности Pod и считает Pod «ещё не готовым», если он не готов и перешёл в готовность в пределах настраиваемого окна с момента запуска. Это окно задаётся параметром --horizontal-pod-autoscaler-initial-readiness-delay, значение по умолчанию — 30 секунд.

Неполные метрики. Если метрики отсутствуют, контроллер пересчитывает среднее консервативнее, предполагая, что такие Pod потребляли 100% желаемого значения при масштабировании вниз и 0% при масштабировании вверх. Это уменьшает величину возможного изменения. Если присутствовали неготовые Pod и нагрузка масштабировалась бы вверх без их учёта, контроллер консервативно предполагает, что неготовые Pod потребляют 0% желаемой метрики, дополнительно уменьшая величину масштабирования вверх.

Стабилизация. В документации Kubernetes указано, что прямо перед масштабированием рекомендация записывается, и контроллер рассматривает все рекомендации в настраиваемом окне, выбирая наибольшую. Значение задаётся параметром --horizontal-pod-autoscaler-downscale-stabilization, по умолчанию — 5 минут. Это означает, что масштабирование вниз происходит постепенно, сглаживая влияние быстро колеблющихся метрик. Google описывает аналогичный период стабилизации: по умолчанию 10 минут, настраивается от 0 секунд до 3600 секунд, применяется только для решений о масштабировании вниз.

Tolerance. В документации Kubernetes указано, что поле tolerance задаёт порог для колебаний метрики, ниже которого автомасштабирование не срабатывает. Если поле не задано, применяется общее для кластера значение tolerance по умолчанию — 10%. Значение по умолчанию можно изменить для масштабирования вверх и вниз аргументом --horizontal-pod-autoscaler-tolerance у kube-controller-manager. Пример из документации: при цели потребления памяти 100MiB и tolerance масштабирования вверх 5% алгоритм рассмотрит масштабирование вверх только при потреблении выше 105MiB.

Эти четыре фактора отделяют идеализированную арифметику от поведения живого кластера. Учебная таблица показывает механику формулы и границ.

Требования к политике перед включением

Перед включением политики проверьте четыре условия.

CPU requests. В документации Kubernetes указано, что при определении спецификации Pod следует задавать resource requests, например cpu и memory. Это значение используется для определения утилизации ресурса и применяется контроллером HPA для масштабирования. Если у части контейнеров Pod не задан соответствующий resource request, утилизация CPU для этого Pod не определена, и автомасштабирование не предпримет действий по этой метрике.

Лимиты ёмкости. Задайте min и max в политике. Google указывает, что стоимость ресурсов можно контролировать, настраивая минимальное и максимальное число экземпляров в политике автомасштабирования. Microsoft описывает ограничения экземпляров как часть профиля: каждый профиль задаёт минимальное и максимальное число экземпляров, а также число по умолчанию.

Стоимостный предел. Верхняя граница напрямую ограничивает расход. Google пишет, что автомасштабирование динамически добавляет и удаляет виртуальные машины, поэтому оплата идёт за используемые ресурсы группы. Microsoft указывает, что при низкой нагрузке автомасштабирование сокращает число ресурсов, что снижает затраты.

Наблюдение после действия. После включения политики следите за числом реплик и метрикой, по которой идёт масштабирование. В документации Kubernetes описан эффект thrashing, или flapping: число реплик может часто колебаться из-за динамической природы оцениваемых метрик. Для сглаживания применяются окно стабилизации и tolerance.

Дополнительно проверьте, что целевой ресурс поддерживает масштабирование. В документации Kubernetes указано, что горизонтальное автомасштабирование не применяется к объектам, которые нельзя масштабировать, например к DaemonSet. Google указывает, что автомасштабирование нельзя использовать с неуправляемыми группами экземпляров и с группами, у которых отключено восстановление виртуальных машин.

Очередь и latency как альтернативный сигнал

CPU — не единственный сигнал для выбора размера. Microsoft в обзоре Azure Monitor перечисляет метрики, по которым настраивается автомасштабирование: загрузка CPU, длина очереди, доступная память, а также расписание. В примере оттуда: масштабировать наружу, добавляя виртуальные машины, когда средняя загрузка CPU на машину выше 70%, и сокращать, когда загрузка падает до 40%.

Google перечисляет сигналы для групп экземпляров: средняя утилизация CPU, пропускная способность балансировки HTTP-нагрузки и метрики Cloud Monitoring. Политика должна содержать хотя бы один сигнал масштабирования; при включении автомасштабирования в группе по умолчанию добавляется сигнал утилизации CPU.

В документации Kubernetes указано, что контроллер периодически корректирует желаемый масштаб целевого ресурса по наблюдаемым метрикам, таким как средняя утилизация CPU, средняя утилизация памяти или любая другая заданная пользовательская метрика. Для пользовательских метрик на Pod контроллер работает так же, как с ресурсными метриками, но использует сырые значения. Для объектных и внешних метрик извлекается одна метрика, описывающая объект, и сравнивается с целевым значением.

Очередь или latency могут быть более подходящим сигналом, чем CPU. Если приложение ждёт внешний сервис, загрузка CPU остаётся низкой при растущей задержке ответа. Сигнал по длине очереди или по latency отражает эту ситуацию напрямую. При нескольких метриках в описании HorizontalPodAutoscaler расчёт выполняется по каждой метрике, а затем выбирается наибольшее из желаемых чисел реплик. Если какую-то метрику нельзя преобразовать в желаемое число реплик и при этом другие метрики предлагают масштабирование вниз, масштабирование пропускается; масштабирование вверх остаётся возможным, если хотя бы одна метрика даёт желаемое число реплик больше текущего.

Частые вопросы

Как выбрать между горизонтальным и вертикальным масштабированием?

Горизонтальное масштабирование меняет число экземпляров, вертикальное — ёмкость одного экземпляра. В документации Kubernetes горизонтальное масштабирование описано как развёртывание большего числа Pod, вертикальное — как выделение большего объёма ресурсов уже работающим Pod. Microsoft указывает, что автомасштабирование Azure Monitor работает по горизонтали и не поддерживает вертикальное масштабирование. Горизонтальный путь подходит, когда приложение делится на независимые экземпляры.

Как считается желаемое число реплик?

Формула: desired = ceil(currentReplicas × currentMetricValue / desiredMetricValue). В документации Kubernetes желаемое число реплик вычисляется как ceil от произведения текущего числа реплик на отношение текущего значения метрики к желаемому. При текущем значении 200m и желаемом 100m число реплик удваивается. Результат затем удерживается в границах min и max.

Почему при утилизации 55% и цели 60% число реплик не меняется?

Отношение 55/60 равно примерно 0.917, произведение на четыре реплики даёт 3.67. Округление вверх превращает результат в 4, и число реплик остаётся прежним. В учебном расчёте tolerance не применяется, поэтому результат определяется именно округлением вверх. При ошибочном отбрасывании дробной части получилось бы 3.

Что происходит, если сырой расчёт выходит за границы min и max?

Применяется ближайшая граница. В учебной таблице строка с утилизацией 180% даёт сырые 12 реплик, но применяется max=8. Строка с утилизацией 0% даёт сырые 0 реплик, но применяется min=2. Границы задаются в политике, например в команде kubectl autoscale rs foo --min=2 --max=5 --cpu=80%.

Какие метрики подходят для масштабирования кроме CPU?

Утилизация памяти, длина очереди, пропускная способность балансировки, пользовательские и внешние метрики. Microsoft перечисляет загрузку CPU, длину очереди и доступную память. Google указывает среднюю утилизацию CPU, пропускную способность балансировки HTTP-нагрузки и метрики Cloud Monitoring. В документации Kubernetes упомянуты средняя утилизация CPU, средняя утилизация памяти и пользовательские метрики. При нескольких метриках выбирается наибольшее желаемое число реплик.

Читайте также

3 материала