KEDA vs HPA: когда стандартного скейлинга не хватает
KEDA против встроенного HPA в Kubernetes. HPA скейлит по CPU/memory — этого часто мало. KEDA: любые метрики (Kafka lag,
Для чего создавался каждый
HPA (Horizontal Pod Autoscaler) создавался как встроенный в Kubernetes механизм для автоматического масштабирования подов на основе наблюдаемой нагрузки, в первую очередь — утилизации процессора и оперативной памяти. Его задача — поддерживать стабильность приложений под изменяющимся трафиком.
KEDA (Kubernetes Event-Driven Autoscaling) проектировался для решения другой задачи: масштабирования приложений, работающих с внешними системами (очереди, потоки данных, планировщики), где стандартных метрик Kubernetes недостаточно. Его цель — превратить любую внешнюю метрику в триггер для масштабирования, включая масштабирование до нуля подов.
В чём реально отличаются
Различия лежат в архитектуре, источниках метрик и поведении.
Источники метрик и триггеры: HPA работает с метриками, которые предоставляет Metrics Server (CPU, memory) или кастомные метрики из API-сервера метрик (например, от Prometheus Adapter). Эти метрики описывают состояние самого приложения или ноды. KEDA вводит понятие скалеров (scalers) — отдельных адаптеров для внешних систем. Скалер напрямую опрашивает источник (например, RabbitMQ, Apache Kafka, облачную очередь или Cron) и преобразует его состояние (длину очереди, лаг, расписание) в метрику для Kubernetes.
Масштабирование до нуля: HPA не умеет масштабировать до нуля подов. У него есть нижняя граница — minReplicas, которую вы задаёте вручную. KEDA — умеет. Когда во внешней системе нет работы (очередь пуста, лаг нулевой), KEDA может установить количество реплик в 0, экономя ресурсы. Как только появляется событие (поступает сообщение), KEDA мгновенно создаёт HPA и масштабирует приложение с 0 до minReplicas.
Управление объектами HPA: HPA — это статический объект, который вы создаёте и которым управляете. KEDA — это оператор, который сам динамически создаёт, управляет и удаляет объекты HPA на основе своей конфигурации (ScaledObject). Вы настраиваете не HPA, а поведение KEDA.
Логика принятия решений: В HPA вы задаёте целевое значение метрики (например, 70% CPU). В KEDA для многих скалеров вы задаёте пороговое значение для самой внешней метрики (например, “масштабируй, если в очереди больше 5 сообщений на одну реплику”). KEDA сама рассчитывает целевую метрику для HPA.
Когда выбрать HPA
Выбирайте стандартный HPA, когда ваша нагрузка хорошо коррелирует с внутренними метриками Kubernetes и вам не нужны специфичные функции KEDA.
- Простое веб-приложение или API, нагрузка на которое прямо зависит от числа запросов и хорошо отражается на потреблении CPU или памяти.
- Стабильная фоновая нагрузка, когда масштабирование до нуля не требуется или даже вредно (долгий холодный старт).
- Сценарии, где нужны сложные правила масштабирования на основе нескольких метрик (CPU, memory, кастомные из Prometheus) с разными весами. Нативная поддержка нескольких метрик в HPA мощнее.
- Стремление к минимальной сложности. HPA — часть Kubernetes, не требует установки дополнительных операторов.
Минус HPA: если ваше приложение простаивает в ожидании сообщений из очереди, потребляя минимум CPU, HPA не увидит необходимости масштабировать, хотя работа может накопиться в самой очереди.
Когда выбрать KEDA
Выбирайте KEDA, когда логика масштабирования определяется внешними по отношению к Kubernetes событиями.
- Обработчики очередей сообщений: Kafka, RabbitMQ, AWS SQS, Azure Service Bus. Скейлинг на основе длины очереди или лага — идеальный для KEDA сценарий.
- Пакетные задания и задачи по расписанию (Cron). Запуск вычислений в определенное время или при появлении файла в хранилище (Blob storage, S3).
- Сервисы с выраженной пульсирующей нагрузкой, где между пиками ресурсы можно полностью освобождать (scale to zero). Например, ночной обработчик отчётов.
- Работа с метриками, которые сложно или неэффективно проксировать в Metrics API. KEDA берёт эту задачу на себя через скалеры.
Минус KEDA: это дополнительный компонент в кластере, который нужно устанавливать и поддерживать. Конфигурация специфична и требует изучения. Для чисто CPU/Memory-нагрузки он добавляет ненужную абстракцию.
Могут ли работать вместе
Да, и это основной режим работы KEDA. KEDA не заменяет HPA, а становится управляющим слоем над ним.
Как это работает:
- Вы разворачиваете приложение (например, Consumer для Kafka) и создаёте для него ресурс KEDA
ScaledObject. - Оператор KEDA следит за метрикой через выбранный скалер (Kafka scaler).
- Когда метрика равна нулю, KEDA масштабирует Deployment до 0 реплик. Объекта HPA в этот момент не существует.
- Как только в топике Kafka появляется сообщение, KEDA:
- Масштабирует Deployment до значения
minReplicas, указанного вScaledObject. - Создаёт объект HPA для этого Deployment.
- Начинает непрерывно подавать рассчитанную метрику (например, текущий лаг на реплику) в этот HPA.
- Масштабирует Deployment до значения
- Далее стандартный механизм HPA в Kubernetes, получая метрики от KEDA, масштабирует количество подов вверх или вниз, но не ниже
minReplicas. - Когда нагрузка снова падает до нуля, KEDA удаляет объект HPA и масштабирует Deployment до 0.
Таким образом, KEDA использует проверенную, надежную и интегрированную в Kubernetes систему HPA для непосредственного масштабирования, решая две её изначальные проблемы: получение метрик из внешних систем и возможность масштабирования до нуля.