본문으로 건너뛰기
버전: 1.0.4

3.5. 오토스케일링

어떨 때 보는가​

  • 부하가 몰리는 시간에 서비스가 느려질 때
  • 한가한 시간에 자원이 낭비될 때
  • 노드 점검 중에 서비스가 끊기지 않게 하고 싶을 때

자동 조절이 필요한 이유​

부하가 늘 때 파드 수를 손으로 늘리면 대응이 늦습니다. 반대로 한가한 시간에 많은 파드를 그대로 두면 자원이 낭비됩니다.

COP 는 두 가지 자동 조절 방식을 제공합니다.

방식판단 기준반응
HPA현재 CPU·메모리 사용률부하가 오른 뒤 늘립니다
CronHPA정해진 시각부하가 오르기 전에 늘립니다

HPA​

HPA(HorizontalPodAutoscaler)는 사용률을 보고 파드 수를 늘리거나 줄입니다.

워크로드 > 수평 자동 확장(HPA) 으로 들어갑니다.

HPA 목록
열설명
이름HPA 이름
대상조절할 Deployment 등
최소 · 최대파드 수의 하한과 상한
복제본현재 파드 수
지표현재 사용률 / 목표 사용률

동작 방식은 이렇습니다.

  1. 대상 파드들의 평균 사용률을 잽니다.
  2. 목표 사용률과 비교합니다.
  3. 필요한 파드 수 = 현재 파드 수 × (현재 사용률 ÷ 목표 사용률) 로 계산합니다.
  4. 최소·최대 범위 안에서 조절합니다.

예를 들어 파드 2개가 평균 80% 를 쓰고 목표가 50% 면, 2 × (80 ÷ 50) = 3.2 → 4개로 늘립니다.

줄일 때는 늘릴 때보다 천천히 움직입니다. 부하가 잠깐 내려갔다고 바로 줄이면 다시 늘려야 하므로, 일정 시간 낮은 상태가 이어져야 줄입니다.

HPA 를 쓰려면 자원 요청량이 있어야 합니다​

HPA 를 걸기 전에 대상 파드에 자원 요청량이 설정되어 있어야 합니다. 없으면 HPA 는 아무 일도 하지 않습니다. 이것이 HPA 가 동작하지 않는 가장 흔한 원인입니다.

왜 필요한가​

앞의 계산식에 나오는 "사용률" 은 요청량 대비 비율 입니다. 노드 전체 용량이나 상한이 아닙니다.

사용률 = 실제 사용량 ÷ 요청량 × 100

요청량이 분모입니다. 요청량이 없으면 분모가 없어 사용률 자체를 구할 수 없고, HPA 목록의 지표 열에 <unknown> 이 뜬 채로 멈춥니다.

요청량·상한이 무엇이고 어떻게 정하는지는 3.1 장에 있습니다. 여기서는 HPA 가 그 값을 어떻게 쓰는지만 봅니다.

계산 예 — COP 샘플 애플리케이션​

COP 가 넣어 주는 전자정부 샘플 애플리케이션의 실제 설정으로 따라가 보겠습니다.

항목값
CPU 상한2 (2 코어)
CPU 요청량별도로 정하지 않음 → 상한과 같은 2 가 자동으로 채워집니다(3.1 장)
HPA 최소 파드 수2
HPA 최대 파드 수4
HPA 목표 사용률75%

여기서 목표 75% 는 "파드 하나가 평균 1.5 코어를 쓰는 상태" 를 뜻합니다.

2 코어(요청량) × 75% = 1.5 코어

파드 2개가 각각 1.8 코어를 쓰고 있다고 하면 이렇게 됩니다.

단계계산
현재 사용률1.8 ÷ 2 × 100 = 90%
필요한 파드 수2 × (90 ÷ 75) = 2.4 → 올림 → 3개
최대 범위 확인3 은 최대 4 이내이므로 그대로 3개

늘어난 뒤에는 같은 부하가 3개로 나뉘므로 파드당 1.2 코어, 사용률 60% 가 되어 목표 아래로 내려갑니다. 부하가 계속 오르면 4개까지 늘고, 4개로도 90% 를 넘으면 더는 늘지 않습니다. 그때는 최대값을 올리거나 다른 병목을 찾아야 합니다.

