수직 파드 오토스케일링

수직 파드 오토스케일링 (Vertical Pod Autoscaling)

쿠버네티스에서 VerticalPodAutoscaler 는 실제 사용량에 맞게 인프라 리소스요청과 한도를 자동으로 조정할 목적으로 워크로드 관리 리소스(예: Deployment 또는 StatefulSet)를 자동으로 업데이트해요.

수직 스케일링은 리소스 수요 증가에 대한 응답으로 이미 실행 중인 워크로드용 Pods에 더 많은 리소스(예: 메모리나 CPU)를 할당하는 것을 의미해요. 이것을 권리자정(rightsizing) 또는 때로 오토파일럿(autopilot) 이라고도 해요. 이것은 부하를 분산하기 위해 더 많은 파드를 배포하는 수평 스케일링과 다르다는 점을 기억하세요.

리소스 사용량이 감소하고 파드 리소스 요청이 최적 수준보다 위로 올라가면, VerticalPodAutoscaler는 워크로드 리소스(Deployment, StatefulSet, 또는 그와 유사한 리소스)에 리소스 요청을 다시 낮추도록 지시해 리소스 낭비를 방지해요.

VerticalPodAutoscaler는 쿠버네티스 API 리소스와 컨트롤러로 구현돼요. 리소스가 컨트롤러의 동작을 결정해요. 쿠버네티스 데이터 플레인 안에서 실행되는 수직 파드 오토스케일링 컨트롤러는 과거 리소스 사용률 분석, 클러스터에서 사용 가능한 리소스 양, 그리고 OOM(메모리 부족) 조건 같은 실시간 이벤트에 기반해 대상(예: Deployment)의 리소스 요청과 한도를 주기적으로 조정해요.

출처: 문서

본문

API 객체

VerticalPodAutoscaler는 쿠버네티스의 Custom Resource Definition (CRD)로 정의돼요. 핵심 쿠버네티스 API의 일부인 HorizontalPodAutoscaler와 달리 VPA는 클러스터에 별도로 설치해야 해요.

현재 stable API 버전은 autoscaling.k8s.io/v1 예요. VPA 설치와 API에 대한 자세한 내용은 VPA GitHub 저장소에서 확인할 수 있어요.

VerticalPodAutoscaler는 어떻게 동작하나요?

그림 1. VerticalPodAutoscaler가 Deployment의 파드 리소스 요청과 한도를 제어함

쿠버네티스는 간헐적으로 실행되는(연속 프로세스가 아닌) 여러 협력 컴포넌트를 통해 수직 파드 오토스케일링을 구현해요. VPA는 세 가지 주요 컴포넌트로 구성돼요:

  • 리소스 사용량을 분석하고 권장 사항을 제공하는 recommender
  • 파드 리소스 요청을 축출(evict)하거나 제자리에서 수정해 업데이트하는 updater
  • 그리고 리소스 권장 사항을 새 파드나 재생성된 파드에 적용하는 VPA admission controller webhook

각 기간마다 한 번 Recommender는 각 VerticalPodAutoscaler 정의가 대상으로 하는 파드의 리소스 사용률을 조회해요. Recommender는 targetRef 로 정의된 대상 리소스를 찾은 다음 대상 리소스의 .spec.selector 라벨에 따라 파드를 선택하고, 리소스 메트릭 API에서 메트릭을 얻어 실제 CPU·메모리 소비를 분석해요.

Recommender는 VerticalPodAutoscaler가 대상으로 하는 각 파드에 대한 현재·과거 리소스 사용 데이터(CPU와 메모리)를 모두 분석해요. 다음을 검토해요:

  • 추세를 식별하기 위한 시간 경과에 따른 과거 소비 패턴
  • 충분한 헤드룸을 보장하기 위한 최고 사용량과 변동성
  • OOM(메모리 부족) 이벤트와 다른 리소스 관련 사고

이 분석에 기반해 Recommender는 세 가지 유형의 권장 사항을 계산해요:

  • 타겟 권장 사항(일반적인 사용에 대한 최적 리소스)
  • 하한(lower bound, 최소 실행 가능 리소스)
  • 상한(upper bound, 최대 합리적 리소스)

이 권장 사항들은 VerticalPodAutoscaler 리소스의 .status.recommendation 필드에 저장돼요.

