수평 파드 오토스케일링

수평 파드 오토스케일링 (Horizontal Pod Autoscaling)

쿠버네티스에서 HorizontalPodAutoscaler는 수요에 맞게 용량을 자동으로 조정하는 것을 목표로 워크로드 리소스(Deployment나 StatefulSet 같은)를 자동으로 업데이트해요.

수평 스케일링(horizontal scaling)은 부하가 증가했을 때 더 많은 파드를 배포하는 것으로 응답하는 것을 의미해요. 이것은 쿠버네티스의 경우 워크로드에 이미 실행 중인 파드에 더 많은 리소스(예: 메모리나 CPU)를 할당하는 것을 의미하는 수직 스케일링(vertical scaling)과 달라요.

부하가 감소하고 파드 수가 구성된 최솟값 위라면, HorizontalPodAutoscaler는 워크로드 리소스(Deployment, StatefulSet, 또는 다른 유사 리소스)에 다시 스케일 다운하도록 지시해요.

수평 파드 오토스케일링은 스케일링할 수 없는 객체(예: DaemonSet)에는 적용되지 않아요.

HorizontalPodAutoscaler는 쿠버네티스 API 리소스와 컨트롤러로 구현돼요. 리소스가 컨트롤러의 동작을 결정해요. 쿠버네티스 제어 플레인 내에서 실행되는 수평 파드 오토스케일링 컨트롤러는 평균 CPU 사용률, 평균 메모리 사용률, 또는 지정한 다른 사용자 지정 메트릭 같은 관찰된 메트릭에 맞게 대상(예: Deployment)의 원하는 스케일을 주기적으로 조정해요.

수평 파드 오토스케일링 사용의 연습 예시가 있어요.

출처: 문서

본문

HorizontalPodAutoscaler는 어떻게 작동하나요?

graph BT
hpa[HorizontalPodAutoscaler] --> scale[Scale]
subgraph rc[Deployment]
    scale
end
scale -.-> pod1[Pod 1]
scale -.-> pod2[Pod 2]
scale -.-> pod3[Pod N]

그림 1. HorizontalPodAutoscaler는 Deployment와 그 ReplicaSet의 scale을 제어한다

쿠버네티스는 수평 파드 오토스케일링을 간헐적으로 실행되는 제어 루프로 구현해요(연속 프로세스는 아님). 간격은 kube-controller-manager에 대한 --horizontal-pod-autoscaler-sync-period 파라미터로 설정돼요 (기본 간격은 15초).

각 기간마다 한 번 컨트롤러 매니저는 각 HorizontalPodAutoscaler 정의에서 지정된 메트릭에 대해 리소스 사용률을 쿼리해요. 컨트롤러 매니저는 scaleTargetRef로 정의된 대상 리소스를 찾은 다음 대상 리소스의 .spec.selector 레이블에 기반해 파드를 선택하고, 리소스 메트릭 API(파드별 리소스 메트릭용) 또는 사용자 지정 메트릭 API(다른 모든 메트릭용)에서 메트릭을 얻어요.

  • 파드별 리소스 메트릭(CPU 같은)의 경우 컨트롤러는 HorizontalPodAutoscaler가 대상으로 하는 각 파드에 대한 리소스 메트릭 API에서 메트릭을 가져와요. 그런 다음 대상 사용률 값이 설정되면 컨트롤러는 각 파드의 컨테이너의 동등한 리소스 요청의 백분율로 사용률 값을 계산해요. 대상 원시(raw) 값이 설정되면 원시 메트릭 값이 직접 사용돼요. 그런 다음 컨트롤러는 모든 대상 파드에 걸쳐 사용률 또는 원시 값(지정된 대상 유형에 따라)의 평균을 내고, 원하는 레플리카 수를 스케일링하는 데 사용되는 비율을 생성해요. 파드의 일부 컨테이너에 관련 리소스 요청이 설정되어 있지 않으면 파드의 CPU 사용률이 정의되지 않고 오토스케일러가 해당 메트릭에 대해 어떤 조치도 취하지 않는다는 점을 유의하세요. 오토스케일링 알고리즘의 작동 방식에 대한 자세한 내용은 아래의 알고리즘 세부 사항 섹션을 참조하세요.
  • 파드별 사용자 지정 메트릭의 경우 컨트롤러는 파드별 리소스 메트릭과 유사하게 작동하지만, 사용률 값이 아닌 원시 값을 사용한다는 점이 달라요.
  • 객체 메트릭과 외부 메트릭의 경우 문제의 객체를 설명하는 단일 메트릭이 가져와져요. 이 메트릭은 대상 값과 비교되어 위와 같이 비율을 생성해요. autoscaling/v2 API 버전에서 이 값은 비교가 이루어지기 전에 선택적으로 파드 수로 나눌 수 있어요.