요청량을 잘못 잡으면 생기는 일​

요청량은 배치에 쓰이는 값이면서 동시에 HPA 의 분모입니다. 한 값이 두 가지를 결정하므로 잘못 잡으면 양쪽이 함께 어긋납니다.

요청량배치에 미치는 영향HPA 에 미치는 영향
실제보다 크게노드에 파드가 몇 개 못 들어갑니다사용률이 낮게 나와 필요한데도 늘지 않습니다
실제보다 작게붐빌 때 밀려납니다사용률이 높게 나와 필요 없는데도 늘어납니다
없음자리를 잡지 않습니다HPA 가 동작하지 않습니다

예를 들어 요청량을 2 코어로 잡았는데 실제로는 0.2 코어밖에 쓰지 않는 애플리케이션이라면, 부하가 다섯 배로 뛰어 1 코어를 써도 사용률은 50% 라 목표 75% 에 못 미쳐 파드가 늘지 않습니다. 화면상 "HPA 는 정상인데 서비스는 느린" 상태가 됩니다.

실제 사용량을 먼저 재고 요청량을 정한 뒤 HPA 를 거십시오. 순서를 바꾸면 목표 사용률을 아무리 조절해도 맞지 않습니다.

메모리 기준으로 조절할 때​

메모리 사용률로도 조절할 수 있지만 CPU 만큼 잘 맞지 않습니다. 자바처럼 힙을 미리 잡아 두는 런타임은 실제로 놀고 있어도 메모리 사용량이 줄지 않아, 파드를 늘려도 사용률이 내려가지 않습니다. 그러면 최대치까지 계속 늘어납니다.

메모리는 상한을 제대로 잡는 쪽이 맞고, 자동 조절은 CPU 를 기준으로 하는 편이 안전합니다.

만들기 — YAML​

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
namespace: my-app
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 75 # 요청량 대비 75%
항목설명
scaleTargetRef조절할 대상. 이름이 틀리면 지표가 <unknown> 으로 남습니다
minReplicas바닥. 2 이상을 권장합니다 — 1 이면 조절 중에 서비스가 끊길 수 있습니다
maxReplicas천장. 클러스터가 감당할 수 있는 값으로 둡니다
averageUtilization목표 사용률. 요청량 기준 입니다(위 절)

오르내림이 잦으면 반응 속도를 조절합니다.

behavior:
scaleDown:
stabilizationWindowSeconds: 300 # 5분 동안 낮아야 줄입니다
scaleUp:
stabilizationWindowSeconds: 0 # 늘릴 때는 바로

줄이는 쪽만 늦추는 것이 요령입니다. 부하가 잠깐 내려갔다고 줄이면 곧 다시 늘려야 해 파드가 계속 오르내립니다.

HPA 가 동작하지 않을 때​

지표 열에 <unknown> 이 보이면 사용량을 읽지 못하는 상태입니다.

원인확인할 것
대상 파드에 자원 요청량이 없음가장 흔한 원인입니다. 파드 상세의 요청·제한을 봅니다(위 절)
지표 수집기가 동작하지 않음운영 담당자에게 문의
대상 이름이 틀림상세 화면의 대상이 실제 Deployment 이름과 같은지
파드가 방금 떴음첫 측정값이 모이기까지 1분 안팎 걸립니다. 잠시 뒤 다시 봅니다

<unknown> 이 아니라 숫자는 나오는데 파드가 늘지 않는 경우 는 원인이 다릅니다.

증상원인
사용률이 목표보다 낮게만 나온다요청량이 실제보다 크게 잡혀 있습니다(위 절)
최대값에 머물러 있다최대 파드 수가 부족하거나 다른 곳이 병목입니다
늘었는데 Pending 에 머문다클러스터에 자리가 없습니다. 노드 자원을 확인합니다(2.1 장)

최대까지 늘었는데도 느리면 파드 수 문제가 아닙니다. 데이터베이스나 외부 연동이 병목일 수 있으니 모니터링 화면에서 확인하십시오(9.2 장).

CronHPA​

CronHPA 는 시각 기준으로 파드 수를 바꿉니다. 부하가 오르기 전에 미리 준비할 때 씁니다.

워크로드 > Cron 자동 확장(CHPA) 에서 봅니다.