updater 컴포넌트는 VerticalPodAutoscaler 리소스를 모니터링하고 현재 파드 리소스 요청을 권장 사항과 비교해요. 차이가 구성된 임계값을 초과하고 업데이트 정책이 허용하면 updater는 다음 중 하나를 할 수 있어요:

  • 파드를 축출해 새 리소스 요청으로 재생성되게 하기(전통적 접근 방식)
  • 클러스터가 제자리 파드 리소스 업데이트를 지원할 때 축출 없이 파드 리소스를 제자리에서 업데이트하기

선택된 방법은 구성된 업데이트 모드, 클러스터 기능, 필요한 리소스 변경 유형에 따라 달라져요. 제자리 업데이트는 가능하면 파드 중단을 피하지만 수정할 수 있는 리소스에 제한이 있을 수 있어요. updater는 서비스 영향을 최소화하기 위해 PodDisruptionBudgets를 존중해요.

admission controller 는 파드 생성 요청을 가로채는 변경(mutating) webhook으로 동작해요. 파드가 VerticalPodAutoscaler의 대상인지 확인하고, 그렇다면 파드가 생성되기 전에 권장 리소스 요청과 한도를 적용해요. 더 구체적으로 admission controller는 VerticalPodAutoscaler 리소스의 .status.recommendation 항목에서 Target 권장 사항을 새 리소스 요청으로 사용해요. admission controller는 초기 배포, updater의 축출 후, 또는 스케일링 작업으로 인해 생성되는 새 파드가 적절한 크기의 리소스 할당으로 시작하도록 보장해요.

VerticalPodAutoscaler는 클러스터에 쿠버네티스 Metrics Server 애드온 같은 메트릭 소스가 설치되어 있어야 해요. VPA 컴포넌트는 metrics.k8s.io API에서 메트릭을 가져와요. Metrics Server는 대부분의 클러스터에서 기본으로 배포되지 않으므로 별도로 시작해야 해요. 리소스 메트릭에 대한 자세한 내용은 Metrics Server를 참고해요.

업데이트 모드 (Update modes)

VerticalPodAutoscaler는 리소스 권장 사항이 파드에 어떻게·언제 적용되는지 제어하는 다양한 업데이트 모드 를 지원해요. VPA 스펙의 updatePolicy 아래 updateMode 필드로 업데이트 모드를 구성해요:

---
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: my-app-vpa
spec:
  targetRef:
    apiVersion: "apps/v1"
    kind: Deployment
    name: my-app
  updatePolicy:
    updateMode: "Recreate"  # Off, Initial, Recreate, InPlaceOrRecreate, InPlace

Off

Off 업데이트 모드에서 VPA recommender는 여전히 리소스 사용량을 분석하고 권장 사항을 생성하지만, 이 권장 사항은 파드에 자동으로 적용되지 않아요. 권장 사항은 VPA 객체의 .status 필드에만 저장돼요.

kubectl 같은 도구를 사용해 .status 와 그 안의 권장 사항을 볼 수 있어요.

Initial

Initial 모드에서 VPA는 파드가 처음 생성될 때만 리소스 요청을 설정해요. 시간이 지나 권장 사항이 바뀌어도 이미 실행 중인 파드의 리소스를 업데이트하지 않아요. 권장 사항은 파드 생성 중에만 적용돼요.

Recreate

Recreate 모드에서 VPA는 현재 리소스 요청이 권장 사항과 크게 다르면 파드를 축출해 파드 리소스를 적극적으로 관리해요. 파드가 축출되면 워크로드 컨트롤러(Deployment, StatefulSet 등을 관리)가 교체 파드를 만들고, VPA admission controller가 새 파드에 업데이트된 리소스 요청을 적용해요.

InPlaceOrRecreate

InPlaceOrRecreate 모드에서 VPA는 가능하면 파드를 재시작하지 않고 파드 리소스 요청과 한도를 업데이트하려 해요. 하지만 특정 리소스 변경에 대해 제자리 업데이트를 수행할 수 없으면 VPA는 파드를 축출(Recreate 모드와 유사)하고 워크로드 컨트롤러가 업데이트된 리소스로 교체 파드를 만들도록 허용해요.

이 모드에서 updater는 제자리 컨테이너 리소스 크기 조정 기능을 사용해 권장 사항을 제자리에서 적용해요.

