KEDA 시리즈 2 - ScaledObject/ScaledJob 사용법

2026년 03월 01일

devops

# Kubernetes# KEDA# Autoscaling# Kafka# DevOps

이전: KEDA 시리즈 1 - 개념과 아키텍처


ScaledObject 기본 구조

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: my-scaledobject
spec:
  scaleTargetRef:
    name: my-deployment       # 스케일 대상 Deployment 이름
  minReplicaCount: 0          # 최소 Pod 수 (0이면 scale-to-zero)
  maxReplicaCount: 10         # 최대 Pod 수
  pollingInterval: 30         # 메트릭 폴링 주기 (초)
  cooldownPeriod: 300         # scale-to-zero 전 대기 시간 (초)
  triggers:
    - type: <scaler-type>
      metadata:
        # scaler별 설정

주요 필드 설명

  • minReplicaCount: 0: 이벤트가 없을 때 Pod를 완전히 제거. 비용 절감에 효과적
  • pollingInterval: 외부 소스를 얼마나 자주 확인할지. 낮을수록 반응 빠르지만 API 호출 증가
  • cooldownPeriod: 마지막 이벤트 이후 scale-to-zero까지 기다리는 시간. 너무 짧으면 cold start가 잦아짐

Scaler 예제

1. Kafka Scaler

Kafka consumer group의 lag을 기반으로 스케일링합니다.

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: kafka-consumer-scaler
spec:
  scaleTargetRef:
    name: kafka-consumer
  minReplicaCount: 1
  maxReplicaCount: 20
  triggers:
    - type: kafka
      metadata:
        bootstrapServers: kafka-broker:9092
        consumerGroup: my-consumer-group
        topic: my-topic
        lagThreshold: "100"         # lag이 100을 넘으면 Pod 추가
        offsetResetPolicy: latest

스케일링 계산 방식:

목표 Pod 수 = ceil(현재 lag / lagThreshold)

lag = 5000, lagThreshold = 100 → 50 Pod (maxReplicaCount에 의해 제한)
lag = 0                        → minReplicaCount (또는 0)

인증이 필요한 경우 (SASL/TLS):

apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
  name: kafka-trigger-auth
spec:
  secretTargetRef:
    - parameter: sasl
      name: kafka-secret
      key: sasl
    - parameter: username
      name: kafka-secret
      key: username
    - parameter: password
      name: kafka-secret
      key: password
---
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: kafka-consumer-scaler
spec:
  scaleTargetRef:
    name: kafka-consumer
  triggers:
    - type: kafka
      authenticationRef:
        name: kafka-trigger-auth    # TriggerAuthentication 참조
      metadata:
        bootstrapServers: kafka-broker:9092
        consumerGroup: my-consumer-group
        topic: my-topic
        lagThreshold: "100"
        sasl: plaintext
        tls: enable

2. HTTP Scaler

HTTP 요청 수를 기반으로 스케일링합니다. http-add-on 이라는 별도 KEDA 애드온이 필요합니다.

helm install http-add-on kedacore/keda-add-ons-http \
  --namespace keda
apiVersion: http.keda.sh/v1alpha1
kind: HTTPScaledObject
metadata:
  name: my-api-scaler
spec:
  host: my-api.example.com
  targetPendingRequests: 100      # Pod당 처리할 목표 요청 수
  scaleTargetRef:
    name: my-api
    port: 8080
  replicas:
    min: 0
    max: 10

HTTP Scaler는 트래픽을 KEDA HTTP Proxy를 통해 라우팅합니다. Ingress 설정을 KEDA Proxy Service로 변경해야 합니다.


3. Cron Scaler

트래픽 패턴이 예측 가능한 경우, 시간 스케줄에 맞춰 미리 Pod를 확장하거나 축소합니다. HPA나 Kafka Scaler는 부하가 실제로 올라온 뒤 반응하지만, Cron은 부하가 오기 전에 선제적으로 스케일업할 수 있습니다.

시나리오별 예제

시나리오 1 - 업무 시간 API 서버

평일 오전 출근 시간에 트래픽이 몰리는 서비스. 9시 이전에 미리 Pod를 늘려 cold start 없이 대응합니다.

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: office-hours-scaler
spec:
  scaleTargetRef:
    name: api-server
  minReplicaCount: 1
  maxReplicaCount: 10
  triggers:
    - type: cron
      metadata:
        timezone: Asia/Seoul
        start: "50 8 * * 1-5"    # 평일 8시 50분 (출근 10분 전) scale-up
        end: "0 19 * * 1-5"      # 평일 19시 scale-down
        desiredReplicas: "5"

