본문 바로가기

Container/Kubernetes

[K8S] Autoscaling - VPA

🍀 In-place Resize of Pod Resource 

kubernetes v1.27 의 alpha버전부터 사용 가능하며, pod나 container를 restart 하는 것 없이 CPU와 memory를 resizing 하는 방법이다. 

$ FEATURE_GATES=InPlacePodVerticalScaling=true
  • YAML
spec:
  containers:
  - name: qos-demo-ctr-5
    image: nginx
    resizePolicy:
    - resourceName: cpu
      restartPolicy: NotRequired
    - resourceName: memory
      restartPolicy: RestartContainer

 

Limitations

  • 오직 CPU, memory resources만 변경할 수 있다.
  • Pod QoS Class는 변경할 수 없다.
  • Init containers와 Ephemeral Containers는 resize할 수 없다.
  • Resource requests와 limits은 일단 설정되고나면 지울 수 없다.

 

Manual Resources scaling

 

  • Kubernetes에서 requests와 limits를 설정해야 하는데,
    너무 낮게 설정하면 Out of Memory(OOM) 오류 발생/ 너무 높게 설정하면 리소스 낭비 발생
  • Pod의 CPU/메모리 사용량은 시간에 따라 변동되는데, 이를 수동으로 조정하는 것은 비효율적이다.

 

# 리소스 사용량 확인
$ kubectl top pod <pod-name>

# 리소스 사용량 변경
$ kubectl edit deployment <pod-name>

 

Vertical Pod Autoscaler (VPA)

  • VPA는 쿠버네티스에 built-in되어 있지 않아서, 따로 deploy해 주어야 한다.
$ kubectl apply -f https://github.com/kubernetes/autoscaler/releases/latest/download/vertical-pod-autoscaler.yaml
  • Pod 자체의 CPU, 메모리 할당량을 동적으로 조절 (= request 및 limit 자동 조절)
  • 💡 Pod의 개수는 그대로 유지하면서, 리소스 사용량만 조정
  • 예를 들어, 특정 Pod이 CPU 200m를 사용 중인데 부족하면 자동으로 500m로 증가 가능

 

 

VPA 구성 요소 3가지

 

  • VPA Recommender (리소스 추천)
    • Pod의 CPU 및 메모리 사용량을 모니터링하고 적절한 값을 계산
    • "이 Pod은 CPU 500m, 메모리 512Mi가 적절할 것 같다"
  • VPA Updater (Pod 재시작)
    • Pod의 리소스 변경이 필요하면 Pod을 삭제하고 새로운 값으로 다시 시작
    • ⭐️ 기존 Pod를 직접 변경할 수 없기 때문에 반드시 재시작된다.
  • VPA Admission Controller (새로운 Pod의 요청 값 자동 설정)
    • 새로 생성되는 Pod에 대해 적절한 requests 값을 자동으로 설정

 

# vpa의 admission-controller, recommender, updater 총 3개가 구성되어 있어야 한다.
$ kubectl get pods -n kube-system | grep vpa


$ kubectl get deploy -n kube-system
NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
coredns                    2/2     2            2           14m
vpa-admission-controller   1/1     1            1           3m12s
vpa-recommender            1/1     1            1           3m12s
vpa-updater                1/1     1            1           3m13s

 

VPA updateMode 

"Auto" VPA가 recommended numbers에 따라 리소스를 자동 조정하고 Pod을 재시작
✨ In-place Update of Pod Resource가 설정되어 있을 때 적용된다.
"Recreate" Pod을 재시작하지만, 직접 수동으로 설정 필요
"Off" VPA가 리소스를 추천만 하고 적용하지 않음
"Initial" Pod가 생성될 때만 적용된다. (나중에는 X)

 

VPA vs HPA

  VPA (Vertical Pod Autoscaler) HPA (Horizontal Pod Autoscaler)
조정 대상 Pod의 CPU/메모리 리소스 Pod 개수(Replicas)
작동 방식 Pod의 resource 요청 값을 조정 후 Pod 재시작 Pod 부하에 따라 개수 조정(keep existing pod running)
적용 시점 일정 시간 동안 데이터 수집 후 적용
(Pod 재시작을 요구하기 때문 - delay 발생)
실시간 부하에 따라 즉시 적용
비용 관점 CPU/memory의 over-provisioning 예방 불필요한 Idle pods 피하기
사용 예시 고정된 개수의 Pod에서 리소스 조정 필요할 때 트래픽 증가 시 Pod 개수를 늘려야 할 때

 

Cluster Autoscaler (CA)

  • 클러스터의 노드 개수를 자동으로 조정
  • 💡 Pod이 더 이상 스케줄링될 공간이 없으면 노드를 추가 / 필요 없으면 노드 제거
  • 주로 클라우드 환경(AWS, GCP, Azure)에서 사용
  • 클러스터 내에서 스케줄링할 리소스가 부족한 경우 자동으로 새 노드를 추가

 