HorizontalPodAutoscaler의 일반적인 용도는 집계된 API(metrics.k8s.io, custom.metrics.k8s.io, external.metrics.k8s.io)에서 메트릭을 가져오도록 구성하는 것이에요. metrics.k8s.io API는 보통 Metrics Server라는 애드온으로 제공되며, 별도로 시작해야 해요. 리소스 메트릭에 대한 자세한 내용은 Metrics Server를 참조하세요.

메트릭 API 지원은 이러한 서로 다른 API의 안정성 보장과 지원 상태를 설명해요.

HorizontalPodAutoscaler 컨트롤러는 스케일링을 지원하는 해당 워크로드 리소스(Deployment와 StatefulSet 같은)에 접근해요. 이러한 리소스 각각은 scale이라는 하위 리소스를 가지며, 레플리카 수를 동적으로 설정하고 각각의 현재 상태를 검사할 수 있게 해주는 인터페이스예요. 쿠버네티스 API의 하위 리소스에 대한 일반적인 정보는 쿠버네티스 API 개념을 참조하세요.

알고리즘 세부 사항

가장 기본적인 관점에서 HorizontalPodAutoscaler 컨트롤러는 원하는 메트릭 값과 현재 메트릭 값 사이의 비율로 작동해요:

예를 들어 현재 메트릭 값이 200m이고 원하는 값이 100m이면, ( { 200.0 \div 100.0 } = 2.0 )이므로 레플리카 수가 두 배가 돼요. 현재 값이 대신 50m이면 ( { 50.0 \div 100.0 } = 0.5 )이므로 레플리카 수를 절반으로 해요. 제어 플레인은 비율이 1.0에 충분히 가까우면(구성 가능한 허용 오차, 기본 0.1) 어떤 스케일링 동작도 건너뛰어요.

targetAverageValue 또는 targetAverageUtilization이 지정되면, currentMetricValue는 HorizontalPodAutoscaler의 scale 대상의 모든 파드에서 주어진 메트릭의 평균을 내어 계산돼요.

허용 오차를 확인하고 최종 값을 결정하기 전에 제어 플레인은 어떤 메트릭이 누락되었는지, 그리고 얼마나 많은 파드가 Ready인지도 고려해요. 파드별 리소스 메트릭의 경우 삭제 타임스탬프가 설정된 모든 파드(삭제 타임스탬프가 있는 객체는 종료/제거 과정에 있음)는 무시되고, 모든 실패한 파드는 폐기돼요. 외부 및 객체 메트릭의 경우 레플리카 수는 Running 및 Ready 파드 수에 기반하며, 여전히 Ready인 종료 중인 파드는 그 합계에 계속 계산돼요.

특정 파드에 메트릭이 누락되면 나중을 위해 따로 둬지고; 메트릭이 누락된 파드는 최종 스케일링 양을 조정하는 데 사용될 거예요.

CPU로 스케일링할 때, 어떤 파드가 아직 준비되지 않았거나(여전히 초기화 중이거나, 어쩌면 불건전하거나) 그 파드에 대한 가장 최근의 메트릭 지점이 준비되기 전이면 그 파드도 따로 둬져요.

기술적 제약 때문에 HorizontalPodAutoscaler 컨트롤러는 특정 CPU 메트릭을 따로 둘지 결정할 때 파드가 처음으로 준비된 때를 정확히 결정할 수 없어요. 대신 파드가 시작된 이후 짧고 구성 가능한 시간 창 내에 준비되지 않았다가 준비로 전환했다면 "아직 준비되지 않음"으로 간주해요. 이 값은 --horizontal-pod-autoscaler-initial-readiness-delay 명령줄 옵션으로 구성되며 기본값은 30초예요. 파드가 준비된 후에는 시작된 이후 더 긴 구성 가능한 시간 내에 준비로의 전환을 첫 번째로 간주해요. 이 값은 --horizontal-pod-autoscaler-cpu-initialization-period 명령줄 옵션으로 구성되며 기본값은 5분.

그런 다음 위에서 따로 둔 or 폐기한 남은 파드를 사용해 ( currentMetricValue \over desiredMetricValue ) 기본 스케일 비율이 계산돼요.

누락된 메트릭이 있으면 제어 플레인은 평균을 더 보수적으로 재계산하는데, 스케일 다운의 경우 그 파드들이 원하는 값의 100%를 소비하고, 스케일 업의 경우 0%를 소비한다고 가정해요. 이것은 가능한 스케일의 크기를 줄여요.

