배경: 기본 동작이 왜 종종 실무에 안 맞는가
오늘 다룰 건 하나다. HorizontalPodAutoscaler(HPA) behavior 필드. 이거 모르는 사람 의외로 많아서 짧게 정리해둔다.
우리 팀 클러스터에서는 오전 10시부터 트래픽이 슬금슬금 올라오는 서비스가 하나 있다. 점심 직후에 잠깐 훅 떨어졌다가 오후에 다시 올라온다. 그런데 HPA를 별다른 설정 없이 켜두면 12시 30분쯤 replica가 4→2로 급격히 떨어졌다가, 13시가 되면 또 CPU가 튀면서 부랴부랴 다시 올린다. 이게 하루에 두세 번씩 반복되니 pod 재기동이 잦아지고 P99가 흔들린다.
원인은 기본 stabilization window. 지금 HPA v2 기본값은 scaleDown이 300초, scaleUp이 0초다. 5분짜리 쿨다운으로는 점심 트래픽 dip을 못 걸러낸다.
behavior 필드 최소 세팅
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-api
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-api
minReplicas: 3
maxReplicas: 30
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
behavior:
scaleDown:
stabilizationWindowSeconds: 600
policies:
- type: Percent
value: 25
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 30
- type: Pods
value: 4
periodSeconds: 30
selectPolicy: Max
포인트는 세 가지다.
scaleDown.stabilizationWindowSeconds: 600— 10분간 "낮은 replica 추천"이 지속돼야 실제로 축소한다. 점심 dip 정도는 무시된다.scaleDown.policies의 Percent 25% + periodSeconds 60 — 한 번에 전체의 25% 이상 안 줄인다. 10대짜리 pod이 한꺼번에 2대로 떨어지는 사태 방지.scaleUp은 반대로 공격적이다. 안정화 창 0초에 두 정책(100%, 4대) 중 큰 값(selectPolicy: Max) 채택. 부하가 튀면 즉시 대응.
실제 값은 서비스마다 다르다
600초가 만능은 아니다. 배치성 트래픽 서비스는 900~1200초까지도 늘려두고, 완전히 스파이키한 실시간 API는 300초 유지가 낫다. 처음부터 정확한 값을 노리기보다는 일주일치 replica 그래프를 봤을 때 "톱니처럼 왔다갔다"하는 게 사라지는 값을 찾는 쪽이 빠르다.
한 가지 사이드 노트. 최근 오토스케일링 관련 글들 다시 뒤져봤는데, 대부분 "aggressive up, conservative down" 패턴을 기본값으로 밀고 있더라. 즉 위 세팅이 요즘의 표준 감각이라고 봐도 무방하다.
확인은 이렇게
바뀌었는지 확인은 이벤트로 보자.
kubectl describe hpa my-api | tail -30
ScalingActive, AbleToScale 조건에 이유가 찍히고, 마지막에 최근 스케일 이벤트가 나온다. 여기서 "recommendation held stable for 10m0s" 같은 문구가 보이면 stabilization window가 실제로 붙잡고 있는 거다.
혹시 다른 값 쓰시는 분 있으면 어떻게 튜닝했는지 궁금하다. 특히 KEDA 같이 얹어 쓸 때 behavior 필드 우선순위가 어떻게 되는지도 다음에 한 번 파봐야겠다.
'IT > Kubernets' 카테고리의 다른 글
| Karpenter vs Cluster Autoscaler, 우리 팀은 왜 Karpenter로 갔나 (0) | 2026.07.30 |
|---|---|
| CoreDNS 죽지도 않았는데 DNS가 느려서 새벽에 깬 이야기 (0) | 2026.07.29 |
| KEDA로 Kafka consumer lag 오토스케일링, 이것만은 알고 시작하자 (0) | 2026.07.24 |
| kubectl debug --profile, 이거 모르면 매번 privileged 파드 만들고 있는 거다 (0) | 2026.07.20 |
| cert-manager 무한 재발급 루프에 걸린 새벽 이야기 (0) | 2026.07.19 |