Proactive Autoscaling — автоскейлер на p95

Проактивный скейлинг на основе p95 перцентиля утилизации. Ноды поднимаются до пика, а не после. Дополняет (не заменяет) стандартный Cluster Autoscaler и умеет безопасно возвращать временную burst-capacity после спада нагрузки.

Обзор

Стандартный Cluster Autoscaler реагирует на pending pods — ноды поднимаются только когда поды уже не помещаются. Proactive Autoscaling анализирует тренды утилизации и добавляет ноды заранее, предотвращая деградацию сервиса.

Слой 1 — Проактивный Scale Up

Два триггера, любой из которых вызывает scale up:

Триггер 1: Тренд

p95(30 мин) > p95(24 ч) + 10 п.п.

Ловит как резкие скачки нагрузки (~2 минуты реакция), так и плавный рост утилизации. Сравнение коротких и длинных окон позволяет отличить реальный тренд от шума.

Триггер 2: Страховка

p95(30 мин) > 85%

Для стабильно высокой нагрузки, когда тренд не показывает роста (нагрузка уже была высокой и остаётся высокой). Абсолютный порог безопасности.

Почему p95, а не avg?

Из 30 точек за 30 минут p95 = 29-я по возрастанию. Если 28 точек по 70% и 2 точки по 90% — p95 = 90%, триггер срабатывает за 2 минуты.

Среднее (avg) смешивает спайки с нормой: те же данные дадут avg = 71%, что ниже порога. P95 отделяет реальный рост от шума.

Слой 2 — Стратегический Scale Down

Условие

p95(14 дней) < 30% — группа стабильно недогружена на протяжении двух недель. Только тогда безопасно уменьшить количество нод.

Формула

ceil(p95_14d × nodes / target_utilization), где target_utilization = 0.60 (60%).

Примеры

Исходное p95 (14д) Формула Результат
3 ноды по ~20% 22% ceil(0.22 × 3 / 0.60) = ceil(1.1) = 2 2 ноды, утилизация ~33%
2 ноды по ~45% 47% ceil(0.47 × 2 / 0.60) = ceil(1.57) = 2 2 ноды, не убираем (p95 > 30%)

Возврат burst-capacity

Эта опция выключена по умолчанию. Включите переключатель «Безопасный burst scale-down» в настройках оптимизации нод, если Oopps может автоматически возвращать временно добавленную capacity после краткосрочного всплеска.

Когда срабатывает

После не менее 30 минут, в которых p95 CPU и memory ниже 45%, и при наличии достаточных долгосрочных метрик. Oopps предлагает убрать только одну единицу capacity за раз.

Цель никогда не ниже наибольшего из трёх значений: исходного minimum node group, стратегического baseline и current − 1. Для autoscaling group Oopps возвращает minSize и initialSize к этому floor, но сохраняет maxSize, чтобы следующий burst мог снова получить capacity.

Автоматическое применение только после preflight

Для включённого burst-return ручное подтверждение не нужно: перед каждым применением Oopps заново выполняет fail-closed preflight. Если хотя бы одна проверка не пройдена, ноды не drainятся, policy не меняется, а причина сохраняется в истории операции.

Конфигурация

Параметр Значение Описание
target_utilization 0.60 Целевая утилизация при scale down (60%)
trend_delta_pp 0.10 Дельта тренда в процентных пунктах (10 п.п.)
safety_threshold 0.85 Абсолютный порог для страховочного триггера (85%)
scale_down_p95_threshold 0.30 Порог p95 для scale down (30%)
max_scale_step 3 Максимум нод, добавляемых/убираемых за раз
p95_short_minutes 30 Окно для короткого p95 (30 минут)
p95_long_minutes 1440 Окно для длинного p95 (24 часа)
scale_down_days 14 Период для стратегического scale down (14 дней)
burst_scale_down_enabled false Включает автоматический возврат временной burst-capacity после preflight
burst_scale_down_p95_threshold 0.45 Максимальный p95 CPU/Memory для burst-return (45%)
burst_scale_down_minutes 30 Продолжительность низкой нагрузки перед возвратом capacity
burst_scale_down_stabilization_minutes 30 Окно стабилизации после успешного burst-return

Cooldown

Cooldown реализован не через таймер, а через проверку факта: node_count в метриках совпадает с запрошенным значением? Если нет — скейлинг ещё в процессе, новое действие не выполняется.

Такой подход работает при любой скорости провижининга нод — от 30 секунд до 5 минут. Платформа не делает предположений о времени создания ноды.

Как применяется рекомендация

Scale up, burst-return и стратегический scale down выполняются по-разному. Scale up меняет scalePolicy node group через MKS API и может применяться автоматически. Scale down считается disruptive-операцией: перед ним Oopps требует безопасного preflight. Для стратегического scale down оператор дополнительно просматривает live preview и подтверждает операцию; включённый burst-return применяется автоматически только при успешном preflight.

Preflight перед scale down

Операция блокируется до изменения policy, если не пройдена хотя бы одна проверка:

Для стратегического scale down после подтверждения, а для burst-return автоматически после успешного preflight, Oopps последовательно выполняет cordon и drain выбранных нод с проверкой готовности workload после каждого шага. Только когда поды успешно перенесены, платформа снижает policy; пустые ноды удаляет Cluster Autoscaler.

Изменение scale policy

Автоматический burst-return не отменяет safety checks

В Auto mode автоматически применяются scale up и только явно включённый burst-return. Стратегический scale down всегда требует подтверждения оператора. Burst-return каждый раз повторяет live preflight с конкретными нодами и подами; при ошибке после drain Oopps снимает cordon, сохраняет причину и исходную policy в истории операции.

Возвращается одна единица capacity, а не обязательно VM с тем же идентификатором, который появился во время всплеска: Oopps выбирает ноду, для которой preflight доказывает безопасный drain. Это сохраняет размер группы и baseline, не привязывая безопасность к identity конкретной VM.

Проверка непрерывности работы

Strict SLO подтверждён для контролируемых сценариев

В изолированном Yandex Cloud test cluster scale up и product-controlled scale down проверены одновременными внешней stable-endpoint и внутренней Service-DNS пробами без retry. В SLO-окне зафиксировано ноль ошибок и таймаутов: scale up — 12/12 внешних и 6/6 внутренних запросов; scale down 3→2 — 675/675 и 436/436 соответственно.

Результат относится к проверенной stateless-топологии с готовым резервом и PDB. Он не заменяет preflight для конкретного кластера и не является обещанием нулевой недоступности при исчерпании capacity или несовместимых ограничениях планирования.

Что дальше?