또한 아직 준비되지 않은 파드가 있고 워크로드가 누락된 메트릭이나 아직 준비되지 않은 파드를 고려하지 않고 스케일 업했을 것이라면, 컨트롤러는 아직 준비되지 않은 파드가 원하는 메트릭의 0%를 소비한다고 보수적으로 가정해 스케일 업의 크기를 더 줄여요.

아직 준비되지 않은 파드와 누락된 메트릭을 고려한 후 컨트롤러는 사용 비율을 재계산해요. 새 비율이 스케일 방향을 뒤집거나 허용 오차 내에 있으면 컨트롤러는 어떤 스케일링 동작도 하지 않아요. 다른 경우에는 새 비율을 사용해 파드 수의 변경을 결정해요.

새 사용 비율이 사용되더라도 평균 사용률의 원래 값은 아직 준비되지 않은 파드나 누락된 메트릭을 고려하지 않고 HorizontalPodAutoscaler status를 통해 다시 보고된다는 점을 유의하세요.

HorizontalPodAutoscaler에 여러 메트릭이 지정되면 이 계산이 각 메트릭에 대해 수행되고 가장 큰 원하는 레플리카 수가 선택돼요. 이러한 메트릭 중 어떤 것을 원하는 레플리카 수로 변환할 수 없고(예: 메트릭 API에서 메트릭을 가져오는 오류 때문에) 가져올 수 있는 메트릭이 스케일 다운을 제안한다면 스케일링은 건너뛰어져요. 이는 하나 이상의 메트릭이 현재 값보다 큰 desiredReplicas를 주면 HPA가 여전히 스케일 업할 수 있음을 의미해요.

마지막으로 HPA가 대상의 스케일을 조정하기 직전에 스케일 권장 사항이 기록돼요. 컨트롤러는 구성 가능한 시간 창 내의 모든 권장 사항을 고려해 그 창에서 가장 높은 권장 사항을 선택해요. 이 값을 --horizontal-pod-autoscaler-downscale-stabilization 명령줄 옵션으로 구성할 수 있으며 기본값은 5분이에요. 이것은 스케일 다운이 점진적으로 발생하며, 빠르게 변동하는 메트릭 값의 영향을 부드럽게 한다는 것을 의미해요.

파드 준비 상태와 오토스케일링 메트릭

HPA(HorizontalPodAutoscaler) 컨트롤러는 시작 중에 파드에서 CPU 메트릭이 수집되는 방식에 영향을 주는 두 가지 명령줄 옵션을 포함해요:

  • --horizontal-pod-autoscaler-cpu-initialization-period (기본값: 5분)

이것은 파드가 시작된 후 다음 경우 외에는 CPU 사용량이 무시되는 시간 창을 정의해요: 파드가 Ready 상태이고, 그리고 메트릭 샘플이 그 Ready 상태였던 기간 동안 완전히 채취된 경우.

이 명령줄 옵션은 초기화 중인 파드(예: 워밍업 중인 Java 앱)의 오해 소지가 있는 높은 CPU 사용량을 HPA 스케일링 결정에서 제외하는 데 도움을 줘요.

  • --horizontal-pod-autoscaler-initial-readiness-delay (기본값: 30초)

이것은 파드가 시작된 후 짧은 지연 기간을 정의하며, 그 동안 HPA 컨트롤러는 현재 Unready인 파드를 (이전에 잠깐 Ready로 전환했더라도) 여전히 초기화 중인 것으로 취급해요.

이것은 다음을 위해 설계됐어요: 시작 중에 Ready와 Unready 사이를 빠르게 변동하는 파드를 포함하지 않도록. HPA가 그들의 메트릭을 유효한 것으로 간주하기 전에 초기 준비 상태 신호에서 안정성을 보장.

이 명령줄 옵션은 클러스터 전체에서만 설정할 수 있어요.

파드 준비 상태의 주요 동작

  • 파드가 Ready이고 Ready 상태를 유지하면 지연 내에서도 메트릭에 기여하는 것으로 계산될 수 있어요.
  • 파드가 Ready와 Unready 사이를 빠르게 토글하면 안정적으로 Ready로 간주될 때까지 메트릭이 무시돼요.

파드 준비 상태의 모범 사례

  • 높은 CPU 사용량이 지나갈 때까지 통과하지 않는 startupProbe를 구성하거나,
  • initialDelaySeconds를 사용해 CPU 스파이크가 가라앉은 후에만 readinessProbe가 Ready를 보고하도록 보장하세요.

그리고 이상적으로는 --horizontal-pod-autoscaler-cpu-initialization-period를 시작 기간을 포함하도록 설정하세요.

