KEDA RabbitMQ 스케일링
KEDA(Kubernetes Event-Driven Autoscaling)를 사용하여 RabbitMQ 큐 길이 기반으로 Pod를 자동 확장하는 방법을 학습합니다.
KEDA란?
KEDA는 이벤트 기반으로 Kubernetes 워크로드를 자동 확장하는 오픈소스 프로젝트입니다.
KEDA 특징
- Scale to Zero: 이벤트가 없을 때 0으로 축소 (비용 절감)
- 다양한 Scaler: RabbitMQ, Azure Service Bus, Kafka, Prometheus 등 50+ scalers
- HPA 통합: 내부적으로 HPA를 생성하여 관리
- External Metrics: 외부 시스템의 메트릭 활용
사전 준비: KEDA 설치
Helm으로 KEDA 설치
# Helm repo 추가
helm repo add kedacore https://kedacore.github.io/charts
helm repo update
# KEDA 설치
helm install keda kedacore/keda --namespace keda --create-namespace
# KEDA 확인
kubectl get pods -n keda
또는 YAML로 설치:
kubectl apply -f https://github.com/kedacore/keda/releases/download/v2.12.0/keda-2.12.0.yaml
# KEDA 확인
kubectl get deployment -n keda
실습 1: RabbitMQ 배포
1. ConfigMap 생성
rabbit-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: rabbit-configmap
data:
RABBITMQ_DEFAULT_USER: guest
RABBITMQ_DEFAULT_PASS: guest
RABBITMQ_HOST: rabbit-svc
RABBITMQ_PORT: "5672"
QUEUE_NAME: SampleQueue
kubectl apply -f rabbit-cm.yaml
2. RabbitMQ Deployment
rabbit-dep.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: rabbit-dep
spec:
replicas: 1
selector:
matchLabels:
app: rabbit-pod
template:
metadata:
labels:
app: rabbit-pod
spec:
containers:
- name: rabbit-container
image: rabbitmq:3-management
ports:
- name: rabbit-ui
containerPort: 15672
- name: rabbit-port
containerPort: 5672
envFrom:
- configMapRef:
name: rabbit-configmap
resources:
requests:
cpu: 300m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
3. RabbitMQ Service
rabbit-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: rabbit-svc
spec:
selector:
app: rabbit-pod
ports:
- name: rabbit-ui
port: 15672
targetPort: 15672
- name: rabbit-port
port: 5672
targetPort: 5672
type: ClusterIP
kubectl apply -f rabbit-dep.yaml -f rabbit-svc.yaml
# RabbitMQ 준비 대기
kubectl wait --for=condition=ready pod -l app=rabbit-pod --timeout=180s
4. RabbitMQ UI 접근
# Port forward
kubectl port-forward svc/rabbit-svc 15672:15672
# 브라우저에서 http://localhost:15672 접근
# ID: guest, PW: guest
실습 2: Queue Processor 배포
1. Queue Processor Deployment
queue-processor.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: queue-processor-dep
spec:
replicas: 1
selector:
matchLabels:
app: queue-processor
template:
metadata:
labels:
app: queue-processor
color: OrangeRed
spec:
initContainers:
- name: queue-checker
image: scubakiz/queuechecker:latest
envFrom:
- configMapRef:
name: rabbit-configmap
containers:
- name: queue-processor
image: scubakiz/queueprocessor:latest
envFrom:
- configMapRef:
name: rabbit-configmap
env:
- name: MIN_SLEEP_INTERVAL
value: "10000" # 메시지당 10-15초 처리 (느린 처리)
- name: MAX_SLEEP_INTERVAL
value: "15000"
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 100m
memory: 128Mi
kubectl apply -f queue-processor.yaml
# Pod 확인
kubectl get pods -l app=queue-processor
실습 3: 메시지 로딩
1. Queue Loader Job
queue-loader-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: queue-loader-job
spec:
ttlSecondsAfterFinished: 30
template:
spec:
restartPolicy: Never
containers:
- name: queue-loader
image: scubakiz/queueloader:latest
envFrom:
- configMapRef:
name: rabbit-configmap
env:
- name: ITEMS_TO_QUEUE
value: "500" # 500개 메시지 생성
kubectl apply -f queue-loader-job.yaml
# Job 확인
kubectl get jobs
# RabbitMQ UI에서 SampleQueue 확인
# 약 500개 메시지가 큐에 쌓임
2. 느린 처리 관찰
# 메시지 처리 속도 관찰
kubectl logs -f deployment/queue-processor-dep
# RabbitMQ UI에서 큐 길이 확인
# 메시지가 천천히 감소함
1개 Pod로는 처리 속도가 느립니다.
실습 4: KEDA ScaledObject 배포
1. KEDA ScaledObject 생성
keda-rabbit.yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: keda-rabbit-so
spec:
scaleTargetRef:
kind: Deployment
name: queue-processor-dep
triggers:
- type: rabbitmq
metadata:
protocol: amqp
queueName: SampleQueue
mode: QueueLength
value: "10" # 메시지 10개당 Pod 1개
host: amqp://guest:guest@rabbit-svc.default.svc.cluster.local:5672
pollingInterval: 1 # 1초마다 확인
cooldownPeriod: 1 # 축소 전 1초 대기
minReplicaCount: 1 # 최소 1개
maxReplicaCount: 30 # 최대 30개
advanced:
restoreToOriginalReplicaCount: false
horizontalPodAutoscalerConfig:
behavior:
scaleUp:
stabilizationWindowSeconds: 1
policies:
- type: Percent
value: 100 # 100%까지 빠르게 증가
periodSeconds: 1
- type: Pods
value: 10 # 또는 10개씩 증가
periodSeconds: 1
selectPolicy: Max # 더 공격적인 정책 선택
scaleDown:
stabilizationWindowSeconds: 20
policies:
- type: Percent
value: 100
periodSeconds: 1
kubectl apply -f keda-rabbit.yaml
# ScaledObject 확인
kubectl get scaledobject
# HPA 자동 생성 확인
kubectl get hpa
2. 자동 스케일링 관찰
# Pod 증가 관찰
kubectl get pods -l app=queue-processor -w
# HPA 상태 확인
kubectl get hpa -w
# 메시지 길이 확인
kubectl describe scaledobject keda-rabbit-so
큐에 500개 메시지가 있으므로 약 50개(500/10) Pod가 생성됩니다 (maxReplicaCount=30으로 제한).
3. 빠른 처리 확인
# RabbitMQ UI에서 메시지 빠르게 감소 확인
# 많은 Pod가 병렬로 처리
# 로그 확인
kubectl logs -l app=queue-processor --tail=10
4. Scale Down 관찰
# 메시지가 모두 처리되면 Pod 감소
kubectl get pods -l app=queue-processor -w
# HPA 확인
kubectl get hpa -w
20초 stabilization 후 Pod가 감소하여 minReplicaCount(1)로 돌아갑니다.
실습 5: Scale to Zero
minReplicaCount를 0으로 설정:
keda-rabbit-zero.yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: keda-rabbit-so
spec:
scaleTargetRef:
kind: Deployment
name: queue-processor-dep
triggers:
- type: rabbitmq
metadata:
protocol: amqp
queueName: SampleQueue
mode: QueueLength
value: "10"
host: amqp://guest:guest@rabbit-svc.default.svc.cluster.local:5672
pollingInterval: 5
cooldownPeriod: 30
minReplicaCount: 0 # Scale to Zero
maxReplicaCount: 30
kubectl apply -f keda-rabbit-zero.yaml
# 메시지가 없으면 0으로 축소
kubectl get pods -l app=queue-processor -w
# 새 메시지 추가 시 자동으로 Pod 생성
kubectl apply -f queue-loader-job.yaml
AKS에서 KEDA 활용
Azure Service Bus Scaler
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: servicebus-scaler
spec:
scaleTargetRef:
name: my-deployment
triggers:
- type: azure-servicebus
metadata:
queueName: myqueue
namespace: myservicebus
messageCount: "5"
authenticationRef:
name: servicebus-auth
Azure Monitor Scaler
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: monitor-scaler
spec:
scaleTargetRef:
name: my-deployment
triggers:
- type: azure-monitor
metadata:
resourceURI: /subscriptions/.../resourceGroups/.../providers/...
metricName: Percentage CPU
targetValue: "70"
정리
kubectl delete scaledobject keda-rabbit-so
kubectl delete deployment queue-processor-dep rabbit-dep
kubectl delete service rabbit-svc
kubectl delete configmap rabbit-configmap
kubectl delete job queue-loader-job
# KEDA 제거 (선택)
helm uninstall keda -n keda
핵심 정리
- KEDA: 이벤트 기반 자동 확장
- ScaledObject: 스케일링 규칙 정의
- Scale to Zero: 비용 최적화
- RabbitMQ Scaler: 큐 길이 기반 스케일링
- HPA 통합: 내부적으로 HPA 생성
- 50+ Scalers: 다양한 이벤트 소스 지원
베스트 프랙티스
- 적절한 value 설정: 메시지당 처리 시간 고려
- minReplicaCount: 최소 가용성 보장 (0 또는 1)
- Stabilization Window: 불필요한 스케일링 방지
- 리소스 설정: 각 Pod의 Requests/Limits 명시
- 모니터링: ScaledObject 메트릭 추적
실습 과제
- value를 다르게 설정(5, 20, 50)하며 스케일링 동작을 관찰해보세요.
- Azure Service Bus를 사용하는 ScaledObject를 생성해보세요.
- 여러 개의 Trigger를 가진 ScaledObject를 만들어보세요.
- Prometheus Scaler를 사용하여 커스텀 메트릭 기반 스케일링을 구현해보세요.
다음 단계
KEDA Cron 스케일러에서 시간 기반 스케일링을 학습합니다.