Guides
KEDA

KEDA с Kafka: автоскейлинг по consumer lag

Настройка KEDA KafkaTrigger для скейлинга по consumer group lag. ScaledObject, bootstrapServers, consumerGroup, lagThres

Привет, коллеги. Если вы запускаете в Kubernetes джобы или стриминговые приложения, которые читают из Kafka, вы наверняка сталкивались с дилеммой: как эффективно масштабировать воркеры под изменяющуюся нагрузку. Ручное выставление реплик — это каменный век, а обычный HPA не видит глубину очереди в топиках. Сегодня разберем, как настроить автоматическое, элегантное и надежное масштабирование по consumer lag с помощью KEDA.

Установка и базовая настройка KEDA

Первым делом устанавливаем KEDA в кластер. Самый простой путь — через Helm.

helm repo add kedacore https://kedacore.github.io/charts
helm repo update
helm install keda kedacore/keda --namespace keda --create-namespace

После установки у вас появятся CRD для ScaledObject и TriggerAuthentication. Именно через ScaledObject мы и будем управлять скейлингом.

Конфигурация ScaledObject для Kafka

Допустим, у нас есть Deployment batch-image-processor, который читает из топика user-images в группе thumbnail-generators. Цель: увеличивать количество подов, когда лаг в группе растет, и уменьшать до нуля, когда очередь пуста.

Создадим манифест kafka-scaledobject.yaml:

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: kafka-consumer-scaledobject
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: batch-image-processor
  pollingInterval: 30
  cooldownPeriod: 300
  minReplicaCount: 0
  maxReplicaCount: 10
  triggers:
  - type: kafka
    metadata:
      bootstrapServers: kafka-cluster-kafka-bootstrap.kafka.svc:9092
      consumerGroup: thumbnail-generators
      topic: user-images
      lagThreshold: "100"
      offsetResetPolicy: latest
    authenticationRef:
      name: keda-trigger-auth-kafka

Разберем ключевые поля:

  • scaleTargetRef: Указываем на наш Deployment, который будем масштабировать.
  • pollingInterval: Как часто KEDA опрашивает метрики лага (в секундах). 30 — разумный баланс между скоростью реакции и нагрузкой.
  • cooldownPeriod: Период охлаждения (в секундах) после масштабирования вниз. Важно для batch-воркеров, чтобы дать подам время завершить работу. 300 секунд — хорошее начало.
  • minReplicaCount: 0 — это наша суперсила. KEDA может масштабировать до нуля подов, когда лага нет, экономя ресурсы.
  • lagThreshold: Порог срабатывания. KEDA будет стремиться поддерживать лаг на одного потребителя не выше этого значения. Формула расчета реплик: ceil(общий_лаг / lagThreshold).
  • offsetResetPolicy: Политика при старте, если offset не найден. latest типично для batch-задач.

Аутентификация в Kafka

В примере выше используется TriggerAuthentication. Для простоты внутреннего кластера с PLAINTEXT можно обойтись без него, указав bootstrapServers напрямую. Но для прода или использования SASL/SSL потребуется создать секрет и ссылку на него.

apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
  name: keda-trigger-auth-kafka
  namespace: default
spec:
  secretTargetRef:
  - parameter: sasl
    name: kafka-credentials
    key: sasl
  - parameter: tls
    name: kafka-credentials
    key: tls

Как это работает с HPA

KEDA не заменяет HPA, а выступает его “драйвером метрик”. При активном скейлинге (когда реплик > 0) KEDA создает и настраивает HPA-объект для нашего Deployment. HPA получает кастомную метрику kafka_lag от KEDA Metrics Adapter и управляет репликами. При масштабировании к нулю KEDA просто останавливает все реплики Deployment, а HPA деактивируется. Это гениально и прозрачно.

Типичные грабли и подводные камни

  1. Неправильный bootstrapServers. Внутри кластера используйте внутренний FQDN сервиса Kafka, как в примере. Для внешнего кластера убедитесь в доступности с нод Kubernetes.
  2. Игнорирование cooldownPeriod. Слишком малое значение (например, 30s) для batch-задач приведет к частому пересозданию подов, которые не успевают завершить работу. Это убивает эффективность.
  3. Забытая consumer group. Убедитесь, что consumerGroup в конфиге KEDA точно соответствует имени группы, которую использует ваше приложение. Несовпадение — самая частая причина “нулевого лага” при полном топике.
  4. Слишком агрессивный lagThreshold. Если установить lagThreshold: "1", KEDA создаст по поду на каждое сообщение. Это сломает ваш кластер. Значение должно отражать реальную пропускную способность одного пода.
  5. Scale to zero для long-running потребителей. Для стриминговых приложений (например, Kafka Streams), которые хранят состояние, масштабирование до нуля может быть деструктивным. В таких случаях выставляйте minReplicaCount: 1.

Итог

KEDA превращает Kafka consumer lag из скрытой метрики в мощный рычаг для автоматического масштабирования. Потратив час на настройку, вы навсегда забудете о ручной подкрутке реплик под всплески данных и сэкономите существенные ресурсы в периоды простоя благодаря scale-to-zero. Просто помните о cooldown и правильно настройте пороги.