API 객체

HorizontalPodAutoscaler는 쿠버네티스 autoscaling API 그룹의 API 유형이에요. 현재 안정 버전은 메모리와 사용자 지정 메트릭에 대한 스케일링 지원을 포함하는 autoscaling/v2 API 버전에서 찾을 수 있어요. autoscaling/v2에서 도입된 새 필드는 autoscaling/v1로 작업할 때 어노테이션으로 보존돼요.

HorizontalPodAutoscaler API 객체를 만들 때 지정된 이름이 유효한 DNS 서브도메인 이름인지 확인하세요. API 객체에 대한 자세한 내용은 HorizontalPodAutoscaler 객체에서 찾을 수 있어요.

워크로드 스케일의 안정성

HorizontalPodAutoscaler를 사용해 레플리카 그룹의 스케일을 관리할 때, 평가된 메트릭의 동적 특성 때문에 레플리카 수가 자주 변동할 수 있어요. 이것은 때때로 스러싱(thrashing) 또는 플래핑(flapping)이라고 불려요. 그것은 사이버네틱스의 히스테리시스(hysteresis) 개념과 유사해요.

롤링 업데이트 중 오토스케일링

쿠버네티스는 Deployment에 롤링 업데이트를 수행할 수 있게 해줘요. 그 경우 Deployment가 기반 ReplicaSets를 대신 관리해요. Deployment에 대한 오토스케일링을 구성할 때 HorizontalPodAutoscaler를 단일 Deployment에 바인딩해요. HorizontalPodAutoscaler는 Deployment의 replicas 필드를 관리해요. deployment 컨트롤러는 기반 ReplicaSets의 replicas를 롤아웃 중과 이후에도 합이 적절한 수가 되도록 설정할 책임이 있어요.

오토스케일된 레플리카 수가 있는 StatefulSet의 롤링 업데이트를 수행하면 StatefulSet이 파드 집합을 직접 관리해요(ReplicaSet과 유사한 중간 리소스가 없음).

리소스 메트릭 지원

어떤 HPA 대상이든 스케일링 대상의 파드 리소스 사용량에 기반해 스케일링될 수 있어요. 파드 스펙을 정의할 때 cpumemory 같은 리소스 요청을 지정해야 해요. 이것은 리소스 사용률을 결정하고 HPA 컨트롤러가 대상을 위아래로 스케일링하는 데 사용돼요. 리소스 사용률 기반 스케일링을 사용하려면 다음과 같은 메트릭 소스를 지정하세요:

type: Resource
resource:
  name: cpu
  target:
    type: Utilization
    averageUtilization: 60

이 메트릭으로 HPA 컨트롤러는 스케일링 대상 파드의 평균 사용률을 60%로 유지할 거예요. 사용률은 파드의 요청 리소스에 대한 현재 리소스 사용량의 비율이에요. 사용률이 계산되고 평균화되는 방법에 대한 자세한 내용은 알고리즘을 참조하세요.

컨테이너 리소스 메트릭

이것은 쿠버네티스의 안정적(stable) 기능이며 1.30 릴리스부터 그렇게 되어 있어요. 더 이상 이 기능을 토글할 수 없어요(관련 기능 게이트가 제거됨).

HorizontalPodAutoscaler API는 컨테이너 메트릭 소스도 지원하며, HPA가 파드 집합에 걸쳐 개별 컨테이너의 리소스 사용량을 추적해 대상 리소스를 스케일링할 수 있어요. 이를 통해 특정 파드에서 가장 중요한 컨테이너에 대한 스케일링 임계값을 구성할 수 있어요. 예를 들어 웹 애플리케이션과 로깅을 제공하는 사이드카 컨테이너가 있다면, 사이드카 컨테이너와 그 리소스 사용량을 무시하고 웹 애플리케이션의 리소스 사용에 기반해 스케일링할 수 있어요.

리소스 대상을 다른 컨테이너 집합을 가진 새 파드 스펙으로 수정한다면, 새로 추가된 컨테이너가 스케일링에도 사용되어야 한다면 HPA spec을 수정해야 해요. 메트릭 소스에 지정된 컨테이너가 존재하지 않거나 파드의 일부에만 존재하면 그 파드들은 무시되고 권장 사항이 재계산돼요. 계산에 대한 자세한 내용은 알고리즘을 참조하세요. 오토스케일링에 컨테이너 리소스를 사용하려면 다음과 같이 메트릭 소스를 정의하세요:

type: ContainerResource
containerResource:
  name: cpu
  container: application
  target:
    type: Utilization
    averageUtilization: 60