일정 표기가 CronJob 과 다릅니다. CronJob 은 다섯 자리인데 CronHPA 는 초를 포함한 여섯 자리 입니다. 3.3 장의 표기를 그대로 쓰면 자리가 하나 밀립니다.

CronHPA 일정 표기
특수문자뜻예
*모든 값0 0 * * * * = 매시 정각
/간격0 */10 * * * * = 10분마다
,목록0 0 9,18 * * * = 09:00 과 18:00
-범위0 0 9-18 * * * = 09:00 부터 18:00 까지 매시

이 밖에 정해진 일정 대신 쓸 수 있는 표기가 있습니다.

표기뜻
@hourly · @daily · @weekly · @monthly · @yearly매시 정각 · 매일 자정 · 매주 일요일 자정 · 매월 1일 자정 · 매년 1월 1일 자정
@every 1h30m1시간 30분마다
@date 2026-12-25 09:00:00그 날짜·시각에 한 번

@date 는 되풀이하지 않는 일정입니다. 행사나 이벤트처럼 날짜가 정해진 일에 씁니다.

어떨 때 쓰는가​

상황왜 CronHPA 인가
업무 시간에만 부하가 몰린다출근 전에 미리 늘려 둡니다. HPA 는 부하가 온 뒤에야 움직입니다
기동이 오래 걸린다자바 애플리케이션처럼 뜨는 데 수 분이 걸리면 HPA 로는 이미 늦습니다
정산·마감처럼 시각이 정해져 있다매월 말일, 매일 새벽 배치 시간에 맞춰 늘립니다
야간·주말에 자원을 줄이고 싶다개발·검증 환경에서 밤에 0 또는 1로 줄여 자원을 아낍니다
행사 일정이 정해져 있다@date 로 시작·종료 시각을 지정합니다
지표로는 부하를 못 읽는다큐 대기열처럼 CPU·메모리에 드러나지 않는 부하

HPA 가 잘 맞지 않는 자리를 메우는 것이 CronHPA 입니다. HPA 는 부하가 오른 뒤 반응하므로 급격히 몰리는 순간에는 이미 느려진 뒤에 늘어납니다.

기본 사용 — 업무 시간에 맞춰 조절​

가장 흔한 형태입니다. 평일 업무 시간에 늘리고 그 뒤 줄입니다.

apiVersion: autoscaling.openmaru.io/v1
kind: CronHPA
metadata:
name: app-cronhpa
namespace: my-app
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
jobs:
- name: scale-up-morning
schedule: "0 50 8 * * 1-5" # 평일 08:50:00
targetSize: 10
- name: scale-down-evening
schedule: "0 0 20 * * 1-5" # 평일 20:00:00
targetSize: 3
- name: weekend-minimum
schedule: "0 0 0 * * 6" # 토요일 00:00:00
targetSize: 2
항목설명
scaleTargetRef조절할 대상. apiVersion·kind·name 세 가지를 모두 적습니다
jobs일정 목록. 하나 이상이어야 합니다
jobs[].name이 CronHPA 안에서 겹치지 않는 이름. 상태 화면에 이 이름으로 나옵니다
jobs[].schedule언제 실행할지
jobs[].targetSize그때 맞출 파드 수. 0 도 넣을 수 있습니다

targetSize 는 "얼마나 늘릴지" 가 아니라 "몇 개로 맞출지" 입니다. 현재 파드 수와 무관하게 그 값으로 맞춥니다.

대상은 scale 조절이 가능한 자원이면 됩니다. Deployment, StatefulSet, ReplicaSet 을 쓸 수 있습니다.

HPA 와 함께 쓰기​

CronHPA 를 Deployment 가 아니라 HPA 에 걸면 둘을 함께 쓸 수 있습니다. 이때 CronHPA 는 파드 수를 직접 바꾸는 대신 HPA 의 최소·최대 파드 수를 조절합니다.

apiVersion: autoscaling.openmaru.io/v1
kind: CronHPA
metadata:
name: app-cronhpa-with-hpa
namespace: my-app
spec:
scaleTargetRef:
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler # Deployment 가 아니라 HPA 를 가리킵니다
name: my-app-hpa
jobs:
- name: peak-hours
schedule: "0 50 8 * * 1-5" # 평일 08:50 — 바닥을 5로 올림
targetSize: 5
- name: off-hours
schedule: "0 0 20 * * 1-5" # 평일 20:00 — 바닥을 2로 내림
targetSize: 2

