[AWS EKS] EKS Autoscaling 3 - KEDA(Kubernetes-based Event Driven Autoscaler)

주영·2025년 3월 8일
0

AWS EKS Workshop Study 3기

목록 보기
14/31

1. KEDA 개요

KEDA는 Kubernetes에서 이벤트 기반 오토스케일링을 지원하는 프레임워크입니다. 기존 HPA (Horizontal Pod Autoscaler)가 CPU 및 메모리와 같은 리소스 메트릭을 기반으로 스케일링을 수행하는 반면, KEDA는 특정 이벤트를 감지하여 Pod의 개수를 조정할 수 있습니다.

1.1 KEDA와 HPA의 차이점

비교 항목HPA (Horizontal Pod Autoscaler)KEDA (Kubernetes Event Driven Autoscaler)
기반 메트릭CPU, Memory 등의 리소스 사용률이벤트(Queue, DB, Cron 등)
Pod 스케일링특정 리소스 활용률 초과 시 확장특정 이벤트 발생 시 확장
Scale to Zero 지원❌ 지원하지 않음✅ 지원 (이벤트 없을 때 0으로 축소)
Metrics ServerKubernetes 기본 Metrics Server 사용KEDA Metrics Server 사용
설정 방식kubectl autoscale 또는 HPA 설정ScaledObject 리소스 활용

KEDA를 사용하면 특정 Queue의 메시지 수, Kafka 메시지 대기열 길이, Cron 스케줄 등의 이벤트를 기준으로 Pod의 개수를 자동으로 조정할 수 있습니다.

2. KEDA 설치 및 설정

KEDA는 Helm을 이용하여 간편하게 설치할 수 있습니다.

2.1 KEDA 설치

