Что такое KEDA и зачем он нужен, если есть HPA?
KEDA добавляет event-driven autoscaling поверх HPA: масштабирует workload по очередям (Redis, Kafka, SQS), Prometheus-метрикам и cron-расписанию, умеет опускать replicas до нуля, чего стандартный HPA не поддерживает.
Что такое KEDA и чем отличается от HPA
HPA (Horizontal Pod Autoscaler) умеет масштабировать по CPU, памяти и custom metrics через Metrics API. Но он не знает о длине очереди RabbitMQ, Kafka consumer lag, числе сообщений в Azure Service Bus или произвольном Prometheus-запросе как единственном источнике истины. KEDA (Kubernetes Event-Driven Autoscaling) закрывает этот пробел: он добавляет ScaledObject / ScaledJob CRD, набор scalers (встроенных интеграций с внешними источниками) и собственный Metrics Server, который публикует значения через External Metrics API. HPA при этом остаётся исполнителем масштабирования — KEDA просто кормит его нужными метриками.
Архитектура
Оператор KEDA состоит из нескольких компонентов:
- keda-operator — следит за ScaledObject/ScaledJob, управляет HPA-объектами, реализует scale-to-zero.
- keda-metrics-apiserver — реализует external.metrics.k8s.io и отдаёт значения scalers в HPA.
- ScaledObject — привязывает Deployment/StatefulSet к одному или нескольким triggers.
- ScaledJob — вместо масштабирования Deployment создаёт Job-объекты под каждый event (батчевая обработка).
Цикл работы: scaler читает внешний источник каждые pollingInterval секунд → вычисляет метрику → KEDA обновляет HPA targetAverageValue → HPA меняет replicas. Если все scalers возвращают 0 и minReplicaCount: 0, KEDA удаляет HPA и выставляет replicas=0 напрямую, обходя HPA (тот не умеет в ноль).
Пример ScaledObject для Redis-очереди
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: worker
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: worker
pollingInterval: 15 # опрос каждые 15 секунд
cooldownPeriod: 60 # ждать 60 секунд перед scale-to-zero
minReplicaCount: 0
maxReplicaCount: 30
triggers:
- type: redis
metadata:
address: redis-master.default.svc:6379
listName: job_queue
listLength: "5" # 1 реплика на каждые 5 сообщений
authenticationRef:
name: redis-secret
Пример ScaledObject для Kafka
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: kafka-consumer
spec:
scaleTargetRef:
name: kafka-consumer
minReplicaCount: 1
maxReplicaCount: 50
triggers:
- type: kafka
metadata:
bootstrapServers: kafka.default.svc:9092
consumerGroup: my-group
topic: events
lagThreshold: "100" # 1 реплика на каждые 100 сообщений лага
offsetResetPolicy: latest
TriggerAuthentication для секретов
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: redis-secret
spec:
secretTargetRef:
- parameter: password
name: redis-credentials
key: password
Когда KEDA необходим, а когда достаточно HPA
HPA с custom metrics адаптера достаточно, если метрика уже есть в Prometheus и Prometheus Adapter настроен. KEDA оправдан когда: нужен scale-to-zero, источник — очередь / event bus, не хочется настраивать Prometheus Adapter вручную, или используются cloud-native источники (SQS, Azure Queue, GCP Pub/Sub).
Подводные камни
- Scale-to-zero требует внешней точки активации; если scaler не видит источник (network issue, wrong credentials), он может ошибочно вернуть 0 и убрать все реплики.
- pollingInterval не равен latency реакции: при коротком spike в очереди реплики могут не успеть подняться до начала timeout сообщений.
- Credentials к внешним системам надо хранить в TriggerAuthentication + Secret, а не в metadata в открытом виде — иначе они попадут в etcd незашифрованными.
- ScaledJob создаёт новый Job на каждый event batch; без TTL-after-finished контроллера завершённые Jobs копятся и засоряют namespace.
- При наличии нескольких triggers KEDA берёт максимальное значение из всех — агрегация не настраивается. Это может приводить к неожиданно высокому числу реплик.
- KEDA управляет HPA-объектом; ручные изменения HPA будут перезаписаны оператором на следующем reconcile-цикле.
- minReplicaCount: 0 вместе с длинным cooldownPeriod может привести к тому, что реплики уйдут в ноль во время ночного затишья, а утренний burst встретит cold-start задержку контейнеров.
- После обновления KEDA CRD (upgrade оператора) существующие ScaledObject могут требовать миграции схемы — проверяйте CHANGELOG перед обновлением.
Common mistakes
- Говорить, что KEDA только для Kafka
- Не знать ScaledObject
- Игнорировать auth к scaler
What the interviewer is testing
- Объясняет event-driven scaling
- Понимает связь с HPA
- Приводит внешний metric use case