참고:

[ VPA 설치 실습 ]

 

1. CRD (Custom Resources Definition) 설치

controlplane ~ ➜  kubectl apply -f /root/vpa-crds.yml
customresourcedefinition.apiextensions.k8s.io/verticalpodautoscalercheckpoints.autoscaling.k8s.io created
customresourcedefinition.apiextensions.k8s.io/verticalpodautoscalers.autoscaling.k8s.io created

controlplane ~ ➜  kubectl apply -f /root/vpa-rbac.yml
clusterrole.rbac.authorization.k8s.io/system:metrics-reader created
...
serviceaccount/vpa-admission-controller created
serviceaccount/vpa-recommender created
serviceaccount/vpa-updater created
...

# 또는
$ git clone https://github.com/kubernetes/autoscaler.git
$ cd autoscaler/vertical-pod-autoscaler
$ ./hack/vpa-up.sh

 

2. CRD 설치 확인

controlplane ~ ➜  kubectl get crds
NAME                                                  CREATED AT
verticalpodautoscalercheckpoints.autoscaling.k8s.io   2025-02-26T03:07:35Z
verticalpodautoscalers.autoscaling.k8s.io             2025-02-26T03:07:35Z

 

3. vpa deploy 확인

controlplane ~ ➜  kubectl get deploy -n kube-system
NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
coredns                    2/2     2            2           17m
vpa-admission-controller   1/1     1            1           6m45s
vpa-recommender            1/1     1            1           6m45s
vpa-updater                1/1     1            1           6m46s

 

[ 실습 2 ] 

 

1. vpa 배포하기

controlplane ~ ➜ cat vpa-cpu.yml
apiVersion: "autoscaling.k8s.io/v1"
kind: VerticalPodAutoscaler
metadata:
  name: flask-app
spec:
  targetRef:
    apiVersion: "apps/v1"
    kind: Deployment
    name: flask-app-4
  updatePolicy:
    updateMode: "Off"  # You can set this to "Auto" if you want automatic updates
  resourcePolicy:
    containerPolicies:
      - containerName: '*'
        minAllowed:
          cpu: 100m
        maxAllowed:
          cpu: 1000m
        controlledResources: ["cpu"]
        
controlplane ~ ➜  kubectl apply -f vpa-cpu.yml 
verticalpodautoscaler.autoscaling.k8s.io/flask-app created

controlplane ~ ➜  kubectl get vpa
NAME        MODE   CPU   MEM   PROVIDED   AGE
flask-app   Off                           5s

 2. kubectl get vpa flask-app-vpa → flask-app-vpa VPA 객체 조회

controlplane ~ ➜  kubectl get vpa flask-app -o yaml
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"autoscaling.k8s.io/v1","kind":"VerticalPodAutoscaler","metadata":{"annotations":{},"name":"flask-app","namespace":"default"},"spec":{"resourcePolicy":{"containerPolicies":[{"containerName":"*","controlledResources":["cpu"],"maxAllowed":{"cpu":"1000m"},"minAllowed":{"cpu":"100m"}}]},"targetRef":{"apiVersion":"apps/v1","kind":"Deployment","name":"flask-app-4"},"updatePolicy":{"updateMode":"Off"}}}
  creationTimestamp: "2025-02-26T04:47:06Z"
  generation: 1
  name: flask-app
  namespace: default
  resourceVersion: "1737"
  uid: f0434ec9-f457-40fc-92ac-1d57f5ebc8df
spec:
  resourcePolicy:
    containerPolicies:
    - containerName: '*'
      controlledResources:
      - cpu
      maxAllowed:
        cpu: 1000m
      minAllowed:
        cpu: 100m
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: flask-app-4
  updatePolicy:
    updateMode: "Off"
status:
  conditions:
  - lastTransitionTime: "2025-02-26T04:47:24Z"
    status: "True"
    type: RecommendationProvided
  recommendation:
    containerRecommendations:
    - containerName: flask-app-4
      lowerBound:
        cpu: 100m
      target:
        cpu: 350m   # 이 값이 권장 cpu 값이다
      uncappedTarget:
        cpu: 350m
      upperBound:
        cpu: "1"
반응형

'Container > Kubernetes' 카테고리의 다른 글

[K8S] StorageClass  (0) 2025.02.26
[K8S] Gateway API  (0) 2025.02.26
[K8S] Autoscaling - HPA  (0) 2025.02.26
[K8S] Mutating/Validating Admission Controller  (0) 2025.02.24
[K8S] Admission Controller  (0) 2025.02.24