🟡 Intermediate

KEDA — Event-Driven Autoscaling pre Kubernetes

KEDA (Kubernetes Event-Driven Autoscaling) je CNCF Graduated projekt, ktorý rozširuje Kubernetes Horizontal Pod Autoscaler o schopnosť škálovať aplikácie podľa externých event zdrojov — Kafka topicov, RabbitMQ queue, AWS SQS, Azure Service Bus, Prometheus queries, Redis zoznamov a desiatok ďalších.

Hlavný rozdiel oproti štandardnému HPA: KEDA vie škálovať od nuly (scale-to-zero) a späť, a reaguje na metriky, ktoré samotný HPA nevie získať.


Prečo nie samotné HPA?

Štandardné HorizontalPodAutoscaler vie škálovať podľa:

  1. CPU/Memory — základné resource metriky cez metrics-server.
  2. Custom metrics — cez custom.metrics.k8s.io API (typicky Prometheus adapter).
  3. External metrics — cez external.metrics.k8s.io API.

Problémy:

  • Minimum 1 replika — HPA nevie škálovať na nulu. Ak máte 50 workerov na rôzne fronty, každý drží aspoň 1 pod — aj keď fronta je prázdna.
  • Konfigurácia external metrík je náročná — treba nainštalovať Prometheus Adapter, napísať ConfigMap s rule-set, riešiť latenciu metrík.
  • Reaktívnosť — HPA scraping beží v pravidelnom intervale, zmena záťaže sa prejaví so zdržaním.

KEDA tieto body rieši natívne a prichádza s 60+ built-in scalermi pre rôzne zdroje.


Architektúra KEDA

┌────────────────────────────────┐
│  KEDA Operator (deployment)    │
│  ├── Controller (reconcile)    │
│  └── Scaler implementations    │
└──────────────┬─────────────────┘
               │
               │ vytvara/edituje
               ▼
┌──────────┐   ┌──────────────┐
│ HPA      │◄──│ ScaledObject │
└────┬─────┘   └──────────────┘
     │
     │ external metrics API
     ▼
┌──────────────────────────────┐
│ KEDA Metrics Adapter         │
│ (External Metrics Provider)  │
└──────────────┬───────────────┘
               │
               ▼
        ┌──────────────┐
        │ External     │
        │ Source       │
        │ (Kafka, ...) │
        └──────────────┘

KEDA pozostáva z dvoch hlavných komponentov:

  1. KEDA Operator — sleduje ScaledObject a ScaledJob CRD zdroje. Pre každý ScaledObject automaticky vytvára HorizontalPodAutoscaler. Navyše rieši prechod medzi 0 ↔ 1 replikami, ktorý klasické HPA nevie.
  2. KEDA Metrics Adapter — implementuje Kubernetes external.metrics.k8s.io API, ktoré HPA využíva. Keď HPA chce vedieť "koľko správ je v Kafka topicu", adapter to query-uje zo zdroja cez príslušný scaler.

Inštalácia

# Helm
helm repo add kedacore https://kedacore.github.io/charts
helm install keda kedacore/keda \
  --namespace keda \
  --create-namespace \
  --version 2.15.0

# Overenie
kubectl get pods -n keda
kubectl api-resources | grep keda

KEDA je ľahká — operator a metrics adapter dokopy ~100 MB RAM.


ScaledObject — základný blok

ScaledObject prepája deployment s jedným alebo viacerými triggermi (scalermi):

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: kafka-consumer
  namespace: production
spec:
  scaleTargetRef:
    name: kafka-consumer-deployment
  pollingInterval: 15          # sekundy medzi check-mi
  cooldownPeriod: 300          # sekundy bez eventov pred scale-to-zero
  minReplicaCount: 0           # povoli scale-to-zero
  maxReplicaCount: 20
  triggers:
    - type: kafka
      metadata:
        bootstrapServers: kafka.kafka:9092
        consumerGroup: payment-processor
        topic: payments
        lagThreshold: "50"

Ako to funguje:

  1. Keď nikto nič do topicu nepíše → lag = 0 → po cooldownPeriod sekundách KEDA škáluje na 0.
  2. Keď sa objaví prvá správa → KEDA ju detekuje pri pollingInterval, škáluje z 0 → 1.
  3. Ďalšie škálovanie (1 → N) robí HPA, ktorý KEDA vytvoril, podľa lagThreshold (50 správ = 1 replika).

Kľúčová vec: prechod 0 ↔ 1 rieši KEDA, nie HPA. HPA samotné toto nevie.


Populárne scalery

KEDA podporuje viac než 60 scalerov. Najčastejšie:

RabbitMQ

triggers:
  - type: rabbitmq
    metadata:
      host: amqp://rabbitmq.rabbitmq.svc:5672
      queueName: orders
      mode: QueueLength
      value: "100"

AWS SQS

triggers:
  - type: aws-sqs-queue
    metadata:
      queueURL: https://sqs.eu-central-1.amazonaws.com/123/my-queue
      queueLength: "50"
      awsRegion: eu-central-1
      identityOwner: operator

Prometheus query

triggers:
  - type: prometheus
    metadata:
      serverAddress: http://prometheus.monitoring:9090
      query: sum(rate(http_requests_total{app="api"}[2m]))
      threshold: "100"