위 예시에서 HPA 컨트롤러는 모든 파드의 application 컨테이너에서 cpu의 평균 사용률이 60%가 되도록 대상을 스케일링해요.

참고:

HorizontalPodAutoscaler가 추적하는 컨테이너의 이름을 변경한다면, 스케일링이 변경이 적용되는 동안 사용 가능하고 효과적으로 유지되도록 특정 순서로 그 변경을 할 수 있어요. 컨테이너를 정의하는 리소스(Deployment 같은)를 업데이트하기 전에 새 컨테이너 이름과 이전 컨테이너 이름을 모두 추적하도록 관련 HPA를 업데이트해야 해요. 이렇게 하면 HPA가 업데이트 과정 전반에 걸쳐 스케일링 권장 사항을 계산할 수 있어요.

컨테이너 이름 변경을 워크로드 리소스에 롤아웃한 후 HPA 스펙에서 이전 컨테이너 이름을 제거해 정리하세요.

사용자 지정 메트릭에 대한 스케일링

(autoscaling/v2beta2 API 버전이 이전에 이 능력을 베타 기능으로 제공했어요)

autoscaling/v2 API 버전을 사용한다면 쿠버네티스나 어떤 쿠버네티스 컴포넌트에도 내장되지 않은 사용자 지정 메트릭에 기반해 HorizontalPodAutoscaler를 스케일하도록 구성할 수 있어요. 그러면 HorizontalPodAutoscaler 컨트롤러가 쿠버네티스 API에서 이러한 사용자 지정 메트릭을 쿼리해요.

요구 사항은 메트릭 API 지원을 참조하세요.

여러 메트릭에 대한 스케일링

(autoscaling/v2beta2 API 버전이 이전에 이 능력을 베타 기능으로 제공했어요)

autoscaling/v2 API 버전을 사용한다면 HorizontalPodAutoscaler가 스케일링할 여러 메트릭을 지정할 수 있어요. 그러면 HorizontalPodAutoscaler 컨트롤러가 각 메트릭을 평가하고 그 메트릭에 기반해 새 스케일을 제안해요. HorizontalPodAutoscaler는 각 메트릭에 권장된 최대 스케일을 취해 워크로드를 그 크기로 설정해요(구성한 전체 최대값보다 크지 않은 경우).

메트릭 API 지원

기본적으로 HorizontalPodAutoscaler 컨트롤러는 일련의 API에서 메트릭을 검색해요. 그것이 이러한 API에 접근하려면 클러스터 관리자가 다음을 보장해야 해요:

  • API 집계 계층이 활성화되어 있어야 해요.
  • 해당 API가 등록되어 있어야 해요:
    • 리소스 메트릭의 경우 metrics.k8s.io API이며, 일반적으로 metrics-server가 제공해요. 클러스터 애드온으로 시작할 수 있어요.

참고:

HorizontalPodAutoscaler는 현재 리소스 메트릭에 대해 metrics.k8s.io/v1beta1 API를 지원해요. 아직 metrics.k8s.io/v1을 지원하지 않아요.

  • 사용자 지정 메트릭의 경우 custom.metrics.k8s.io API예요. 메트릭 솔루션 공급업체가 제공하는 "어댑터(adapter)" API 서버가 제공해요. 사용 가능한 쿠버네티스 메트릭 어댑터가 있는지 메트릭 파이프라인을 확인하세요.
  • 외부 메트릭의 경우 external.metrics.k8s.io API예요. 위에서 제공된 사용자 지정 메트릭 어댑터가 제공할 수 있어요.

이러한 다양한 메트릭 경로와 그것들이 어떻게 다른지에 대한 자세한 내용은 HPA V2, custom.metrics.k8s.io, external.metrics.k8s.io의 관련 설계 제안을 참조하세요.

사용 방법에 대한 예시는 사용자 지정 메트릭 사용 연습과 외부 메트릭 사용 연습을 참조하세요.

구성 가능한 스케일링 동작

(autoscaling/v2beta2 API 버전이 이전에 이 능력을 베타 기능으로 제공했어요)

v2 HorizontalPodAutoscaler API를 사용한다면 behavior 필드(API 참조 참조)를 사용해 별도의 스케일 업과 스케일 다운 동작을 구성할 수 있어요. behavior 필드 아래에 scaleUp 및/또는 scaleDown을 설정해 이러한 동작을 지정해요.

스케일링 정책은 스케일링하는 동안 레플리카의 변화율을 제어할 수 있게 해줘요. 또한 두 가지 설정을 사용해 플래핑을 방지할 수 있어요: 레플리카 수를 부드럽게 하기 위한 안정화 창(stabilization window)과 지정된 임계값 아래의 작은 메트릭 변동을 무시하기 위한 허용 오차(tolerance).

