Представьте: сервис на 20 подах стабильно держит 500 RPS, но каждый вечер в 19:00 прилетает пик до 2000 RPS. Вы настроили Horizontal Pod Autoscaler по CPU — и он молчит. Под нагрузкой процессор не растёт, потому что узкое место — блокировки в базе или ожидание ответа внешнего API. Поды не масштабируются, latency растёт, алерты горят. Знакомо? Это классическая ловушка автоскейлинга: инструмент работает, но мерит не то.
В этой статье разберём, как на самом деле устроен автоскейлинг в Kubernetes, сравним три подхода — HPA, VPA и KEDA — и покажем на примере, где каждый из них экономит деньги, а где создаёт проблемы. А заодно обсудим, почему самостоятельное освоение этих механизмов часто упирается в отсутствие обратной связи и дорогие ошибки.
Почему автоскейлинг — это не просто «включить HPA»
Автоскейлинг в Kubernetes — это не одна кнопка, а набор контроллеров, каждый со своей логикой и ограничениями. HPA (Horizontal Pod Autoscaler) меняет количество реплик, VPA (Vertical Pod Autoscaler) — ресурсы (CPU/memory) контейнера, KEDA (Kubernetes Event-driven Autoscaling) добавляет масштабирование по событиям из очередей, Kafka, cron и других источников. Все они работают через API метрик (metrics-server, Prometheus Adapter, custom metrics API), и именно здесь начинаются сложности.
Ключевая идея: автоскейлер — это контур управления с обратной связью. Он периодически опрашивает метрики, сравнивает с целевым значением и меняет желаемое состояние (replicas или resources). Задержка этого контура, качество метрик и правильный выбор целевого показателя определяют, будет ли система стабильной или уйдёт в oscillation (колебания).
Разбор реального кейса: пики трафика и очередь заказов
Возьмём типичный интернет-магазин. Есть API-сервис, обрабатывающий заказы, и очередь RabbitMQ, куда падают задачи на резервирование товара. В обычном режиме API потребляет 200m CPU на под, при пике — до 800m. HPA настроен на targetCPUUtilizationPercentage: 70. Казалось бы, всё просто.
Но при пике CPU не успевает вырасти: API большую часть времени ждёт ответа от платёжного шлюза. HPA видит среднюю утилизацию 40% и не масштабирует. Очередь растёт, заказы обрабатываются с задержкой в минуты.
Что делает практик:
1. Переводит HPA на кастомную метрику — например, http_requests_per_second из Prometheus Adapter. Целевое значение — 100 RPS на под. Теперь масштабирование реагирует на реальную нагрузку, а не на CPU.
2. Для очереди заказов подключает KEDA с триггером по длине очереди RabbitMQ. KEDA может масштабировать до нуля, когда очередь пуста, и быстро поднимать поды при всплеске.
3. Настраивает VPA в режиме Off (только рекомендации), чтобы понять реальные запросы ресурсов и не конфликтовать с HPA.
Результат: latency при пике снижается с нескольких секунд до сотен миллисекунд, а в ночные часы KEDA масштабирует поды до нуля, экономя на неиспользуемых ресурсах.
Если бы оставили HPA по CPU, проблема бы только усугубилась: поды не добавлялись бы, а VPA в режиме Auto мог бы внезапно перезапустить поды, изменив requests, что привело бы к кратковременной недоступности.
Три подхода: сравниваем на практике
HPA: горизонтальное масштабирование по метрикам
HPA увеличивает число реплик на основе наблюдаемых метрик. Поддерживает CPU, память, кастомные метрики (например, RPS) и внешние метрики (из Kafka, облачных сервисов). Основной параметр — целевое значение (target). Алгоритм простой: desiredReplicas = ceil(currentReplicas * (currentMetricValue / targetMetricValue)).
Где ломается: задержка метрик. Если Prometheus собирает данные раз в 30 секунд, а HPA опрашивает каждые 15, реакция на пик может занять минуту и больше. За это время пользователи уже увидят таймауты.
Совет: используйте behavior в HPA (доступно с Kubernetes 1.18) для настройки scaleUp/scaleDown политик, чтобы избежать резких скачков и oscillation.
VPA: вертикальное масштабирование и рекомендации
VPA автоматически подбирает requests/limits для контейнеров на основе исторического потребления. Работает в трёх режимах: Off (только рекомендации), Initial (применяет при создании пода), Auto (применяет и перезапускает поды при изменении).
Главный подводный камень: VPA в режиме Auto перезапускает поды при изменении ресурсов. В production это может привести к сбоям, если не настроен PodDisruptionBudget. Кроме того, VPA конфликтует с HPA, если оба используют CPU или память как метрику. Правильная схема: HPA масштабирует по кастомной метрике (RPS), VPA управляет только памятью (или наоборот), либо VPA работает в режиме Off для сбора рекомендаций.
KEDA: масштабирование по событиям
KEDA расширяет HPA, добавляя event-driven триггеры: длина очереди, лаг Kafka, cron-расписание, метрики из базы данных. Он может масштабировать до нуля (scale-to-zero), что критично для экономии в непиковые часы.
Ограничение: scale-to-zero подразумевает, что приложение умеет быстро стартовать (холодный старт). Если ваш сервис инициализируется 30 секунд, первый запрос после простоя может завершиться таймаутом. Решение — использовать minReplicaCount: 1 для критичных сервисов или настроить (warm-up).
Где ломается механизм: три сценария отказа
1. Задержка кастомных метрик
Вы настроили HPA на метрику из Prometheus Adapter, но адаптер кэширует данные или сам Prometheus не успевает. В результате HPA принимает решение на основе устаревших данных. Как заметить: сравните время между всплеском нагрузки и моментом увеличения реплик. Если задержка превышает 1-2 минуты, стоит задуматься о более частом сборе метрик или использовании внешних метрик напрямую из приложения.
Что делать: уменьшить интервал scrape в Prometheus (например, до 15 секунд), настроить HPA с behavior.scaleUp.stabilizationWindowSeconds: 0 для быстрой реакции, но с осторожностью.
2. Конфликт HPA и VPA
Если HPA и VPA одновременно управляют CPU, они начинают «перетягивать одеяло»: HPA увеличивает реплики, VPA увеличивает requests, что снижает утилизацию и провоцирует дальнейший рост реплик. Кластер уходит в шторм пересозданий подов.
Как заметить: нестабильное количество реплик, частые перезапуски подов без изменения нагрузки. Что делать: разнести зоны ответственности. Например, HPA — по RPS, VPA — по памяти. Или использовать VPA только в режиме Off для сбора рекомендаций и ручного обновления манифестов.
3. Scale-to-zero и холодный старт
KEDA масштабирует до нуля, но приложение не готово к быстрому запуску. Первый запрос после простоя обрабатывается 10-20 секунд, пользователи уходят. Как заметить: мониторинг времени ответа на первый запрос после периода низкой нагрузки. Что делать: установить minReplicaCount: 1 для пользовательских API, либо использовать KEDA с advanced настройками, например, horizontalPodAutoscalerConfig с behavior для плавного старта.
Пути освоения: самостоятельный, курсы, практика
Автоскейлинг в Kubernetes — область, где теория без практики бесполезна. Можно прочитать документацию, но настроить HPA, VPA и KEDA в связке без обратной связи сложно: ошибки проявляются не сразу, а в production при пиковой нагрузке.
Самостоятельный путь: документация Kubernetes, статьи, эксперименты в minikube или kind. Плюс — бесплатно, минус — нет структуры, легко упустить важные детали (например, взаимодействие VPA и HPA), а ошибки в production могут стоить дорого.
Курсы и структурированное обучение: дают последовательность, разбор кейсов и обратную связь. Например, в курсе Kubernetes в production разбираются именно такие сценарии: как настроить HPA по кастомным метрикам, избежать конфликтов с VPA, использовать KEDA для event-driven масштабирования. Персонализированные уроки под уровень студента позволяют сразу применять знания к своему кластеру.
Практика в реальных проектах: самый ценный опыт, но требует времени и ответственности. Если вы работаете в команде, где есть наставник, это лучший вариант.
Честный trade-off: самостоятельное изучение экономит деньги, но может занять в 2-3 раза больше времени и привести к ошибкам, которые дорого исправлять. Курсы ускоряют процесс и дают проверенные схемы, но требуют финансовых вложений.
Кому подходит этот путь, а кому нет
Подходит: DevOps-инженерам, SRE, разработчикам, которые управляют production-кластерами и хотят автоматизировать масштабирование без сюрпризов. Если вы уже знакомы с основами Kubernetes (поды, деплойменты, сервисы) и хотите перейти на продвинутый уровень — это ваш путь.
Не подходит: новичкам, которые ещё не запускали кластер и не понимают, как работают requests/limits. Автоскейлинг — это следующий шаг после освоения базовых абстракций. Также не стоит идти сюда, если вы ищете только теоретические знания без практики — материал требует применения.
В финале хочу сказать: автоскейлинг в Kubernetes — это мощный инструмент, но он требует понимания метрик, задержек и взаимодействия компонентов. Если вы готовы разобраться в этих механизмах на практике, курс Kubernetes в production даёт структурированный путь с разбором реальных кейсов и обратной связью по вашим решениям. Начните с настройки HPA в тестовом кластере, а затем переходите к комплексным сценариям — и production скажет вам спасибо.