Trieda prometheus je extrémne silná — viete škálovať čokoľvek, čo sa dá vyjadriť PromQL dotazom: HTTP req/s, latencia, aktívne užívateľské sessions, custom business metriky.

Redis list

triggers:
  - type: redis
    metadata:
      address: redis.redis.svc:6379
      listName: jobs
      listLength: "20"

Cron

triggers:
  - type: cron
    metadata:
      timezone: Europe/Bratislava
      start: 0 8 * * 1-5
      end: 0 18 * * 1-5
      desiredReplicas: "10"

Užitočný na predikovateľné záťažové okná (pracovná doba, kampane).


Scale-to-zero v praxi

Scale-to-zero znamená, že pod neexistuje, keď nie je práca. Úspora: RAM, CPU a node-level kapacita sa uvoľnia. Pri 50 workeroch v klastri to môže byť rozdiel niekoľkých nodov.

Ako to vyzerá v čase:

T=0:00   zadná fronta prázdna        → replicas=0    (žiadny pod)
T=0:05   event prichádza do queue    → KEDA detekuje → replicas=1
T=0:06   pod sa spúšťa, spracuje event
T=0:10   ďalších 500 events za minútu → HPA → replicas=10
T=0:20   queue drain, ~10 events/min  → HPA → replicas=2
T=0:25   fronta prázdna                → cooldown (5 min)
T=0:30   žiadne eventy                 → KEDA → replicas=0

Upozornenie: scale-to-zero má latenciu pri prvej správe — pod musí štartnúť, čo môže trvať 10-30 sekúnd. Pre synchrónne API (frontend → API) to nie je vhodné. Pre async fronty je to ideálne.


ScaledJob — pre batch processing

Ak spracovávate batch jobs, kde každý event = nová K8s Job, použite ScaledJob:

apiVersion: keda.sh/v1alpha1
kind: ScaledJob
metadata:
  name: image-processor
spec:
  jobTargetRef:
    template:
      spec:
        containers:
          - name: processor
            image: my-registry/image-processor:latest
        restartPolicy: Never
  pollingInterval: 10
  maxReplicaCount: 50
  triggers:
    - type: rabbitmq
      metadata:
        host: amqp://rabbitmq.rabbitmq.svc:5672
        queueName: image-jobs
        mode: QueueLength
        value: "1"

Každá správa v queue → nová K8s Job s jedným podom. Po dokončení sa pod ukončí. Vhodné pre CPU-intenzívne one-off tasky, kde nechcete dlhovekých workerov.


Authentication cez TriggerAuthentication

Scaler často potrebuje credentials (IAM, SAS token, password). KEDA rieši cez TriggerAuthentication:

apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
  name: aws-credentials
  namespace: production
spec:
  secretTargetRef:
    - parameter: awsAccessKeyID
      name: aws-secret
      key: AWS_ACCESS_KEY_ID
    - parameter: awsSecretAccessKey
      name: aws-secret
      key: AWS_SECRET_ACCESS_KEY
---
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: sqs-worker
spec:
  scaleTargetRef:
    name: sqs-worker
  triggers:
    - type: aws-sqs-queue
      metadata:
        queueURL: https://sqs.eu-central-1.amazonaws.com/123/my-queue
        queueLength: "50"
      authenticationRef:
        name: aws-credentials

Alebo cez Workload Identity / IRSA / Pod Identity — bez statických kľúčov.


Integrácia s Knative / Dapr

KEDA sa dobre dopĺňa s inými cloud-native projektmi:

  • Knative Serving — má vlastný autoscaler, ale viete ho nahradiť KEDA pre špecifické use-cases.
  • Dapr — pre event-driven aplikácie, kde Dapr rieši sidecar-komunikáciu s brokerom a KEDA rieši škálovanie.
  • Argo Workflows — KEDA umí škálovať worker pools workflowov podľa fronty.

Produkčné tipy a typické chyby

  • Nikdy nepoužívajte HPA súčasne s KEDA pre tú istú deployment — KEDA si vytvorí vlastné HPA, manuálne HPA bude kolidovať.
  • cooldownPeriod nastavte dostatočne dlhý (min 5 min), aby ste nezaskakovali 0 ↔ 1 pri flapping eventoch.
  • pollingInterval — default 30 s. Pre rýchlejšiu reakciu znížte na 10-15 s, ale pozor na zaťaženie zdroja.
  • Pravidelne monitorujte keda-operator logy — chyby pri spojení so scalerom sa tam ukážu.
  • Fallback policyfallback v ScaledObject definuje, čo robiť, keď scaler nie je dostupný (napr. Kafka padne). Default správanie môže spôsobiť škálovanie na minimum.
  • Multiple triggers — jeden ScaledObject môže mať viac triggerov. HPA zvolí maximum z nich.

Zhrnutie

KEDA je dnes štandardná odpoveď na otázku "ako v Kubernetes škálovať aplikácie podľa fronty alebo externej metriky". Je ľahká, CNCF Graduated, má širokú podporu scalerov a predovšetkým prináša scale-to-zero, ktoré samotné HPA nevie.

Pre moderné event-driven architektúry (Kafka, SQS, RabbitMQ, webhooks spracované async) je KEDA jedno z najpraktickejších zlepšení, ktoré viete do klastra pridať — inštalácia trvá minúty, efekt na resource utilization je zvyčajne dvojciferne percentný.

Odkazy