동작은 이렇습니다.

시각CronHPA 가 하는 일그 뒤 HPA 가 하는 일
08:50HPA 최소 파드 수를 5로 올립니다부하가 더 오르면 최대까지 스스로 늘립니다
20:00HPA 최소 파드 수를 2로 내립니다부하가 낮으면 2까지 줄입니다

시각 기준으로 바닥을 정하고, 그 위는 HPA 가 실제 부하를 보고 조절합니다. 예측 가능한 부분은 CronHPA 가, 예측할 수 없는 부분은 HPA 가 맡는 구성입니다.

targetSize 가 현재 최대 파드 수보다 크면 최대값도 함께 올라갑니다. 최대를 넘어서는 값을 넣어도 실패하지 않습니다.

한 번만 실행​

runOnce: true 를 넣으면 그 일정은 한 번 실행되고 목록에서 사라집니다.

jobs:
- name: one-time-scale-up
schedule: "0 0 9 * * *"
targetSize: 10
runOnce: true

@date 와 함께 쓰면 특정 날짜의 행사에 맞출 수 있습니다.

jobs:
- name: event-start
schedule: "@date 2026-10-03 00:00:00"
targetSize: 20
- name: event-end
schedule: "@date 2026-10-09 00:00:00"
targetSize: 3

특정 날짜에 건너뛰기​

excludeDates 에 적은 날에는 모든 일정이 실행되지 않습니다. 공휴일이나 주말에 조절을 멈출 때 씁니다.

spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
excludeDates:
- "* * * * * 6" # 매주 토요일
- "* * * * * 0" # 매주 일요일
- "* * * 1 1 *" # 1월 1일
- "* * * 25 12 *" # 12월 25일
jobs:
- name: scale-up
schedule: "0 50 8 * * *"
targetSize: 5
- name: scale-down
schedule: "0 10 18 * * *"
targetSize: 1

excludeDates 도 크론 표기로 씁니다. 2026-01-01 같은 날짜 형식이 아닙니다. 여섯 자리 표기에서 날짜에 해당하는 자리만 지정하고 나머지는 * 로 둡니다.

제외일에는 늘리기도 줄이기도 하지 않습니다. 위 예에서 금요일 18:10 에 1개로 줄인 뒤 토요일·일요일에는 아무 일도 일어나지 않으므로, 월요일 08:50 까지 1개로 유지됩니다. 주말에도 최소 대수가 필요하면 excludeDates 대신 주말용 일정을 따로 넣으십시오.

상태 확인​

Console 의 CronHPA 상세 화면에서 일정별 상태를 봅니다.

상태뜻
Submitted등록되어 다음 실행을 기다립니다
Succeed마지막 실행이 성공했습니다
Failed마지막 실행이 실패했습니다. 사유가 함께 표시됩니다

각 일정마다 마지막 실행 시각 과 다음 실행 예정 시각 이 나옵니다. 의도한 시각과 다르면 아래 시간대 항목을 확인하십시오.

주의할 것​

항목내용
일정 표기 자리 수여섯 자리입니다. CronJob 표기(다섯 자리)를 그대로 쓰면 자리가 밀려 엉뚱한 시각에 실행됩니다
시간대컨트롤러의 시간대를 따릅니다. COP 는 기본으로 Asia/Seoul 로 설치합니다. 다른 시간대로 설치했다면 일정 시각도 그 기준입니다
targetSize: 00 을 넣으면 파드가 모두 내려가 서비스가 멈춥니다. 개발·검증 환경에서 야간에 자원을 아낄 때만 쓰십시오
되돌리는 일정을 반드시 함께 넣으십시오늘리는 일정만 두면 계속 그 상태로 남습니다
손으로 바꾼 파드 수는 다음 일정에 덮어써집니다Console 에서 복제본 수를 바꿔도 다음 실행 시각에 targetSize 로 되돌아갑니다
Deployment 에 직접 걸면 HPA 와 다툽니다함께 쓰려면 HPA 를 대상으로 지정하십시오(위 참고)
클러스터 여유를 넘겨 잡지 마십시오늘어난 파드가 Pending 에 머물면 오히려 상황이 나빠집니다

