HPA를 붙였더니 Pod 수가 3 → 6 → 3 → 5처럼 몇 분 단위로 출렁입니다. 이렇게 늘었다 줄었다를 반복하는 걸 플래핑(flapping) 이라고 합니다. 스케일이 바뀔 때마다 새 Pod 기동·종료 비용이 들고, 워밍업이 끝나기 전에 다시 죽어 오히려 지연이 커집니다. 원인은 대부분 "지표가 임계값 근처에서 진동"하거나 "스케일 다운이 너무 공격적"이라서입니다.
먼저 무엇이 흔들리는지 본다
Kubernetes
# 현재 타깃 지표와 레플리카 추이
kubectl get hpa web-hpa --watch
# 스케일 이벤트 기록 (언제·왜 바뀌었나)
kubectl describe hpa web-hpa
describe의 Events에 New size: 6; reason: cpu resource utilization above target처럼 변경 사유가 남습니다. CPU가 목표값(예: 50%) 바로 위아래에서 진동한다면 전형적인 플래핑입니다.
원인과 대응
| 증상 | 원인 | 대응 |
|---|---|---|
| 분 단위로 오르내림 | 스케일 다운이 즉시 일어남 | scaleDown stabilizationWindow 확대 |
| 지표가 임계값 근처 진동 | 타깃 사용률이 실사용과 너무 가까움 | 타깃을 60~70%로 여유있게 |
| 한 번에 많이 늘었다 줆 | 스텝 폭 제한 없음 | behavior policies로 변경폭 제한 |
behavior로 안정화
autoscaling/v2의 behavior 필드로 스케일 업/다운 속도를 따로 제어합니다. 핵심은 스케일 다운을 천천히 가져가는 것입니다.
YAML
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 65
behavior:
scaleDown:
stabilizationWindowSeconds: 300 # 5분간 최댓값 유지 후에만 축소
policies:
- type: Pods
value: 1 # 한 번에 1개씩만 줄임
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0 # 부하 급증엔 즉시 대응
policies:
- type: Percent
value: 100
periodSeconds: 30
scaleDown의 stabilizationWindowSeconds: 300이 가장 효과가 큽니다. HPA는 이 창 안의 권장값 중 가장 큰 값을 채택하므로, 잠깐 부하가 빠져도 5분은 줄이지 않고 버팁니다.
체크리스트
Kubernetes
# 1. metrics-server가 정상이어야 지표가 흔들리지 않음
kubectl top pods
# 2. 타깃 사용률이 실사용보다 충분히 높은지
kubectl describe hpa web-hpa | grep -i target
# 3. behavior 적용 후 추이 관찰
kubectl get hpa web-hpa --watch
타깃을 너무 낮게(30%) 잡으면 작은 부하에도 반응해 진동합니다. 안정화 창과 여유 있는 타깃을 함께 쓰는 게 핵심입니다.
HPA에 부하를 주고 behavior 정책을 바꿔가며 플래핑이 잦아드는 과정을 직접 관찰하는 실습은 쿠버네티스 트랙에서 회원가입 없이 무료로 해볼 수 있습니다.