수직형 Pod 오토스케일링
수직형 Pod 오토스케일링 (Vertical Pod Autoscaling)
쿠버네티스에서 VerticalPodAutoscaler는 워크로드 관리 [리소스](예: [Deployment]이나 [StatefulSet])를 자동으로 업데이트하여, 실제 사용량에 맞도록 인프라 [리소스]의 [requests and limits]를 자동으로 조정하는 것을 목표로 해요.
수직 스케일링은 리소스 수요가 증가할 때 워크로드에 대해 이미 실행 중인 [Pod]에 더 많은 리소스(예: 메모리나 CPU)를 할당하는 것을 의미합니다. 이것은 rightsizing 또는 때로는 autopilot이라고도 알려져 있어요. 이것은 부하를 분산하기 위해 더 많은 Pod를 배포하는 것을 의미하는 수평 스케일링과는 다릅니다.
리소스 사용량이 감소하고 Pod 리소스 요청이 최적 수준 이상이면, VerticalPodAutoscaler는 워크로드 리소스(Deployment, StatefulSet 또는 다른 유사 리소스)에 리소스 요청을 다시 낮추도록 지시하여 리소스 낭비를 방지합니다.
VerticalPodAutoscaler는 쿠버네티스 API 리소스와 [컨트롤러]로 구현됩니다. 리소스는 컨트롤러의 동작을 결정합니다. 쿠버네티스 데이터 플레인 안에서 실행되는 수직 Pod 오토스케일링 컨트롤러는, 과거 리소스 사용률 분석, 클러스터에서 사용 가능한 리소스 양, OOM(out-of-memory) 조건 같은 실시간 이벤트를 기반으로 대상(예: Deployment)의 리소스 requests와 limits를 주기적으로 조정합니다.
API 객체 (API object)
VerticalPodAutoscaler는 쿠버네티스에서 Custom Resource Definition으로 정의됩니다. 핵심 쿠버네티스 API의 일부인 HorizontalPodAutoscaler와 달리, VPA는 클러스터에 별도로 설치해야 해요.
현재 안정적 API 버전은 autoscaling.k8s.io/v1입니다. VPA 설치와 API에 대한 자세한 내용은 VPA GitHub 저장소에서 찾을 수 있어요.
VerticalPodAutoscaler는 어떻게 동작하나요? (How does a VerticalPodAutoscaler work?)
쿠버네티스는 간헐적으로 실행되는 여러 협력 컴포넌트를 통해 수직 Pod 오토스케일링을 구현합니다 (연속적인 프로세스가 아닙니다). VPA는 세 가지 주요 컴포넌트로 구성됩니다.
- recommender — 리소스 사용량을 분석하고 권장 사항을 제공해요.
- updater — Pod를 축출하거나 제자리에서 수정하여 Pod 리소스 요청을 조정합니다.
- VPA admission controller webhook — 새로 생성되거나 다시 생성된 Pod에 리소스 권장 사항을 적용해요.
각 기간 동안 한 번씩 Recommender는 각 VerticalPodAutoscaler 정의가 대상으로 하는 Pod의 리소스 사용률을 쿼리합니다. Recommender는 targetRef가 정의한 대상 리소스를 찾은 다음, 대상 리소스의 .spec.selector 레이블을 기반으로 pod를 선택하고, 리소스 메트릭 API에서 메트릭을 얻어 실제 CPU와 메모리 소비를 분석해요.
Recommender는 VerticalPodAutoscaler의 대상이 되는 각 Pod의 현재 및 과거 리소스 사용 데이터(CPU와 메모리)를 모두 분석합니다. 다음을 검사합니다.
- 추세를 식별하기 위한 시간에 따른 과거 소비 패턴
- 충분한 헤드룸을 보장하기 위한 최대 사용량과 변동
- OOM(out-of-memory) 이벤트 및 기타 리소스 관련 사건
이 분석을 기반으로 Recommender는 세 가지 유형의 권장 사항을 계산합니다.
- Target 권장 사항 (일반적인 사용을 위한 최적 리소스)
- Lower bound (최소 실현 가능 리소스)
- Upper bound (최대 합리적 리소스)
이 권장 사항들은 VerticalPodAutoscaler 리소스의 .status.recommendation 필드에 저장됩니다.
updater 컴포넌트는 VerticalPodAutoscaler 리소스를 모니터링하고 현재 Pod 리소스 요청을 권장 사항과 비교합니다. 차이가 구성된 임계값을 초과하고 업데이트 정책이 허용하면, updater는 다음 중 하나를 할 수 있어요.
- Pod를 축출하여 새 리소스 요청으로 재생성되도록 트리거 (전통적인 접근)
- 클러스터가 제자리 Pod 리소스 업데이트를 지원할 때 축출 없이 Pod 리소스를 제자리에서 업데이트
선택된 방법은 구성된 업데이트 모드, 클러스터 기능, 필요한 리소스 변경 유형에 따라 달라집니다. 제자리 업데이트는 가능하면 Pod 중단을 피하지만, 수정할 수 있는 리소스에 제한이 있을 수 있어요. updater는 서비스 영향을 최소화하기 위해 PodDisruptionBudgets을 존중합니다.
admission controller는 Pod 생성 요청을 가로채는 mutating webhook으로 동작합니다. Pod가 VerticalPodAutoscaler의 대상인지 확인하고, 그렇다면 Pod가 생성되기 전에 권장 리소스 requests와 limits를 적용합니다. 더 구체적으로, admission controller는 VerticalPodAutoscaler 리소스의 .status.recommendation 구역의 Target 권장 사항을 새 리소스 requests로 사용합니다. admission controller는 초기 배포 중, updater에 의한 축출 후, 또는 스케일링 작업으로 인해 생성되든, 새 Pod가 적절한 크기의 리소스 할당으로 시작하도록 보장합니다.
VerticalPodAutoscaler는 클러스터에 쿠버네티스의 Metrics Server [애드온] 같은 메트릭 소스가 설치되어 있어야 합니다. VPA 컴포넌트는 metrics.k8s.io API에서 메트릭을 가져옵니다. Metrics Server는 대부분의 클러스터에서 기본으로 배포되지 않으므로 별도로 실행해야 해요. 리소스 메트릭에 대한 자세한 내용은 Metrics Server를 참고하세요.
업데이트 모드 (Update modes)
VerticalPodAutoscaler는 리소스 권장 사항이 Pod에 어떻게, 언제 적용되는지 제어하는 다양한 업데이트 모드를 지원해요. updatePolicy 아래의 VPA 스펙에서 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는 여전히 리소스 사용량을 분석하고 권장 사항을 생성하지만, 이 권장 사항은 Pod에 자동으로 적용되지 않아요. 권장 사항은 VPA 객체의 .status 필드에만 저장됩니다.
kubectl 같은 도구를 사용해 .status와 그 안의 권장 사항을 볼 수 있어요.
Initial
Initial 모드에서 VPA는 Pod가 처음 생성될 때만 리소스 요청을 설정합니다. 권장 사항이 시간이 지나도 바뀌더라도 이미 실행 중인 Pod의 리소스는 업데이트하지 않아요. 권장 사항은 Pod 생성 중에만 적용됩니다.
Recreate
Recreate 모드에서 VPA는 현재 리소스 요청이 권장 사항과 크게 다를 때 Pod를 축출하여 Pod 리소스를 적극적으로 관리합니다. Pod가 축출되면 워크로드 컨트롤러(Deployment, StatefulSet 등을 관리하는)가 교체 Pod를 만들고, VPA admission controller가 새 Pod에 업데이트된 리소스 요청을 적용합니다.
InPlaceOrRecreate
InPlaceOrRecreate 모드에서 VPA는 가능하면 Pod를 재시작하지 않고 리소스 requests와 limits를 업데이트하려고 시도해요. 그러나 특정 리소스 변경에 대해 제자리 업데이트를 수행할 수 없으면, VPA는 Pod 축출로 대체되고(Recreate 모드와 유사) 워크로드 컨트롤러가 업데이트된 리소스로 교체 Pod를 만들도록 허용합니다.
이 모드에서 updater는 Resize Container Resources In-Place 기능을 사용해 제자리에서 권장 사항을 적용합니다.
InPlace
이 모드는 VPA 1.7.0에서 alpha 기능으로 사용할 수 있으며, InPlacePodVerticalScaling 클러스터 기능 게이트가 활성화된 Kubernetes 1.33 이상과 VPA updater 및 admission controller의 InPlace 기능 게이트가 필요합니다. 제자리 Pod 리사이즈 기능을 사용해 Pod를 중단하지 않고 업데이트를 적용합니다.
InPlace 모드에서 VPA는 Pod를 재시작하거나 축출하지 않고 리소스 requests와 limits를 업데이트하려고 시도합니다. 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 모드는 항상 기다렸다 재시도합니다. 업데이트가 얼마나 오래 대기 중이든 절대 Pod를 축출하지 않아요.
Auto (폐기됨 / deprecated)
참고:
Auto업데이트 모드는 VPA 버전 1.4.0부터 폐기되었습니다. 축출 기반 업데이트에는Recreate를, 축출 대체가 있는 제자리 업데이트에는InPlaceOrRecreate를 사용하세요.
Auto 모드는 현재 Recreate 모드의 별칭이며 동일하게 동작합니다. 자동 업데이트 전략의 미래 확장을 허용하기 위해 도입되었어요.
리소스 정책 (Resource policies)
리소스 정책을 사용하면 VerticalPodAutoscaler가 권장 사항을 생성하고 업데이트를 적용하는 방법을 세밀하게 조정할 수 있어요. 리소스 권장 사항의 경계를 설정하고, 관리할 리소스를 지정하고, Pod 안의 개별 컨테이너에 대해 다른 정책을 구성할 수 있습니다.
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가 Pod 안의 컨테이너에 대해 어떤 리소스 유형을 관리할지 지정합니다. 지정하지 않으면 VPA는 기본적으로 CPU와 메모리 모두를 관리합니다. VPA를 특정 리소스만 관리하도록 제한할 수 있습니다. 유효한 리소스 이름은 cpu와 memory입니다.
controlledValues
controlledValues 필드는 VPA가 리소스 requests, limits, 또는 둘 다를 제어할지 결정합니다.
- RequestsAndLimits — VPA가 requests와 limits를 모두 설정합니다. limit은 Pod 스펙에서 정의된 request-to-limit 비율에 따라 request에 비례해 확장됩니다. 이것이 기본 모드입니다.
- RequestsOnly — VPA는 requests만 설정하고 limits는 변경하지 않습니다. Limits는 존중되며, 사용량이 한도를 초과하면 여전히 스로틀링이나 OOM kill을 트리거할 수 있어요.
이 두 개념에 대해 더 배우려면 requests and limits를 참고하세요.
LimitRange 리소스 (LimitRange resources)
admission controller와 updater VPA 컴포넌트는 [LimitRanges]에 정의된 제약 조건을 준수하도록 권장 사항을 후처리합니다. type이 Pod와 Container인 LimitRange 리소스가 쿠버네티스 클러스터에서 확인됩니다.
예를 들어 Container LimitRange 리소스의 max 필드가 초과되면, 두 VPA 컴포넌트 모두 limit을 max 필드에 정의된 값으로 낮추고, Pod 스펙의 request-to-limit 비율을 유지하기 위해 request도 비례적으로 감소시킵니다.
다음 내용 (What's next)
클러스터에서 오토스케일링을 구성한다면, 올바른 수의 노드를 실행하고 있는지 확인하기 위해 노드 오토스케일링을 고려할 수도 있어요. 수평 Pod 오토스케일링에 대해 더 읽어볼 수도 있습니다.