VPA​

HPA 와 CronHPA 가 파드 개수를 바꾸는 것이라면, VPA 는 파드 하나의 크기를 맞춥니다. 워크로드가 실제로 쓰는 양을 지켜보고 적정 자원 요청량을 알려 주거나, 설정에 따라 적용합니다.

워크로드 > 수직 자동 확장(VPA) 에서 봅니다.

설치되어 있어도 그것만으로는 아무것도 바뀌지 않습니다. 대상을 지정하는 VPA 를 만들어야 그 워크로드에 대해 동작합니다.

어떨 때 쓰는가​

상황왜 VPA 인가
요청량을 얼마로 잡을지 모르겠다실제 사용량에서 적정값을 계산해 줍니다. 위 "자원 요청량" 계산을 대신합니다
넉넉히 잡아 둔 값이 노드를 묶고 있다실제 필요량만큼으로 줄여 다른 워크로드가 쓸 자리를 되찾습니다
부하 패턴이 바뀌었다지금 사용량에 맞춰 다시 알려 줍니다
개수를 늘릴 수 없는 워크로드다데이터베이스처럼 복제본을 늘리기 어려우면 크기를 키우는 쪽이 맞습니다

개수로 풀리지 않는 자리를 메우는 것이 VPA 입니다. 파드 하나가 감당할 양 자체가 모자라면 개수를 늘려도 각 파드가 여전히 부족합니다.

어떤 워크로드에 잘 맞는가​

개수를 늘리는 것으로 풀리지 않거나, 늘리기 어려운 워크로드입니다.

워크로드이런 상황입니다
데이터베이스조회가 늘어 느려졌습니다. 파드를 둘로 늘려도 쓰기는 여전히 한 대가 받습니다. 그 한 대에 메모리를 더 주는 것이 답입니다
캐시 서버담아 둘 데이터가 5Gi 인데 파드에 2Gi 만 줬습니다. 파드를 넷으로 늘려도 각자 2Gi 씩 담을 뿐이라 여전히 모자랍니다
자바 애플리케이션-Xmx2g 로 띄웠는데 컨테이너 메모리 제한이 1Gi 입니다. 힙이 차오르는 순간 컨테이너가 강제 종료됩니다(OOMKilled). 개수와 무관합니다
머신러닝 추론 서버모델 파일이 4Gi 입니다. 파드마다 그것을 통째로 올리므로 어느 파드든 4Gi 가 필요합니다
배치 작업월말 정산은 평소의 다섯 배를 처리합니다. 평소에 맞추면 월말에 죽고, 월말에 맞추면 한 달 내내 놀립니다
사이드카가 붙은 파드애플리케이션은 2Gi 가 필요하고 로그 수집 사이드카는 64Mi 면 충분합니다. 한 값으로 뭉뚱그리면 한쪽이 반드시 어긋납니다

가르는 기준은 하나입니다. 파드를 하나 더 띄우면 그 문제가 풀리는지 보십시오. 풀리면 HPA 고, 풀리지 않으면 VPA 입니다. 요청이 몰려서 느린 것은 파드를 늘리면 나눠 받지만, 메모리가 모자라서 죽는 것은 몇 대를 띄워도 각자 죽습니다.

사이드카가 있으면 컨테이너별로 상한을 거십시오. 권고가 모든 컨테이너에 일괄로 적용되면 사이드카가 과하게 커지거나 본체가 모자라게 됩니다. containerPolicies 로 컨테이너마다 따로 정할 수 있습니다.

실제로 얼마나 어긋나 있나​

값을 정하기 어렵다는 것은 추상적인 이야기가 아닙니다. 시험 클러스터를 실측한 결과입니다.

상태개수
요청량·제한량을 둘 다 비워 둠31
요청량만 비워 둠33
제한량만 비워 둠10
(전체 Deployment)151

값을 적어 둔 것도 실제와 맞지 않는 경우가 많습니다. 같은 클러스터 안에 과하게 잡은 것과 모자라게 잡은 것이 함께 있습니다.