스케일링 정책

spec의 behavior 섹션에 하나 이상의 스케일링 정책을 지정할 수 있어요. 여러 정책이 지정되면 가장 높은 변경량을 허용하는 정책이 기본적으로 선택돼요. 다음 예시는 스케일 다운 동안 이 동작을 보여 줘요:

behavior:
  scaleDown:
    policies:
    - type: Pods
      value: 4
      periodSeconds: 60
    - type: Percent
      value: 10
      periodSeconds: 60

periodSeconds는 정책이 성립해야 하는 과거 시간의 길이를 나타내요. periodSeconds에 대해 설정할 수 있는 최대값은 1800(30분)이에요. 첫 번째 정책(Pods)은 1분 안에 최대 4개의 레플리카가 스케일 다운되도록 허용해요. 두 번째 정책(Percent)은 1분 안에 현재 레플리카의 최대 10%가 스케일 다운되도록 허용해요.

기본적으로 가장 높은 변경량을 허용하는 정책이 선택되므로, 두 번째 정책은 파드 레플리카 수가 40개를 넘을 때만 사용돼요. 40개 이하라면 첫 번째 정책이 적용돼요. 예를 들어 80개의 레플리카가 있고 대상을 10개로 스케일 다운해야 한다면 첫 단계에서 8개의 레플리카가 줄어들어요. 다음 반복에서 레플리카 수가 72개일 때 10%는 7.2지만 8로 반올림돼요. 오토스케일러 컨트롤러의 각 루프에서 변경할 파드 수는 현재 레플리카 수에 기반해 재계산돼요. 레플리카 수가 40 미만으로 떨어지면 첫 번째 정책(Pods)이 적용되고 한 번에 4개의 레플리카가 줄어들어요.

selectPolicy 필드를 스케일링 방향에 대해 지정해 정책 선택을 변경할 수 있어요. Min으로 설정하면 레플리카 수에서 가장 작은 변경을 허용하는 정책을 선택해요. Disabled로 설정하면 그 방향의 스케일링을 완전히 비활성화해요.

안정화 창 (Stabilization window)

안정화 창은 스케일링에 사용되는 메트릭이 계속 변동할 때 레플리카 수의 플래핑을 제한하는 데 사용돼요. 오토스케일링 알고리즘은 이 창을 사용해 이전의 원하는 상태를 추론하고 워크로드 스케일에 원치 않는 변경을 피해요.

예를 들어 다음 예시 조각에서 scaleDown에 안정화 창이 지정돼 있어요.

behavior:
  scaleDown:
    stabilizationWindowSeconds: 300

메트릭이 대상을 스케일 다운해야 한다고 나타낼 때 알고리즘은 이전에 계산된 원하는 상태를 살펴보고 지정된 간격에서 가장 높은 값을 사용해요. 위 예시에서 지난 5분의 모든 원하는 상태가 고려돼요.

이것은 이동 최대값에 근접하며, 스케일링 알고리즘이 파드를 제거했다가 몇 분 후 동등한 파드를 재생성하기만을 트리거하는 것을 피해요.

허용 오차 (Tolerance)

이것은 쿠버네티스의 안정적(stable) 기능이며 v1.37 버전부터 그렇게 되어 있어요. v1.33 릴리스에서 처음 사용 가능해졌어요. 더 이상 이 기능이나 동작을 비활성화하거나 선택 해제할 수 없어요(잠겨 있음); 관련 기능 게이트 HPAConfigurableTolerance에 값을 명시적으로 설정하면 쿠버네티스는 그것을 무시하지만 오류를 보고하지 않아요.

tolerance 필드는 메트릭 변동에 대한 임계값을 구성해, 오토스케일러가 그 값보다 낮은 변경에 대해 스케일링하지 못하게 해요.

이 허용 오차는 원하는 메트릭 값 주변의 변동량으로 정의되며, 그 아래에서는 스케일링이 발생하지 않아요. 예를 들어 대상 메모리 소비가 100MiB이고 스케일 업 허용 오차가 5%로 구성된 HorizontalPodAutoscaler를 고려해 보세요:

behavior:
  scaleUp:
    tolerance: 0.05 # 5% tolerance for scale up

이 구성으로 HPA 알고리즘은 메모리 소비가 105MiB보다 높을 때만(즉 대상보다 5% 위) 스케일 업을 고려해요.