# 설치 전 기존 metrics-server 제공 Metris API 확인
kubectl get --raw "/apis/metrics.k8s.io" -v=6 | jq
kubectl get --raw "/apis/metrics.k8s.io" | jq
{
  "kind": "APIGroup",
  "apiVersion": "v1",
  "name": "metrics.k8s.io",
  ...


# KEDA 설치 : serviceMonitor 만으로도 충분할듯
# KEDA 설정값 작성 (keda-values.yaml)
cat <<EOT > keda-values.yaml
metricsServer:
  useHostNetwork: true

prometheus:
  metricServer:
    enabled: true
    port: 9022
    portName: metrics
    path: /metrics
    serviceMonitor:
      # Enables ServiceMonitor creation for the Prometheus Operator
      enabled: true
    podMonitor:
      # Enables PodMonitor creation for the Prometheus Operator
      enabled: true
  operator:
    enabled: true
    port: 8080
    serviceMonitor:
      # Enables ServiceMonitor creation for the Prometheus Operator
      enabled: true
    podMonitor:
      # Enables PodMonitor creation for the Prometheus Operator
      enabled: true
  webhooks:
    enabled: true
    port: 8020
    serviceMonitor:
      # Enables ServiceMonitor creation for the Prometheus webhooks
      enabled: true
EOT

# Helm 저장소 추가 및 업데이트
helm repo add kedacore https://kedacore.github.io/charts
helm repo update
# KEDA 설치
helm install keda kedacore/keda --version 2.16.0 --namespace keda --create-namespace -f keda-values.yaml

# KEDA 설치 확인
kubectl get crd | grep keda
kubectl get all -n keda
kubectl get validatingwebhookconfigurations keda-admission -o yaml
kubectl get podmonitor,servicemonitors -n keda
kubectl get apiservice v1beta1.external.metrics.k8s.io -o yaml

# CPU/Mem은 기존 metrics-server 의존하여, KEDA metrics-server는 외부 이벤트 소스(Scaler) 메트릭을 노출 
## https://keda.sh/docs/2.16/operate/metrics-server/
kubectl get pod -n keda -l app=keda-operator-metrics-apiserver

# Querying metrics exposed by KEDA Metrics Server
kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1" | jq
{
  "kind": "APIResourceList",
  "apiVersion": "v1",
  "groupVersion": "external.metrics.k8s.io/v1beta1",
  "resources": [
    {
      "name": "externalmetrics",
      "singularName": "",
      "namespaced": true,
      "kind": "ExternalMetricValueList",
      "verbs": [
        "get"
      ]
    }
  ]
}

3. KEDA 아키텍처 및 주요 컴포넌트

KEDA는 Kubernetes 클러스터 내에서 아래와 같은 주요 컴포넌트로 구성됩니다.

3.1 주요 컴포넌트


https://keda.sh/docs/2.10/concepts/

  1. KEDA Operator (Agent)

    • Kubernetes Deployment를 감지하고, 스케일 인/아웃을 수행합니다.
    • 필요하지 않을 때 Pod 개수를 0으로 조정합니다.
  2. KEDA Metrics Server

    • HPA가 이벤트 기반 메트릭을 읽을 수 있도록 메트릭 데이터를 제공합니다.
    • Kafka, RabbitMQ, AWS SQS, Azure Queue Storage 등의 이벤트 소스를 감지하고 메트릭을 생성합니다.
  3. Admission Webhooks

    • 잘못된 리소스 구성을 방지하고, 최적의 설정을 적용하도록 검증합니다.

4. KEDA Scalers 사용 예제 (Kafka 기반 트리거)

KEDA는 다양한 Scalers를 지원하며, 그중 하나인 Kafka 트리거를 예제로 살펴보겠습니다.

4.1 Kafka 기반 트리거 설정

아래 YAML 파일을 사용하여 Kafka 메시지 대기열 길이를 기반으로 자동 확장할 수 있습니다.

triggers:
- type: kafka
  metadata:
    bootstrapServers: kafka.svc:9092
    consumerGroup: my-group
    topic: test-topic
    lagThreshold: '5' # 스케일링을 트리거하는 평균 타겟 값(Default: 5, Optional)
    activationLagThreshold: '3' # 스케일러 활성화 기준
    offsetResetPolicy: latest
    allowIdleConsumers: false
    scaleToZeroOnInvalidOffset: false
    excludePersistentLag: false
    limitToPartitionsWithLag: false
    version: 1.0.0
    partitionLimitation: '1,2,10-20,31'
    sasl: plaintext
    tls: enable
    unsafeSsl: 'false'

위 설정을 적용하면, Kafka 대기열 길이가 5개 이상일 경우 Pod가 자동 확장됩니다.

5. KEDA를 활용한 Cron 기반 스케일링

다음은 특정 시간대에만 Pod를 활성화하는 Cron ScaledObject 설정 예제입니다.

# keda 네임스페이스에 디플로이먼트 생성
kubectl apply -f php-apache.yaml -n keda
kubectl get pod -n keda

# Cron 기반 ScaledObject 설정
# 매 정각(00,15,30,45분)에 Pod가 활성화되며, 5분 후에는 다시 0으로 축소됨
cat <<EOT > keda-cron.yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: php-apache-cron-scaled
spec:
  minReplicaCount: 0
  maxReplicaCount: 2  # Specifies the maximum number of replicas to scale up to (defaults to 100).
  pollingInterval: 30  # Specifies how often KEDA should check for scaling events
  cooldownPeriod: 300  # Specifies the cool-down period in seconds after a scaling event
  scaleTargetRef:  # Identifies the Kubernetes deployment or other resource that should be scaled.
    apiVersion: apps/v1
    kind: Deployment
    name: php-apache
  triggers:  # Defines the specific configuration for your chosen scaler, including any required parameters or settings
  - type: cron
    metadata:
      timezone: Asia/Seoul
      start: 00,15,30,45 * * * *
      end: 05,20,35,50 * * * *
      desiredReplicas: "1"
EOT

# ScaledObject 배포
kubectl apply -f keda-cron.yaml -n keda

# 그라파나 대시보드 추가 : 대시보드 상단에 namespace : keda 로 변경하기!
# KEDA 대시보드 Import : https://github.com/kedacore/keda/blob/main/config/grafana/keda-dashboard.json

# 모니터링
watch -d 'kubectl get ScaledObject,hpa,pod -n keda'
kubectl get ScaledObject -w

# ScaledObject 상태 확인
kubectl get ScaledObject,hpa,pod -n keda
kubectl get hpa -o jsonpath="{.items[0].spec}" -n keda | jq
...
"metrics": [
    {
      "external": {
        "metric": {
          "name": "s0-cron-Asia-Seoul-00,15,30,45xxxx-05,20,35,50xxxx",
          "selector": {
            "matchLabels": {
              "scaledobject.keda.sh/name": "php-apache-cron-scaled"
            }
          }
        },
        "target": {
          "averageValue": "1",
          "type": "AverageValue"
        }
      },
      "type": "External"
    }
  • 정각 전


  • 정각(Pod 활성화)


  • 5분 후(다시 0으로 축소)

6. KEDA 및 관련 리소스 삭제

# KEDA 및 deployment 등 삭제
kubectl delete ScaledObject -n keda php-apache-cron-scaled && kubectl delete deploy php-apache -n keda && helm uninstall keda -n keda
kubectl delete namespace keda

0개의 댓글