어긋난 방향실측 예
과하게 잡음요청 4000m 인데 실사용 7m (0.2%) · 요청 2000m 인데 6m (0.3%)
모자라게 잡음요청 50m 인데 실사용 459m (918%) · 요청 1000m 인데 3105m (310%)

과하게 잡으면 노드 자리를 묶어 다른 파드가 들어오지 못하고, 모자라게 잡으면 스케줄러가 여유를 잘못 계산하고 CPU 가 조여집니다. VPA 는 이 값을 관측으로 다시 정해 줍니다.

어떻게 시작하는 것이 안전한가​

  1. Off 로 걸어 두고 며칠 지켜봅니다. 파드를 건드리지 않고 권고만 쌓입니다.
  2. 권고값이 평소 사용량과 맞는지 봅니다. 부하가 몰리는 날을 포함해야 합니다.
  3. 중요도가 낮은 워크로드부터 적용해 봅니다.
  4. maxAllowed 로 상한을 걸어 권고가 지나치게 커지는 것을 막습니다.
  5. 운영 워크로드는 마지막에, 재시작 없는 모드를 쓸 수 있는지 확인하고 적용합니다.

HPA 가 이미 붙어 있는 워크로드에는 Off 로만 두십시오. 같은 자원을 두 컨트롤러가 겨누면 값이 튑니다. 권고만 받아 사람이 판단해 반영하는 것이 안전합니다.

권고만 받아 보기​

가장 안전한 시작입니다. 파드를 전혀 건드리지 않고 적정값만 알려 줍니다.

apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: my-app-vpa
namespace: my-namespace
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app # 대상 워크로드
updatePolicy:
updateMode: "Off" # 알려만 주고 바꾸지 않습니다

값은 바로 나오지 않습니다. 사용량을 얼마간 지켜봐야 하므로 처음에는 비어 있는 것이 정상입니다. 몇 분 뒤에 다시 보십시오.

권고값 읽는 법​

목록에서 CPU·메모리 권고값을 보고, 이름을 누르면 상세에서 컨테이너마다 네 값을 봅니다.

값뜻
하한이보다 낮으면 모자랄 수 있습니다
권장값실제로 참고할 값입니다
상한이보다 높이 잡을 이유가 없습니다
제한 전 권장값최소·최대 제한을 걸지 않았다면 나왔을 값

하한과 상한은 지켜본 사용량의 폭 입니다. 운영자가 정한 값이 아닙니다. 지켜본 기간이 짧으면 상한이 아주 크게 나올 수 있고, 시간이 지나면 좁혀집니다.

권장값과 제한 전 권장값이 다르면 내가 걸어 둔 상한이 권고를 깎고 있다는 뜻입니다.

권장값: cpu 500m 제한 전 권장값: cpu 763m ← 상한에 걸려 깎였습니다

실제로는 763m 이 필요한데 500m 으로 제한해 둔 것이므로, 상한을 올릴지 아니면 일부러 억제한 것인지 판단하십시오. 제한을 걸지 않았다면 두 값은 같습니다.

적용하기​

권고를 실제로 반영하려면 updateMode 를 바꿉니다.

값동작
Off알려만 줍니다. 파드를 건드리지 않습니다
Initial파드가 새로 뜰 때만 적용합니다
Recreate차이가 크면 파드를 다시 만듭니다. 잠시 끊깁니다
InPlaceOrRecreate다시 만들지 않고 조정합니다. 안 되면 다시 만듭니다

InPlaceOrRecreate 는 서비스를 끊지 않고 조정하므로 가장 나은 선택이지만 조건이 있습니다.

  • 복제본이 2개 이상 이어야 합니다. 하나뿐이면 조정하지 않습니다 — 그 파드를 건드리는 순간 서비스가 끊기기 때문입니다.
  • 이 기능은 아직 시험 단계라 기본으로 꺼져 있습니다. 쓰려면 설치 담당자에게 요청하십시오.

다시 만들지 않고 조정됐는지는 파드가 다시 뜨지 않았는데 요청량만 바뀐 것 으로 확인합니다.