시나리오 2 - 커머스 피크타임

점심(12-13시)과 저녁(18-20시)에 주문이 집중되는 쇼핑몰. 두 개의 Cron 트리거로 각 피크를 별도 처리합니다.

triggers:
  - type: cron
    metadata:
      timezone: Asia/Seoul
      start: "50 11 * * *"       # 11시 50분 scale-up
      end: "0 13 * * *"          # 13시 scale-down
      desiredReplicas: "8"
  - type: cron
    metadata:
      timezone: Asia/Seoul
      start: "50 17 * * *"       # 17시 50분 scale-up
      end: "0 20 * * *"          # 20시 scale-down
      desiredReplicas: "10"

시나리오 3 - 야간 배치 + 주간 scale-to-zero

주간에는 트래픽이 없고 새벽에만 배치를 실행하는 워커. 낮 동안 Pod를 0으로 유지해 비용을 절감합니다.

spec:
  minReplicaCount: 0             # 평소에는 Pod 없음
  maxReplicaCount: 5
  triggers:
    - type: cron
      metadata:
        timezone: Asia/Seoul
        start: "0 2 * * *"       # 새벽 2시 배치 시작
        end: "0 5 * * *"         # 새벽 5시 종료
        desiredReplicas: "3"

Cron + Kafka 조합 (멀티 트리거)

업무 시간에는 최소 Pod 수를 보장하면서, 이벤트가 몰릴 때는 추가로 확장합니다.

triggers:
  - type: cron
    metadata:
      timezone: Asia/Seoul
      start: "0 9 * * 1-5"
      end: "0 18 * * 1-5"
      desiredReplicas: "3"        # 업무 시간 최소 3개 보장
  - type: kafka
    metadata:
      bootstrapServers: kafka:9092
      consumerGroup: my-group
      topic: my-topic
      lagThreshold: "50"          # lag에 따라 추가 확장

멀티 트리거 시 KEDA는 각 트리거의 목표값 중 최댓값을 사용합니다. 업무 시간 외에 lag이 발생하면 Kafka Scaler가 단독으로 동작합니다.


ScaledJob

배치 작업처럼 이벤트 하나당 Job 하나를 실행하고 싶을 때 사용합니다.

apiVersion: keda.sh/v1alpha1
kind: ScaledJob
metadata:
  name: batch-job-scaler
spec:
  jobTargetRef:
    template:
      spec:
        containers:
          - name: batch-processor
            image: my-batch:latest
        restartPolicy: Never
  minReplicaCount: 0
  maxReplicaCount: 50
  triggers:
    - type: kafka
      metadata:
        bootstrapServers: kafka:9092
        consumerGroup: batch-group
        topic: batch-topic
        lagThreshold: "1"         # lag 1개당 Job 1개 실행
ScaledObject ScaledJob
대상 Deployment, StatefulSet Job
스케일 단위 Pod 수 조절 Job 개수 조절
사용 케이스 상시 실행 서비스 이벤트당 1회 처리 배치

상태 확인

# ScaledObject 상태 확인
kubectl get scaledobject
# NAME                   SCALETARGETKIND      SCALETARGETNAME   MIN   MAX   TRIGGERS   READY
# kafka-consumer-scaler  apps/v1.Deployment   kafka-consumer    1     20    kafka      True

# 현재 메트릭 값 확인
kubectl describe scaledobject kafka-consumer-scaler

# KEDA가 자동 생성한 HPA 확인
kubectl get hpa

READY: False 인 경우 이벤트 확인:

kubectl describe scaledobject <name>
# Events 섹션에서 오류 원인 확인

주의사항

1. scale-to-zero의 cold start

  • minReplicaCount: 0 설정 시 첫 이벤트 처리에 Pod 시작 시간만큼 지연 발생
  • 지연이 허용되지 않는 서비스는 minReplicaCount: 1 이상 유지

2. Kafka partition 수와 최대 Pod 수

  • Kafka consumer는 partition 수보다 많은 Pod를 띄워도 idle 상태
  • maxReplicaCount를 topic partition 수 이하로 설정

3. cooldownPeriod 조정

  • 너무 짧으면 이벤트가 간헐적일 때 Pod가 계속 뜨고 내려가는 flapping 발생
  • 기본값 300초(5분)에서 시작해서 워크로드 패턴에 맞게 조정

4. TriggerAuthentication 네임스페이스

  • TriggerAuthentication은 같은 네임스페이스의 ScaledObject만 참조 가능
  • 클러스터 전체에서 공유하려면 ClusterTriggerAuthentication 사용
© 2026, 미나리와 함께 만들었음