이 필드를 설정하지 않으면 HPA는 기본 클러스터 전체 허용 오차 10%를 적용해요. 이 기본값은 kube-controller-manager --horizontal-pod-autoscaler-tolerance 명령줄 인수를 사용해 스케일 업과 스케일 다운 모두에 대해 업데이트할 수 있어요. (쿠버네티스 API로 이 기본값을 구성할 수는 없어요.)

기본 동작

사용자 지정 스케일링을 사용하기 위해 모든 필드를 지정할 필요는 없어요. 사용자 지정해야 할 값만 지정할 수 있어요. 이러한 사용자 지정 값은 기본값과 병합돼요. 기본값은 HPA 알고리즘의 기존 동작과 일치해요.

behavior:
  scaleDown:
    stabilizationWindowSeconds: 300
    policies:
    - type: Percent
      value: 100
      periodSeconds: 15
  scaleUp:
    stabilizationWindowSeconds: 0
    policies:
    - type: Percent
      value: 100
      periodSeconds: 15
    - type: Pods
      value: 4
      periodSeconds: 15
    selectPolicy: Max

스케일 다운의 경우 안정화 창은 300초(또는 제공된 경우 --horizontal-pod-autoscaler-downscale-stabilization 명령줄 옵션의 값)예요. 스케일 다운에는 단일 정책만 있으며 현재 실행 중인 레플리카의 100%를 제거하는 것을 허용하므로 스케일링 대상이 최소 허용 레플리카로 스케일 다운될 수 있음을 의미해요. 스케일 업의 경우 안정화 창이 없어요. 메트릭이 대상을 스케일 업해야 한다고 나타내면 대상이 즉시 스케일 업돼요. HPA가 정상 상태에 도달할 때까지 15초마다 최대 4개의 파드 또는 현재 실행 중인 레플리카의 100%가 추가될 수 있는 두 정책이 있어요.

예시: 다운스케일 안정화 창 변경

1분의 사용자 지정 다운스케일 안정화 창을 제공하려면 다음 동작이 HPA에 추가돼요:

behavior:
  scaleDown:
    stabilizationWindowSeconds: 60

예시: 스케일 다운 속도 제한

HPA가 파드를 제거하는 속도를 분당 10%로 제한하려면 다음 동작이 HPA에 추가돼요:

behavior:
  scaleDown:
    policies:
    - type: Percent
      value: 10
      periodSeconds: 60

분당 5개 이상의 파드가 제거되지 않도록 하려면 고정 크기 5의 두 번째 스케일 다운 정책을 추가하고 selectPolicy를 minimum으로 설정해요. selectPolicyMin으로 설정하면 오토스케일러가 가장 적은 수의 파드에 영향을 주는 정책을 선택한다는 뜻이에요:

behavior:
  scaleDown:
    policies:
    - type: Percent
      value: 10
      periodSeconds: 60
    - type: Pods
      value: 5
      periodSeconds: 60
    selectPolicy: Min

예시: 스케일 다운 비활성화

selectPolicyDisabled는 주어진 방향의 스케일링을 끄요. 따라서 다운스케일링을 방지하려면 다음 정책이 사용되게 돼요:

behavior:
  scaleDown:
    selectPolicy: Disabled

kubectl에서의 HorizontalPodAutoscaler 지원

HorizontalPodAutoscaler는 모든 API 리소스처럼 kubectl에 의해 표준 방식으로 지원돼요. kubectl create 명령으로 새 오토스케일러를 만들 수 있어요. kubectl get hpa로 오토스케일러를 나열하거나 kubectl describe hpa로 자세한 설명을 얻을 수 있어요. 마지막으로 kubectl delete hpa로 오토스케일러를 삭제할 수 있어요.

또한 HorizontalPodAutoscaler 객체를 만들기 위한 특별한 kubectl autoscale 명령이 있어요. 예를 들어 kubectl autoscale rs foo --min=2 --max=5 --cpu=80%를 실행하면 ReplicaSet foo에 대한 오토스케일러를 만들며, 대상 CPU 사용률을 80%로 설정하고 레플리카 수는 2와 5 사이로 설정해요.

0으로 그리고 0에서 스케일링

사용자 지정(객체) 또는 외부 메트릭으로 스케일링하는 HorizontalPodAutoscaler의 경우 spec.minReplicas를 0으로 설정할 수 있어요. 그러면 부하가 없을 때 워크로드가 레플리카 0까지 완전히 스케일 다운되고, 메트릭이 적어도 하나의 레플리카가 필요함을 나타내면 다시 스케일 업돼요. 이것은 가끔 사용되는 큐의 소비자나 GPU 같은 전용 하드웨어가 필요한 job처럼 오랜 기간 유휴 상태이고 계속 실행하기에 비싼 워크로드에 유용해요.