주의할 것​

  • 🔴 같은 자원을 기준으로 HPA 와 함께 쓰지 마십시오. 아래 "함께 쓸 때 주의할 점" 참고.
  • 요청량을 올리면 제한량도 같은 비율로 오릅니다. 요청량이 다섯 배가 되면 제한량도 다섯 배가 됩니다. 원하지 않으면 maxAllowed 로 상한을 거십시오.
  • 권고가 노드 여유보다 크면 파드가 Pending 에 머뭅니다. 이때도 maxAllowed 로 상한을 겁니다.
  • 한 워크로드에 VPA 를 여러 개 걸지 마십시오. 어느 쪽이 적용될지 정해져 있지 않습니다.
  • 직접 만든 파드(Deployment 등에 속하지 않는 파드)는 대상이 아닙니다.
  • VPA 를 지워도 이미 바뀐 요청량은 그대로 남습니다. 되돌리려면 워크로드를 직접 고치십시오.

APM 지표로 조절하기​

HPA 는 기본적으로 CPU·메모리를 봅니다. 그런데 서비스가 힘든 것과 CPU 가 높은 것은 다릅니다. 외부 호출을 기다리거나 잠금에 걸려 있으면 CPU 는 한가한데 응답만 느려집니다.

APM 을 설치하면 APM 이 재고 있는 값을 HPA 의 기준으로 쓸 수 있습니다. 표준 HPA 설정에 지표 이름만 적으면 되고, 별도의 컨트롤러를 만들지 않습니다.

어떨 때 쓰는가​

  • CPU 는 한가한데 응답이 느려질 때 늘리고 싶다
  • 처리 건수나 접속 사용자 수를 기준으로 삼고 싶다
  • 오류가 늘어나는 상황에서 늘리고 싶다

전제가 하나 있습니다. APM 이 설치되어 있어야 합니다. APM 이 없으면 이 지표들이 아예 보이지 않습니다. CPU·메모리 기준 HPA 는 APM 과 무관하게 그대로 동작합니다.

쓸 수 있는 지표​

지표 이름무엇목표 형식
tps초당 트랜잭션AverageValue
activeUser접속 사용자 수AverageValue
loginUser로그인 사용자 수AverageValue
avgRT평균 응답시간(밀리초)Value
errorRate오류율 0~100Value
apdexDeficit응답 품질 부족분(100 - apdex)Value

🔴 목표 형식을 지표에 맞게 골라야 합니다. AverageValue 는 받은 값을 파드 수로 나눕니다. 합계인 값(tps·activeUser·loginUser)에는 맞지만, 이미 평균이거나 비율인 값(avgRT·errorRate·apdexDeficit)을 나누면 뜻이 사라집니다. 오류 없이 숫자만 틀리므로 알아채기 어렵습니다.

apdex(만족도)는 목록에는 있지만 확장 조건으로 쓸 수 없습니다. 값이 클수록 좋은 지표라 그대로 걸면 응답이 좋을 때 파드가 늘어납니다. 대신 apdexDeficit 을 쓰십시오.

만들기 — YAML​

평균 응답시간이 500밀리초를 넘으면 늘리는 예입니다.

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
namespace: my-namespace
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: External
external:
metric:
name: avgRT
selector:
matchLabels:
apmAlias: apm1 # 어느 APM 서버에 물어볼지
groupName: my-app-group # APM 에 등록된 그룹 이름
target:
type: Value # 평균값이므로 나누지 않습니다
value: "500"

초당 처리 건수를 기준으로 삼는다면 목표 형식이 달라집니다.

- type: External
external:
metric:
name: tps
selector:
matchLabels:
apmAlias: apm1
groupName: my-app-group
target:
type: AverageValue # 합계이므로 파드 수로 나눕니다
averageValue: "100" # 파드 한 대가 100건을 맡는다

apmAlias 와 groupName 은 APM 설치 시 정한 값입니다. 모르면 설치 담당자에게 확인하십시오. 별칭이 틀리면 조회가 거부되며, 다른 서버의 값으로 조용히 조절되지 않습니다.

주의할 것​

  • APM 이 응답하지 못하면 지표를 읽지 못합니다. 이때 HPA 는 파드 수를 바꾸지 않고 현재 상태를 유지합니다.
  • 값이 없는 구간에는 답하지 않습니다. 수집이 끊겼을 때 0 으로 채우면 "가장 좋은 상태" 로 읽혀 파드가 줄어들기 때문입니다.
  • 목록에서 지표 이름과 현재값이 보이지 않으면 APM 설치 여부와 별칭·그룹 이름을 먼저 확인하십시오.

