ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • KEDA: Kubernetes Event-Driven Autoscaling
    이코에코(Eco²)/Applied 2025. 12. 26. 17:15

    GitHub: kedacore/keda
    CNCF 프로젝트: Graduated (2024)


    KEDA (Kubernetes Event-Driven Autoscaling)는 이벤트 기반 워크로드에 대한 세밀한 오토스케일링을 제공하는 Kubernetes 컴포넌트이다. 기존 HPA(Horizontal Pod Autoscaler)를 확장하여 외부 이벤트 소스(메시지 큐, 스트림, 데이터베이스 등)를 기반으로 스케일링할 수 있게 한다.

    KEDA의 핵심 기여

    ┌─────────────────────────────────────────────────────────────────┐
    │                    KEDA의 핵심 기여                               │
    ├─────────────────────────────────────────────────────────────────┤
    │                                                                  │
    │  1. 이벤트 기반 스케일링                                         │
    │     → CPU/메모리가 아닌 큐 길이, 메시지 수 등으로 스케일링        │
    │     → 워크로드 특성에 맞는 정밀한 스케일링                       │
    │                                                                  │
    │  2. Zero-to-N 스케일링                                           │
    │     → 이벤트가 없으면 Pod 수를 0으로 축소 (비용 절감)            │
    │     → 이벤트 발생 시 자동으로 Pod 생성                           │
    │                                                                  │
    │  3. 다양한 이벤트 소스 지원                                      │
    │     → 60+ 스케일러: RabbitMQ, Redis, Kafka, AWS SQS 등          │
    │     → 커스텀 메트릭 스케일러 지원                                │
    │                                                                  │
    │  4. HPA와의 원활한 통합                                          │
    │     → 기존 HPA 인프라 활용                                       │
    │     → External Metrics API 표준 준수                             │
    │                                                                  │
    └─────────────────────────────────────────────────────────────────┘

    HPA의 한계와 KEDA의 등장 배경

    ┌─────────────────────────────────────────────────────────────────┐
    │                 HPA의 한계                                        │
    ├─────────────────────────────────────────────────────────────────┤
    │                                                                  │
    │  문제 1: 제한된 메트릭 소스                                      │
    │  ────────────────────────                                        │
    │  • HPA는 기본적으로 CPU/Memory 메트릭만 지원                     │
    │  • Custom Metrics는 별도 어댑터 설치 필요                        │
    │  • External Metrics 연동이 복잡                                  │
    │                                                                  │
    │  문제 2: 최소 1개 Pod 필요                                       │
    │  ─────────────────────────                                       │
    │  • HPA는 minReplicas ≥ 1 (0으로 스케일 불가)                    │
    │  • 유휴 시간에도 리소스 비용 발생                                │
    │                                                                  │
    │  문제 3: 이벤트 기반 워크로드에 부적합                           │
    │  ────────────────────────────────                                │
    │  • 큐 기반 워크로드: CPU 사용률과 처리량이 비례하지 않음         │
    │  • 버스트 트래픽: CPU 메트릭 지연으로 스케일링 늦음              │
    │                                                                  │
    │  해결: KEDA                                                      │
    │  ────────────                                                    │
    │  • 다양한 이벤트 소스를 External Metrics로 노출                  │
    │  • ScaleToZero 지원으로 비용 최적화                              │
    │  • 이벤트 발생량에 비례한 정확한 스케일링                        │
    │                                                                  │
    └─────────────────────────────────────────────────────────────────┘

    Kubernetes HPA 기초

    KEDA를 이해하기 위해 먼저 HPA의 동작 원리를 이해해야 한다.

    1. HPA 동작 원리 (Control Loop)

    ┌─────────────────────────────────────────────────────────────────┐
    │                    HPA Control Loop                               │
    ├─────────────────────────────────────────────────────────────────┤
    │                                                                  │
    │  ┌────────────────────────────────────────────────────────────┐ │
    │  │                   HPA Controller                            │ │
    │  │  (kube-controller-manager 내부, 기본 15초 주기)             │ │
    │  └─────────────────────────┬──────────────────────────────────┘ │
    │                            │                                     │
    │            ┌───────────────┼───────────────┐                     │
    │            │               │               │                     │
    │            ▼               ▼               ▼                     │
    │     ┌──────────┐    ┌──────────┐    ┌──────────┐                │
    │     │ Metrics  │    │ Custom   │    │ External │                │
    │     │ Server   │    │ Metrics  │    │ Metrics  │                │
    │     │(Resource)│    │  API     │    │   API    │                │
    │     └──────────┘    └──────────┘    └──────────┘                │
    │            │               │               │                     │
    │            └───────────────┴───────────────┘                     │
    │                            │                                     │
    │                            ▼                                     │
    │                  ┌─────────────────┐                            │
    │                  │ 메트릭 수집 완료 │                            │
    │                  └────────┬────────┘                            │
    │                           │                                      │
    │                           ▼                                      │
    │                  ┌─────────────────┐                            │
    │                  │ 목표 Replicas   │                            │
    │                  │ 계산           │                             │
    │                  └────────┬────────┘                            │
    │                           │                                      │
    │                           ▼                                      │
    │                  ┌─────────────────┐                            │
    │                  │ Deployment      │                            │
    │                  │ Scale 조정      │                            │
    │                  └─────────────────┘                            │
    │                                                                  │
    │  동작 주기: --horizontal-pod-autoscaler-sync-period (기본 15s)  │
    │                                                                  │
    └─────────────────────────────────────────────────────────────────┘

    2. Kubernetes 메트릭 API 계층

    API 그룹 엔드포인트 제공자 용도
    metrics.k8s.io /apis/metrics.k8s.io/v1beta1 Metrics Server CPU, Memory (Resource)
    custom.metrics.k8s.io /apis/custom.metrics.k8s.io/v1beta1 Prometheus Adapter 등 클러스터 내부 커스텀 메트릭
    external.metrics.k8s.io /apis/external.metrics.k8s.io/v1beta1 KEDA, Stackdriver 등 외부 시스템 메트릭
    ┌─────────────────────────────────────────────────────────────────┐
    │              Kubernetes Metrics API 계층 구조                     │
    ├─────────────────────────────────────────────────────────────────┤
    │                                                                  │
    │  ┌─────────────────────────────────────────────────────────────┐│
    │  │                    API Server                                ││
    │  │  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐           ││
    │  │  │ metrics.    │ │ custom.     │ │ external.   │           ││
    │  │  │ k8s.io      │ │ metrics.    │ │ metrics.    │           ││
    │  │  │             │ │ k8s.io      │ │ k8s.io      │           ││
    │  │  └──────┬──────┘ └──────┬──────┘ └──────┬──────┘           ││
    │  └─────────┼───────────────┼───────────────┼───────────────────┘│
    │            │               │               │                     │
    │            ▼               ▼               ▼                     │
    │     ┌──────────┐    ┌──────────┐    ┌──────────┐                │
    │     │ Metrics  │    │Prometheus│    │   KEDA   │                │
    │     │ Server   │    │ Adapter  │    │  Metrics │                │
    │     │          │    │          │    │  Server  │                │
    │     └──────────┘    └──────────┘    └──────────┘                │
    │            │               │               │                     │
    │            ▼               ▼               ▼                     │
    │     ┌──────────┐    ┌──────────┐    ┌──────────┐                │
    │     │  kubelet │    │Prometheus│    │ RabbitMQ │                │
    │     │ (cAdvisor)│   │          │    │  Redis   │                │
    │     │          │    │          │    │  Kafka   │                │
    │     └──────────┘    └──────────┘    └──────────┘                │
    │                                                                  │
    │  KEDA는 external.metrics.k8s.io API를 제공하여                  │
    │  외부 시스템의 메트릭을 HPA에 노출                               │
    │                                                                  │
    └─────────────────────────────────────────────────────────────────┘

    3. HPA 스케일링 알고리즘

    HPA는 다음 수식으로 목표 레플리카 수를 계산한다:

    기본 수식:

    desiredReplicas = ⌈3 × (75/50)⌉ = ⌈4.5⌉ = 5

     

    다중 메트릭 시:

    각 메트릭에 대해 desiredReplicas 계산 → 최댓값 선택

    예시:

    현재 상태:
      currentReplicas = 2
      currentMetricValue = 100 (큐 메시지 수)
      desiredMetricValue = 30 (목표: Pod당 30개)
    
    계산:
      desiredReplicas = ceil(2 × 100/30)
                      = ceil(2 × 3.33)
                      = ceil(6.67)
                      = 7
    
    결과: 7개 Pod로 스케일 아웃

    KEDA 아키텍처

    1. 전체 구성 요소

    ┌─────────────────────────────────────────────────────────────────┐
    │                    KEDA 아키텍처                                  │
    ├─────────────────────────────────────────────────────────────────┤
    │                                                                  │
    │  ┌─────────────────────────────────────────────────────────────┐│
    │  │                      keda namespace                          ││
    │  │                                                              ││
    │  │  ┌────────────────┐  ┌────────────────┐  ┌───────────────┐ ││
    │  │  │ KEDA Operator  │  │ KEDA Metrics   │  │   Admission   │ ││
    │  │  │                │  │    Server      │  │   Webhooks    │ ││
    │  │  │  ┌──────────┐  │  │                │  │               │ ││
    │  │  │  │ Scaler   │  │  │ External       │  │ ScaledObject  │ ││
    │  │  │  │ Handler  │  │  │ Metrics API    │  │ Validation    │ ││
    │  │  │  └──────────┘  │  │                │  │               │ ││
    │  │  └───────┬────────┘  └───────┬────────┘  └───────────────┘ ││
    │  │          │                   │                              ││
    │  └──────────┼───────────────────┼──────────────────────────────┘│
    │             │                   │                                │
    │             │                   │ external.metrics.k8s.io       │
    │             │                   │                                │
    │  ┌──────────┼───────────────────┼──────────────────────────────┐│
    │  │          │                   │                              ││
    │  │          ▼                   ▼                              ││
    │  │  ┌────────────┐      ┌────────────┐                        ││
    │  │  │ ScaledObject│      │    HPA     │                        ││
    │  │  │ (CR)        │      │ (자동생성) │                        ││
    │  │  └──────┬─────┘      └──────┬─────┘                        ││
    │  │         │                   │                               ││
    │  │         └───────────────────┤                               ││
    │  │                             │                               ││
    │  │                             ▼                               ││
    │  │                      ┌────────────┐                         ││
    │  │                      │ Deployment │                         ││
    │  │                      │  / Job     │                         ││
    │  │                      └────────────┘                         ││
    │  │                                                              ││
    │  │                    target namespace                          ││
    │  └──────────────────────────────────────────────────────────────┘│
    │                                                                  │
    │                             │                                    │
    │                             ▼                                    │
    │                      ┌────────────┐                              │
    │                      │ RabbitMQ   │                              │
    │                      │ Redis      │                              │
    │                      │ Kafka      │  외부 이벤트 소스            │
    │                      └────────────┘                              │
    │                                                                  │
    └─────────────────────────────────────────────────────────────────┘

    2. KEDA Operator

    역할:

    • ScaledObject/ScaledJob CRD 감시
    • 트리거에 해당하는 Scaler 인스턴스 생성
    • HPA 객체 자동 생성/관리
    • Scale-to-Zero 처리 (HPA 없이 직접 스케일링)
    ┌─────────────────────────────────────────────────────────────────┐
    │                 KEDA Operator 동작 흐름                           │
    ├─────────────────────────────────────────────────────────────────┤
    │                                                                  │
    │  1. ScaledObject 생성 감지                                       │
    │     │                                                            │
    │     ▼                                                            │
    │  2. 트리거 설정 파싱 (RabbitMQ, Redis 등)                        │
    │     │                                                            │
    │     ▼                                                            │
    │  3. 해당 Scaler 인스턴스 생성                                    │
    │     │                                                            │
    │     ▼                                                            │
    │  4. HPA 객체 생성 (minReplicas ≥ 1일 때)                        │
    │     │                                                            │
    │     └─── HPA가 스케일링 담당 (1 ↔ maxReplicas)                  │
    │     │                                                            │
    │     ▼                                                            │
    │  5. Scale-to-Zero 처리 (minReplicas = 0일 때)                   │
    │     │                                                            │
    │     └─── Operator가 직접 스케일링 (0 ↔ 1)                       │
    │          (HPA는 0으로 스케일 불가하므로)                         │
    │                                                                  │
    └─────────────────────────────────────────────────────────────────┘

    3. KEDA Metrics Server

    역할:

    • external.metrics.k8s.io API 구현
    • HPA가 요청하는 메트릭 제공
    • Scaler를 통해 외부 시스템에서 메트릭 조회
    HPA ──► API Server ──► KEDA Metrics Server ──► Scaler ──► RabbitMQ
                  │
                  │ GET /apis/external.metrics.k8s.io/v1beta1/
                  │     namespaces/*/s0-rabbitmq-queue-length
                  ▼
            메트릭 값 반환: {value: 150}

    4. CRD 종류

    CRD 용도
    ScaledObject Deployment, StatefulSet 등 스케일링
    ScaledJob Job 기반 스케일링 (완료 후 삭제)
    TriggerAuthentication 네임스페이스 범위 인증 정보
    ClusterTriggerAuthentication 클러스터 범위 인증 정보

    External Metrics API 상세

    1. API 구조

    # API 엔드포인트
    GET /apis/external.metrics.k8s.io/v1beta1/namespaces/{namespace}/{metricName}
    
    # 예시 요청
    GET /apis/external.metrics.k8s.io/v1beta1/namespaces/scan/s0-rabbitmq-queue-length
    
    # 응답 형식
    {
      "kind": "ExternalMetricValueList",
      "apiVersion": "external.metrics.k8s.io/v1beta1",
      "metadata": {},
      "items": [
        {
          "metricName": "s0-rabbitmq-queue-length",
          "metricLabels": {},
          "timestamp": "2025-12-26T10:00:00Z",
          "value": "150"
        }
      ]
    }

    2. KEDA 메트릭 이름 규칙

    KEDA는 ScaledObject의 트리거를 기반으로 메트릭 이름을 생성한다:

    s{trigger-index}-{scaler-type}-{metric-name}
    
    예시:
      s0-rabbitmq-scan_queue         # 첫 번째 트리거, RabbitMQ, queue 길이
      s1-prometheus-http_requests    # 두 번째 트리거, Prometheus

    3. KEDA가 메트릭을 제공하는 과정

    ┌─────────────────────────────────────────────────────────────────┐
    │            KEDA External Metrics 제공 과정                        │
    ├─────────────────────────────────────────────────────────────────┤
    │                                                                  │
    │  1. ScaledObject 생성                                            │
    │     └─► KEDA Operator가 Scaler 인스턴스 생성                     │
    │                                                                  │
    │  2. HPA가 메트릭 요청 (15초 주기)                                │
    │     │                                                            │
    │     ├─► API Server가 KEDA Metrics Server로 라우팅               │
    │     │                                                            │
    │     └─► KEDA Metrics Server가 해당 Scaler 호출                  │
    │                                                                  │
    │  3. Scaler가 외부 시스템 조회                                    │
    │     │                                                            │
    │     ├─► RabbitMQ: Management API로 큐 길이 조회                 │
    │     ├─► Redis: XPENDING으로 Pending 메시지 수 조회              │
    │     └─► Kafka: Consumer Lag 조회                                │
    │                                                                  │
    │  4. 메트릭 값 반환                                               │
    │     └─► HPA가 desiredReplicas 계산                              │
    │                                                                  │
    └─────────────────────────────────────────────────────────────────┘

    ScaledObject 상세

    1. 전체 구조

    apiVersion: keda.sh/v1alpha1
    kind: ScaledObject
    metadata:
      name: scan-worker-scaledobject
      namespace: scan
    spec:
      # 1. 스케일링 대상
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: scan-worker
    
      # 2. 스케일링 범위
      minReplicaCount: 0         # 최소 (0 = scale-to-zero)
      maxReplicaCount: 10        # 최대
    
      # 3. 동작 설정
      pollingInterval: 15        # 메트릭 조회 주기 (초)
      cooldownPeriod: 300        # 스케일 다운 대기 시간 (초)
    
      # 4. 고급 설정
      advanced:
        restoreToOriginalReplicaCount: false
        horizontalPodAutoscalerConfig:
          behavior:
            scaleDown:
              stabilizationWindowSeconds: 300
    
      # 5. Fallback 설정
      fallback:
        failureThreshold: 3
        replicas: 2
    
      # 6. 트리거 정의
      triggers:
      - type: rabbitmq
        metadata:
          queueName: scan_queue
          mode: QueueLength
          value: "5"
        authenticationRef:
          name: rabbitmq-auth

    2. 주요 필드 상세

    scaleTargetRef

    scaleTargetRef:
      apiVersion: apps/v1       # 대상 API 버전
      kind: Deployment          # Deployment, StatefulSet 등
      name: scan-worker         # 대상 이름
      # envSourceContainerName: worker  # 환경변수 소스 컨테이너 (선택)

    스케일링 범위

    필드 기본값 설명
    minReplicaCount 0 최소 레플리카 수 (0 = scale-to-zero)
    maxReplicaCount 100 최대 레플리카 수
    idleReplicaCount - 유휴 시 유지할 레플리카 수 (선택)
    ┌─────────────────────────────────────────────────────────────────┐
    │            minReplicaCount와 idleReplicaCount 관계               │
    ├─────────────────────────────────────────────────────────────────┤
    │                                                                  │
    │  minReplicaCount: 0, idleReplicaCount: 미설정                   │
    │  ────────────────────────────────────────                        │
    │  이벤트 없음 → 0개 Pod                                           │
    │  이벤트 있음 → 1~maxReplicas                                    │
    │                                                                  │
    │  minReplicaCount: 0, idleReplicaCount: 2                        │
    │  ─────────────────────────────────────────                       │
    │  이벤트 없음 → 2개 Pod (대기 상태)                               │
    │  이벤트 있음 → 2~maxReplicas                                    │
    │                                                                  │
    │  용도: 콜드 스타트 지연 없이 빠른 응답 필요 시                   │
    │                                                                  │
    └─────────────────────────────────────────────────────────────────┘

    동작 설정

    필드 기본값 설명
    pollingInterval 30 메트릭 조회 주기 (초)
    cooldownPeriod 300 마지막 트리거 활성화 후 스케일 다운 대기 (초)
    ┌─────────────────────────────────────────────────────────────────┐
    │              pollingInterval과 cooldownPeriod                     │
    ├─────────────────────────────────────────────────────────────────┤
    │                                                                  │
    │  시간 ────────────────────────────────────────────────────────► │
    │                                                                  │
    │  메시지 수   ████████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░        │
    │              │              │                                    │
    │              │              └─ 메시지 처리 완료 (0개)            │
    │              │                                                   │
    │              └─ 메시지 유입 (100개)                              │
    │                                                                  │
    │  Pod 수          ┌────────────────────────────────┐              │
    │              ────┘                                └────          │
    │                  │                                │              │
    │                  │  ◄──── cooldownPeriod ────►   │              │
    │                  │         (300초)                │              │
    │                  │                                │              │
    │                  스케일 아웃               스케일 다운            │
    │                                                                  │
    │  cooldownPeriod 동안 메트릭이 0이어도 스케일 다운하지 않음       │
    │  → 일시적 부하 감소 시 불필요한 스케일 다운 방지                 │
    │                                                                  │
    └─────────────────────────────────────────────────────────────────┘

    Fallback 설정

    메트릭 조회 실패 시 안전 장치:

    fallback:
      failureThreshold: 3    # 연속 실패 횟수
      replicas: 2            # 실패 시 유지할 레플리카 수
    정상 ──► 메트릭 조회 실패 (1회) ──► 메트릭 조회 실패 (2회) ──► 
             메트릭 조회 실패 (3회) ──► Fallback 모드 (2 replicas 유지)

    RabbitMQ Scaler 상세

    1. 동작 원리

    ┌─────────────────────────────────────────────────────────────────┐
    │              RabbitMQ Scaler 동작 원리                            │
    ├─────────────────────────────────────────────────────────────────┤
    │                                                                  │
    │  ┌─────────────────┐                                            │
    │  │ KEDA Scaler     │                                            │
    │  │ (RabbitMQ)      │                                            │
    │  └────────┬────────┘                                            │
    │           │                                                      │
    │           │ HTTP GET /api/queues/{vhost}/{queue}                │
    │           │                                                      │
    │           ▼                                                      │
    │  ┌─────────────────┐                                            │
    │  │ RabbitMQ        │                                            │
    │  │ Management API  │  (포트 15672)                              │
    │  └────────┬────────┘                                            │
    │           │                                                      │
    │           │ 응답:                                                │
    │           │ {                                                    │
    │           │   "messages": 150,          ← 큐에 있는 메시지 수   │
    │           │   "messages_ready": 145,    ← 소비 가능한 메시지    │
    │           │   "messages_unacked": 5,    ← 처리 중인 메시지      │
    │           │   "consumers": 2,           ← 소비자 수             │
    │           │   "message_stats": {...}                             │
    │           │ }                                                    │
    │           │                                                      │
    │           ▼                                                      │
    │  ┌─────────────────┐                                            │
    │  │ 메트릭 계산     │                                            │
    │  │                 │                                            │
    │  │ mode에 따라:    │                                            │
    │  │ • QueueLength   │ → messages 사용                            │
    │  │ • MessageRate   │ → message_stats 사용                       │
    │  └────────┬────────┘                                            │
    │           │                                                      │
    │           ▼                                                      │
    │  ┌─────────────────┐                                            │
    │  │ HPA에 메트릭    │                                            │
    │  │ 제공            │                                            │
    │  └─────────────────┘                                            │
    │                                                                  │
    └─────────────────────────────────────────────────────────────────┘

    2. ScaledObject 설정 예시

    apiVersion: keda.sh/v1alpha1
    kind: ScaledObject
    metadata:
      name: scan-worker-scaledobject
      namespace: scan
    spec:
      scaleTargetRef:
        name: scan-worker
      minReplicaCount: 0
      maxReplicaCount: 10
      pollingInterval: 15
      cooldownPeriod: 300
      triggers:
      - type: rabbitmq
        metadata:
          # 필수 설정
          queueName: scan_queue
    
          # 모드 선택
          mode: QueueLength           # QueueLength 또는 MessageRate
    
          # 목표 값 (Pod당 처리할 메시지 수)
          value: "5"
    
          # RabbitMQ 연결 설정
          host: amqp://guest:guest@rabbitmq.rabbitmq.svc.cluster.local:5672/
    
          # 또는 hostFromEnv로 환경변수에서 가져오기
          # hostFromEnv: RABBITMQ_URL
    
          # vhost 설정 (기본값: /)
          vhostName: /
    
          # 큐가 없을 때 동작
          activationValue: "0"        # 0이면 스케일 다운
    
          # TLS 설정
          # unsafeSsl: "true"         # 인증서 검증 비활성화
    
        authenticationRef:
          name: rabbitmq-auth

    3. TriggerAuthentication 설정

    apiVersion: keda.sh/v1alpha1
    kind: TriggerAuthentication
    metadata:
      name: rabbitmq-auth
      namespace: scan
    spec:
      # 방법 1: Secret에서 직접 참조
      secretTargetRef:
      - parameter: host
        name: rabbitmq-secret
        key: connection-string
    
      # 방법 2: 개별 파라미터
      # secretTargetRef:
      # - parameter: username
      #   name: rabbitmq-secret
      #   key: username
      # - parameter: password
      #   name: rabbitmq-secret
      #   key: password

    4. 스케일링 계산 예시

    ┌─────────────────────────────────────────────────────────────────┐
    │              RabbitMQ 스케일링 계산 예시                          │
    ├─────────────────────────────────────────────────────────────────┤
    │                                                                  │
    │  설정:                                                           │
    │    mode: QueueLength                                            │
    │    value: 5 (Pod당 목표 메시지 수)                              │
    │    minReplicaCount: 0                                           │
    │    maxReplicaCount: 10                                          │
    │                                                                  │
    │  상황 1: 큐에 메시지 0개                                        │
    │  ─────────────────────────                                       │
    │    desiredReplicas = ceil(0 / 5) = 0                            │
    │    결과: 0개 Pod (scale-to-zero)                                │
    │                                                                  │
    │  상황 2: 큐에 메시지 15개                                       │
    │  ──────────────────────────                                      │
    │    desiredReplicas = ceil(15 / 5) = 3                           │
    │    결과: 3개 Pod                                                │
    │                                                                  │
    │  상황 3: 큐에 메시지 100개                                      │
    │  ───────────────────────────                                     │
    │    desiredReplicas = ceil(100 / 5) = 20                         │
    │    결과: 10개 Pod (maxReplicaCount 제한)                        │
    │                                                                  │
    │  상황 4: 큐에 메시지 2개                                        │
    │  ──────────────────────────                                      │
    │    desiredReplicas = ceil(2 / 5) = 1                            │
    │    결과: 1개 Pod (최소 1개, 메시지 있으므로)                    │
    │                                                                  │
    └─────────────────────────────────────────────────────────────────┘

    5. QueueLength vs MessageRate

    모드 메트릭 용도
    QueueLength 큐에 쌓인 메시지 수 배치 처리, 백로그 처리
    MessageRate 초당 메시지 발행/소비율 실시간 스트리밍, 일정한 처리율 유지
    # QueueLength 모드
    triggers:
    - type: rabbitmq
      metadata:
        mode: QueueLength
        value: "5"           # Pod당 5개 메시지 처리
    
    # MessageRate 모드
    triggers:
    - type: rabbitmq
      metadata:
        mode: MessageRate
        value: "100"         # Pod당 초당 100개 메시지 처리

    스케일링 알고리즘 상세

    1. KEDA + HPA 통합 알고리즘

    ┌─────────────────────────────────────────────────────────────────┐
    │              KEDA 스케일링 알고리즘                               │
    ├─────────────────────────────────────────────────────────────────┤
    │                                                                  │
    │  Phase 1: 메트릭 수집 (pollingInterval 주기)                    │
    │  ─────────────────────────────────────────                       │
    │  각 트리거에서 메트릭 값 조회                                    │
    │  예: rabbitmq.GetMetrics() → 150 (큐 길이)                      │
    │                                                                  │
    │  Phase 2: IsActive 판단                                          │
    │  ──────────────────────                                          │
    │  메트릭 > activationValue → true (스케일링 필요)                │
    │  메트릭 ≤ activationValue → false (유휴 상태)                   │
    │                                                                  │
    │  Phase 3: Scale-to-Zero 처리 (Operator)                         │
    │  ─────────────────────────────────────                           │
    │  if (!IsActive && currentReplicas > 0) {                        │
    │      cooldownPeriod 대기 후 replicas = 0                        │
    │  }                                                               │
    │  if (IsActive && currentReplicas == 0) {                        │
    │      replicas = 1 (즉시)                                        │
    │  }                                                               │
    │                                                                  │
    │  Phase 4: HPA 스케일링 (1 ↔ maxReplicas)                        │
    │  ──────────────────────────────────────                          │
    │  HPA가 external.metrics.k8s.io에서 메트릭 조회                  │
    │  desiredReplicas = ceil(currentMetric / targetMetric)           │
    │  Deployment.replicas 조정                                        │
    │                                                                  │
    └─────────────────────────────────────────────────────────────────┘

    2. 수식 상세

    단일 트리거:

    [
    \text{desiredReplicas} = \lceil \frac{\text{currentMetricValue}}{\text{targetMetricValue}} \rceil
    ]

    다중 트리거:

    [
    \text{desiredReplicas} = \max(\text{desiredReplicas}_1, \text{desiredReplicas}_2, ..., \text{desiredReplicas}_n)
    ]

    예시 (다중 트리거):

    triggers:
    - type: rabbitmq
      metadata:
        queueName: scan_queue
        value: "5"              # 목표: Pod당 5개
    - type: prometheus
      metadata:
        query: http_requests_total
        threshold: "100"        # 목표: Pod당 100 RPS
    큐 메시지: 30개 → desiredReplicas_rabbitmq = ceil(30/5) = 6
    HTTP RPS: 250   → desiredReplicas_prometheus = ceil(250/100) = 3
    
    최종: max(6, 3) = 6 Pods

    3. Stabilization Window

    급격한 스케일 변동을 방지하기 위한 안정화 기간:

    advanced:
      horizontalPodAutoscalerConfig:
        behavior:
          scaleDown:
            stabilizationWindowSeconds: 300    # 5분
            policies:
            - type: Percent
              value: 10
              periodSeconds: 60                # 분당 최대 10% 감소
          scaleUp:
            stabilizationWindowSeconds: 0      # 즉시 스케일 업
            policies:
            - type: Pods
              value: 4
              periodSeconds: 60                # 분당 최대 4개 증가
    ┌─────────────────────────────────────────────────────────────────┐
    │              Stabilization Window 동작                            │
    ├─────────────────────────────────────────────────────────────────┤
    │                                                                  │
    │  시간 ────────────────────────────────────────────────────────► │
    │                                                                  │
    │  계산된 replicas                                                 │
    │                                                                  │
    │       10  ──────┐                                                │
    │                 │                                                │
    │        6  ──────┼──────┐                                         │
    │                 │      │                                         │
    │        3  ──────┼──────┼──────────────────────────────────       │
    │                 │      │                                         │
    │                 │      │                                         │
    │                 │◄────►│ stabilizationWindowSeconds             │
    │                 │      │                                         │
    │                 │      └─ 실제 스케일 다운 시점                   │
    │                 │                                                │
    │                 └─ 스케일 다운 요청 시점                          │
    │                                                                  │
    │  Window 기간 중 가장 높은 값으로 유지                            │
    │  → 스파이크 후 급격한 스케일 다운 방지                          │
    │                                                                  │
    └─────────────────────────────────────────────────────────────────┘

    운영 고려사항

    1. Scale-to-Zero 동작

    ┌─────────────────────────────────────────────────────────────────┐
    │              Scale-to-Zero 동작 상세                              │
    ├─────────────────────────────────────────────────────────────────┤
    │                                                                  │
    │  ┌─────────────────────────────────────────────────────────────┐│
    │  │                    0 Replicas                                ││
    │  │                        │                                     ││
    │  │  이벤트 감지 ──────────┤                                     ││
    │  │  (pollingInterval)    │                                     ││
    │  │                        ▼                                     ││
    │  │              ┌─────────────────┐                            ││
    │  │              │ KEDA Operator가 │                            ││
    │  │              │ replicas = 1    │                            ││
    │  │              └────────┬────────┘                            ││
    │  │                       │                                      ││
    │  │                       ▼                                      ││
    │  │              ┌─────────────────┐                            ││
    │  │              │ Pod 생성 (콜드  │                            ││
    │  │              │ 스타트 지연)    │                            ││
    │  │              └────────┬────────┘                            ││
    │  │                       │                                      ││
    │  │                       ▼                                      ││
    │  │              ┌─────────────────┐                            ││
    │  │              │ HPA 활성화      │                            ││
    │  │              │ (1↔maxReplicas) │                            ││
    │  │              └─────────────────┘                            ││
    │  │                                                              ││
    │  └─────────────────────────────────────────────────────────────┘│
    │                                                                  │
    │  주의사항:                                                       │
    │  ─────────                                                       │
    │  • 콜드 스타트 지연: Pod 생성 + 컨테이너 시작 + 초기화          │
    │  • 지연 허용 불가 시: idleReplicaCount 또는 minReplicaCount ≥ 1│
    │                                                                  │
    └─────────────────────────────────────────────────────────────────┘

    2. 콜드 스타트 최적화

    방법 설명
    idleReplicaCount 유휴 시에도 지정 수 Pod 유지
    이미지 프리풀 노드에 이미지 미리 캐시
    Init 컨테이너 최적화 의존성 초기화 시간 단축
    PodDisruptionBudget 최소 가용 Pod 보장

    3. 메트릭 지연 고려

    ┌─────────────────────────────────────────────────────────────────┐
    │              메트릭 지연과 스케일링 타이밍                        │
    ├─────────────────────────────────────────────────────────────────┤
    │                                                                  │
    │  시간 흐름:                                                      │
    │                                                                  │
    │  T+0s   : 메시지 100개 유입                                     │
    │  T+15s  : KEDA 메트릭 조회 (pollingInterval)                    │
    │  T+15s  : HPA 메트릭 조회                                       │
    │  T+16s  : HPA가 스케일 결정                                     │
    │  T+20s  : 새 Pod 스케줄링                                       │
    │  T+30s  : 컨테이너 시작                                         │
    │  T+45s  : Pod Ready, 메시지 처리 시작                           │
    │                                                                  │
    │  총 지연: ~45초                                                  │
    │                                                                  │
    │  최적화:                                                         │
    │  ─────────                                                       │
    │  • pollingInterval 감소 (예: 5초)                               │
    │  • 선제적 스케일링 (예: activationValue < threshold)            │
    │  • idleReplicaCount로 워밍업된 Pod 유지                         │
    │                                                                  │
    └─────────────────────────────────────────────────────────────────┘

    4. Prometheus 메트릭 모니터링

    KEDA가 노출하는 Prometheus 메트릭:

    # Operator 메트릭
    keda_scaler_active{namespace, scaledObject, scaler}        # 스케일러 활성 상태
    keda_scaler_metrics_value{namespace, scaledObject, scaler} # 현재 메트릭 값
    keda_scaled_object_errors{namespace, scaledObject}         # 에러 횟수
    
    # Metrics Server 메트릭
    keda_metrics_adapter_scaler_metrics_value{...}             # 어댑터가 제공하는 메트릭
    
    # 예시 쿼리
    # 스케일러별 현재 메트릭 값
    keda_scaler_metrics_value{namespace="scan", scaledObject="scan-worker-scaledobject"}
    
    # 에러 발생 추이
    rate(keda_scaled_object_errors[5m])

    5. 트러블슈팅 체크리스트

    ┌─────────────────────────────────────────────────────────────────┐
    │              KEDA 트러블슈팅 체크리스트                           │
    ├─────────────────────────────────────────────────────────────────┤
    │                                                                  │
    │  ☐ ScaledObject 상태 확인                                       │
    │     kubectl get scaledobject -n {namespace}                     │
    │     kubectl describe scaledobject {name} -n {namespace}         │
    │                                                                  │
    │  ☐ HPA 자동 생성 확인                                           │
    │     kubectl get hpa -n {namespace}                              │
    │                                                                  │
    │  ☐ KEDA Operator 로그 확인                                      │
    │     kubectl logs -n keda deployment/keda-operator               │
    │                                                                  │
    │  ☐ Metrics Server 로그 확인                                     │
    │     kubectl logs -n keda deployment/keda-metrics-apiserver      │
    │                                                                  │
    │  ☐ External Metrics API 직접 조회                               │
    │     kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1/   │
    │         namespaces/{ns}/{metric-name}"                          │
    │                                                                  │
    │  ☐ TriggerAuthentication 검증                                   │
    │     kubectl get triggerauthentication -n {namespace}            │
    │     kubectl describe triggerauthentication {name} -n {namespace}│
    │                                                                  │
    │  ☐ RabbitMQ Management API 직접 확인                            │
    │     curl -u guest:guest http://rabbitmq:15672/api/queues        │
    │                                                                  │
    └─────────────────────────────────────────────────────────────────┘

    다른 스케일러 개요

    KEDA는 60개 이상의 스케일러를 지원한다. 주요 스케일러:

    스케일러 메트릭 용도
    rabbitmq 큐 길이, 메시지율 메시지 큐 기반 워커
    redis-streams Pending 메시지 수, Consumer Lag 스트림 처리
    kafka Consumer Lag 이벤트 스트리밍
    prometheus PromQL 쿼리 결과 커스텀 메트릭
    aws-sqs ApproximateNumberOfMessages AWS 메시지 큐
    azure-servicebus 메시지 수 Azure 메시지 큐
    cron Cron 스케줄 시간 기반 스케일링
    cpu/memory 리소스 사용률 기본 리소스 기반

    References

    공식 문서

    Kubernetes 문서


    버전 정보

    • 작성일: 2025-12-26
    • KEDA 버전: 2.16.0
    • Kubernetes 버전: 1.28+

    댓글

ABOUT ME

🎓 부산대학교 정보컴퓨터공학과 학사: 2017.03 - 2023.08
☁️ Rakuten Symphony Jr. Cloud Engineer: 2024.12.09 - 2025.08.31
🏆 2025 AI 새싹톤 우수상 수상: 2025.10.30 - 2025.12.02
🌏 이코에코(Eco²) 백엔드/인프라 고도화 중: 2025.12 - Present

Designed by Mango