InPlace

이 모드는 VPA 1.7.0에서 alpha 기능으로 제공되며, InPlacePodVerticalScaling 클러스터 기능 게이트가 활성화된 쿠버네티스 1.33 이상과 VPA updater·admission controller에서 InPlace 기능 게이트가 활성화되어 있어야 해요. 파드를 중단하지 않고 업데이트를 적용하기 위해 제자리 파드 리사이즈 기능을 사용해요.

InPlace 모드에서 VPA는 파드를 재시작하거나 축출하지 않고 파드 리소스 요청과 한도를 업데이트하려 해요. InPlaceOrRecreate 와 달리 이 모드는 절대 축출로 폴백하지 않아요. 제자리 업데이트를 적용할 수 없으면(예: 노드에 충분한 용량이 없어서) VPA는 업데이트를 연기하고 이후 조정 루프에서 재시도해요.

InPlace 모드를 사용하려면 VPA updater와 admission controller 모두에서 InPlace 기능 게이트를 활성화해요:

--feature-gates=InPlace=true

그런 다음 VPA 스펙에서 updateMode"InPlace" 로 설정해요:

apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: my-app-vpa
spec:
  targetRef:
    apiVersion: "apps/v1"
    kind: Deployment
    name: my-app
  updatePolicy:
    updateMode: "InPlace"

InPlaceOrRecreate와의 핵심 차이: 리사이즈가 연기되거나 진행 중이거나 실행 불가능할 때 InPlace 모드는 업데이트가 얼마나 오래 보류되어 있든 항상 기다렸다가 재시도해요. 절대 파드를 축출하지 않아요.

Auto (사용 중단)

참고:

Auto 모드는 현재 Recreate 모드의 별칭이며 동일하게 동작해요. 자동 업데이트 전략의 향후 확장을 허용하기 위해 도입됐어요.

리소스 정책 (Resource policies)

리소스 정책은 VerticalPodAutoscaler가 권장 사항을 생성하고 업데이트를 적용하는 방식을 세밀하게 조정할 수 있게 해줘요. 리소스 권장 사항의 경계를 설정하고, 관리할 리소스를 지정하며, 파드 안의 개별 컨테이너에 대해 다른 정책을 구성할 수 있어요.

VPA 스펙의 resourcePolicy 필드에서 리소스 정책을 정의해요:

apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: my-app-vpa
spec:
  targetRef:
    apiVersion: "apps/v1"
    kind: Deployment
    name: my-app
  updatePolicy:
    updateMode: "Recreate"
  resourcePolicy:
    containerPolicies:
    - containerName: "application"
      minAllowed:
        cpu: 100m
        memory: 128Mi
      maxAllowed:
        cpu: 2
        memory: 2Gi
      controlledResources:
      - cpu
      - memory
      controlledValues: RequestsAndLimits

minAllowed와 maxAllowed

이 필드는 VPA 권장 사항의 경계를 설정해요. 실제 사용 데이터가 다른 값을 제안하더라도 VPA는 minAllowed 아래 또는 maxAllowed 위의 리소스를 절대 권장하지 않아요.

controlledResources

controlledResources 필드는 VPA가 파드의 컨테이너에 대해 관리해야 하는 리소스 유형을 지정해요. 지정하지 않으면 VPA는 기본적으로 CPU와 메모리를 모두 관리해요. VPA가 특정 리소스만 관리하도록 제한할 수 있어요. 유효한 리소스 이름은 cpumemory 예요.

controlledValues

controlledValues 필드는 VPA가 리소스 요청, 한도, 또는 둘 다를 제어하는지 결정해요:

그 두 개념에 대해 더 알아보려면 요청과 한도를 참고해요.

LimitRange 리소스

admission controller와 updater VPA 컴포넌트는 LimitRange에 정의된 제약을 준수하도록 권장 사항을 사후 처리해요. 쿠버네티스 클러스터에서 type Pod와 Container인 LimitRange 리소스를 확인해요.

예를 들어 Container LimitRange 리소스의 max 필드를 초과하면 두 VPA 컴포넌트 모두 한도를 max 필드에 정의된 값으로 낮추고, Pod 스펙의 요청-대-한도 비율을 유지하기 위해 요청도 비례적으로 감소시켜요.

더 알아보기 (Learn more)

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