HPA · CronHPA · VPA · APM 지표 고르기​

상황권장
부하가 언제 오를지 예측할 수 없다HPA
매일 같은 시간에 몰린다 (출근 시간, 정산 시간)CronHPA
예열 시간이 길어 부하가 온 뒤 늘리면 늦다CronHPA
야간·주말에 자원을 줄이고 싶다CronHPA
날짜가 정해진 행사가 있다CronHPA (@date)
CPU 는 한가한데 응답이 느려진다APM 지표(avgRT)
처리 건수·사용자 수로 판단하고 싶다APM 지표(tps·activeUser)
요청량을 얼마로 잡을지 모르겠다VPA (Off 로 권고만 받아 보십시오)
파드 하나가 감당할 양 자체가 모자라다VPA
개수를 늘리기 어려운 워크로드다VPA
HPA 와 CronHPA 둘 다 필요하다CronHPA 를 HPA 에 걸어 함께 씁니다(위 "HPA 와 함께 쓰기")

PodDisruptionBudget​

PodDisruptionBudget 은 노드 점검 등으로 파드를 옮길 때 동시에 몇 개까지 내려도 되는지 정합니다.

워크로드 > Pod 중단 예산 에서 봅니다.

설정뜻
minAvailable항상 남아 있어야 하는 최소 파드 수
maxUnavailable동시에 내려도 되는 최대 파드 수

둘 중 하나만 설정합니다. 개수 대신 비율(50%)로도 적을 수 있습니다.

설정하지 않으면 점검 중에 모든 파드가 한꺼번에 내려가 서비스가 끊길 수 있습니다. 노드 점검은 예고 없이 진행되기도 하므로 중요한 서비스에는 미리 설정해 두십시오.

너무 엄격하게 잡으면 노드 점검 자체가 진행되지 않습니다. 복제본이 2개인데 minAvailable: 2 로 두면 파드를 하나도 옮길 수 없어 점검이 멈춥니다.

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: my-app-pdb
namespace: my-app
spec:
minAvailable: 2 # 또는 maxUnavailable: 1 (둘 중 하나만)
selector:
matchLabels:
app: my-app # 보호할 파드의 레이블

selector 는 Deployment 를 가리키는 것이 아니라 파드 레이블을 고릅니다. Deployment 의 spec.selector.matchLabels 와 같은 값을 쓰면 됩니다(3.2 장).

자동 조절을 함께 쓴다면 비율로 적는 편이 안전합니다. 개수로 적으면 파드가 줄었을 때 점검이 막힙니다.

maxUnavailable: 25%

함께 쓸 때 주의할 점​

  • HPA 와 CronHPA 를 같은 Deployment 에 각각 걸지 마십시오. 서로 다른 값을 지시해 파드 수가 오르내립니다. 함께 쓰려면 CronHPA 의 대상을 HPA 로 지정 하십시오(위 참고).
  • 🔴 같은 자원(CPU 또는 메모리)을 기준으로 HPA 와 VPA 를 함께 걸지 마십시오. HPA 는 그 자원을 보고 개수를 늘리고 VPA 는 같은 자원의 요청량을 바꾸므로, 서로의 판단을 되돌립니다. 기준이 다르면(예: HPA 는 CPU, VPA 는 메모리) 함께 쓸 수 있습니다. 판단이 어려우면 VPA 를 Off 로 두어 권고만 받으십시오 — 그 모드는 아무것도 바꾸지 않아 HPA 와 부딪치지 않습니다.
  • 자동 조절을 설정한 대상의 복제본 수를 손으로 바꿔도 곧 되돌아갑니다.
  • ArgoCD 로 관리하는 자원에 자동 조절을 걸 때는 설정 저장소의 복제본 수 항목을 빼야 합니다. 그러지 않으면 ArgoCD 가 파드 수를 되돌립니다(4.7 장).
  • 최소값을 1 로 두면 조절 도중 서비스가 잠시 끊길 수 있습니다. 2 이상을 권장합니다.
  • 최대값은 클러스터가 감당할 수 있는 범위로 두십시오. 자원이 모자라면 늘어난 파드가 Pending 에 머물러 오히려 상황이 나빠집니다.