먼저 HPA(HorizontalPodAutoscaler)는 아래와 같은 매니페스트 예시로 생성할 수 있다.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
...
spec:
minReplicas: 2
maxReplicas: 4
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: sample-deployment
metrics:
- type: Resource
resource:
name: cpu
target:
averageUtilization: 60
type: Utilization
behavior:
scaleUp:
stabilizationWindowSeconds: 120
policies:
- periodSeconds: 15
type: Pods
value: 4
- periodSeconds: 15
type: Percent
value: 100
selectPolicy: Max
scaleDown:
stabilizationWindowSeconds: 600
policies:
- periodSeconds: 15
type: Percent
value: 50
selectPolicy: Max
설정 항목 중에 metrics 와 behavior 에 대해 자세히 알아본다.
1. metrics
metrics 는 오토스케일링이 수행되는 임계치를 설정하는 항목이다. metrics[].resource.name 항목에는 cpu 또는 memory 가 올 수 있지만, 실제로 애플리케이션에서 memory 는 부하에 따라 증감하지 않고 상시 일정량을 점유하기 때문에 잘 쓰이지 않는다. metrics[].resource.target.averageUtilization 은 임계치가 될 파드 평균 cpu 사용률을 의미하는데, 그 기준은 파드의 spec.containers[].resources.requests.cpu 항목이 된다. 말이 좀 어려운데, 아래 표의 예시를 살펴보자
| spec.containers[].resources.requests.cpu (pod) |
averageUtilization(HPA) | cpu 사용률 기준 | 스케일링 동작 |
| 100m | 70 | 100밀리코어를 100% 로 취급 | scale out : 파드의 평균 CPU 사용률 70% 초과시 scale in: 파드의 평균 CPU 사용률 70% 미만시 |
| 500m | 80 | 500밀리코어를 100%로 취급 | scale out : 파드의 평균 CPU 사용률 80% 초과시 scale in: 파드의 평균 CPU 사용률 80% 미만시 |
이때, 스케일링 이후의 desired 한 파드 갯수는 아래 계산 공식을 따른다.
스케일링 이후 파드의 수 = ceil(현재 파드 수 * (파드 평균 cpu 사용률 / HPA cpu 임계치))
예를 들어 아래와 같은 상황이라고 하자
| HPA cpu 임계치(averageUtilization) | 현재 파드 수 | 파드 평균 cpu 사용률 |
| 50 | 4 | 70 |
파드 평균 cpu 사용률(70%)이 임계치(50%)를 초과했으므로 스케일 아웃이 일어날테고, 스케일링 후의 파드 갯수는 아래와 같다.
4 * (70/50) = 5.6
=> 올림처리하여 6
다음과 같은 상황에는 scale in 이 일어난다.
| HPA cpu 임계치(averageUtilization) | 현재 파드 수 | 파드 평균 cpu 사용률 |
| 50 | 4 | 20 |
4 * (20/50) = 1.6
=> 올림처리하여 2
물론, 스케일링 되더라도 minReplicas ~ maxReplicas 범위를 벗어날 수 없다.
2. behavior
behavior 은 스케일링의 상세 동작을 설정하는 항목이다. behavio 하위의 scaleUp 과 scaleDown 은 아래와 같은 항목이다.
| 항목 | 설명 |
| scaleUp | 스케일 아웃 동작 상세설정. 항목명이 scaleUp 임에 유의 |
| scaleDown | 스케일 인 동작 상세설정. 항목명이 scaleDown 임에 유의 |
scaleUp, scaleDown 각 하위로는 아래와 같은 항목을 지정할 수 있다.
| 항목 | 설명 | 예시 | |
| stabilizationWindowSeconds | 스케일링을 위해 metrics 조건에 부합한 채 유지해야 하는 시간(초) | averageUtilization: 60 / scaleUp.stabilizationWindowSeconds: 120 인 경우, 파드 평균 cpu 사용률이 120초간 60%를 초과해야 스케일 아웃 수행됨 |
|
| policies[] | periodSeconds | 스케일링 갯수 제한 주기(초) | periodSeconds: 15 type: Pods value: 2 => 15초마다 최대 2개의 파드를 스케일링할 수 있음 --- periodSeconds: 20 type: Percent value: 100 => 20초마다 최대 "현재 파드 갯수"의 100% 만큼의 파드를 스케일링 할 수 있음 |
| type | 제한 방식 - Pods: 파드 갯수 지정 제한 - Percent: 현재 파드 기준 % 제한 |
||
| value | 제한 값 | ||
| selectPolicy | polices 가 여러개일 때 선택 방식 - Max: 가장 큰 숫자를 선택 - Min: 가장 작은 숫자를 선택 |
scaleUp: policies: - periodSeconds: 15 type: Pods value: 4 - periodSeconds: 15 type: Percent value: 100 selectPolicy: Max => 현재 파드 갯수가 2개인 경우라면, 첫번째 정책을 선택(4개) => 현재 파드 갯수가 5개인 경우라면, 두번째 정책을 선택(5개) |
|
위와 같이 정리할 수 있지만, selectPolicy 의 동작에 대해서 의문이 든다. periodSeconds 가 동일하면 쉽게 계산할 수 있지만, 다르다면 어떤 기준으로 선택할까?
이는 쿠버네티스의 제어 루프 주기가 도달하는 시점이 스케일링 갯수 계산 시점이라는 점을 생각해야 한다. 마스터 노드에는 kube-controller-manager 가 존재하는데, 이 안에 HPA 컨트롤러가 포함된다. HPA 컨트롤러가 주기적으로(기본 15초) cpu 상태와 스케일링 정책을 계산하여 스케일링을 수행한다. 이 계산 시점 기준으로 각 policies 의 의해 스케일링 가능한 갯수를 산출하고, selectPolicy 에 따라 최대 or 최소 갯수를 선택한다.
예를 들어, 제어 루프 주기가 도달하여 파드 스케일링 갯수 계산공식에 의해 2 -> 10개로 스케일 아웃 갯수가 정해졌다. selectPolicy: Max 이며, behavior.scaleUp.polices 정책은 2개가 있고, 아래와 같다.
- 15초 정책: 이번 주기(15초)에 늘릴 수 있는 남은 갯수가 4개
- 60초 정책: 이번 주기(60초)에 늘릴 수 있는 남은 갯수가 10개
60초 정책이 더 많은 갯수(10개)를 늘릴 수 있으므로 선택된다.
3. HPA 동작 매커니즘
HPA 를 사용하다보면 stabilizationWindowSeconds 가 동일하더라도 cpu 사용률이 임계치를 넘어가는 시점과 실제 스케일링이 일어나는 시점의 차이가 매번 다르다고 느끼게 된다. 이는 HPA 의 동작 매커니즘에 따른 현상인데, 결론만 말하자면 여러 컴포넌트나 오브젝트가 각각 자원 사용량이나 임계값을 확인하는 주기와 관계가 있다. 아래는 그 모식도이다.

| 주체 | 대상 | 가져오는 정보 | 주기(초) |
| kubelet | container runtime | cpu/memory 사용량 | 10 |
| metrics-server | kubelet | cpu/memory 사용량 | 60 |
| kube-controller-manager | metrics-server | cpu/memory 사용량 | 15 |
| HPA | 스케일링 임계값 |
이에 따라서 운이 좋으면 실제 cpu 사용량이 임계값을 넘는 순간 바로 스케일링이 시작되겠지만, 운이 안좋으면 최대 85초 후 시작된다.
'Kubernetes' 카테고리의 다른 글
| [Kubernetes] Pod 상태 체크를 위한 Probe 의 이해 (0) | 2026.05.01 |
|---|---|
| [Kubernetes] 리소스별 selector 정리 (0) | 2026.04.26 |
| [Kubernetes] 오브젝트 라벨링 및 네이밍 가이드 (0) | 2026.04.26 |
| [Kubernetes] 리소스, 오브젝트, 컨트롤러, 컴포넌트 용어 차이 (0) | 2026.03.24 |
| [Kubernetes] 컨테이너의 volumeMounts 옵션 항목 종류 (0) | 2026.03.03 |