0으로의 스케일링은 객체 및 외부 메트릭에서만 지원돼요. 리소스 메트릭(CPU나 메모리 사용률 같은)에서는 사용할 수 없는데, 그것은 실행 중인 파드에서만 측정할 수 있기 때문이에요. minReplicas: 0을 설정하려면 적어도 하나의 객체 또는 외부 메트릭이 구성되어야 해요; 그렇지 않으면 API 서버가 HorizontalPodAutoscaler를 거부해요.

이 동작은 기본적으로 활성화된 HPAScaleToZero 기능 게이트로 제어돼요. 기능 게이트는 minReplicas: 0을 허용하는 kube-apiserver와 스케일링을 수행하는 kube-controller-manager 모두에서 활성화되어야 해요.

HPA가 워크로드를 0 레플리카로 유지하는 동안, HorizontalPodAutoscaler의 status에 ScaledToZero 조건을 True로 설정해 기록해요. HPA는 이 조건을 사용해 0으로 스케일한 워크로드(메트릭이 돌아오면 다시 스케일 업할 것)와 레플리카 수를 0으로 설정해 수동으로 비활성화된 워크로드를 구분해요. 워크로드가 다시 스케일 업되면 조건은 reason: NotScaledToZero으로 False로 설정돼요.

암묵적 유지관리 모드 비활성화

HPA 구성을 변경할 필요 없이 대상에 대해 HPA를 암묵적으로 비활성화할 수 있어요. 대상의 원하는 레플리카 수가 0으로 설정되고 HPA의 최소 레플리카 수가 0보다 크면, 대상의 원하는 레플리카 수나 HPA의 최소 레플리카 수를 수동으로 조정해 재활성화할 때까지 HPA는 대상을 조정하는 것을 멈추고(자기 자신에 ScalingActive 조건을 false로 설정)요.

Deployment와 StatefulSet을 수평 오토스케일링으로 마이그레이션

HPA가 활성화되면 Deployment 및/또는 StatefulSet의 spec.replicas 값을 매니페스트에서 제거하는 것이 권장돼요. 이렇게 하지 않으면 그 객체에 변경이 적용될 때마다, 예를 들어 kubectl apply -f deployment.yaml을 통해, 쿠버네티스가 현재 파드 수를 spec.replicas 키의 값으로 스케일링하도록 지시할 거예요. 이것은 원하지 않을 수 있고 HPA가 활성 상태일 때 문제가 될 수 있으며, 스러싱이나 플래핑 동작을 초래해요.

spec.replicas 제거는 이 키의 기본값이 1이므로 파드 수의 일회성 감소를 초래할 수 있음을 명심하세요(Deployment Replicas 참조). 업데이트 시 1개를 제외한 모든 파드가 종료 절차를 시작할 거예요. 이후의 어떤 배포 애플리케이션도 정상적으로 동작하며 원하는 대로 롤링 업데이트 구성을 존중할 거예요. 배포를 수정하는 방식에 따라 다음 두 가지 방법 중 하나를 선택해 이 감소를 피할 수 있어요:

  • 클라이언트 사이드 적용(기본값):
kubectl apply edit-last-applied deployment/<deployment_name>
  • 편집기에서 spec.replicas를 제거해요. 편집기를 저장하고 종료하면 kubectl이 업데이트를 적용해요. 이 단계에서 파드 수에 대한 변경은 일어나지 않아요.

  • 이제 매니페스트에서 spec.replicas를 제거할 수 있어요. 소스 코드 관리를 사용한다면 변경 사항을 커밋하거나 업데이트를 추적하는 방식에 적절한 다른 단계를 취하세요.

  • 이제부터 kubectl apply -f deployment.yaml을 실행할 수 있어요.

  • 서버 사이드 적용:

서버 사이드 적용을 사용할 때 이 정확한 사용 사례를 다루는 소유권 이전 지침을 따를 수 있어요.

더 알아보기 (Learn more)

클러스터에서 오토스케일링을 구성한다면 올바른 수의 노드를 실행하고 있는지 보장하기 위해 노드 오토스케일링 사용을 고려할 수도 있어요. 수직 파드 오토스케일링에 대해 더 읽을 수도 있어요.

HorizontalPodAutoscaler에 대한 자세한 정보:

  • 수평 파드 오토스케일링 연습 예시 읽기.
  • kubectl autoscale 문서 읽기.
  • 자신의 사용자 지정 메트릭 어댑터를 작성하고 싶다면 시작하기 위한 boilerplate 확인하기.
  • HorizontalPodAutoscaler의 API 참조 읽기.