# Kubernetes VPA(Vertical Pod Autoscaler) * 可以縮小過度資源請求的 pod,也可以根據使用情況隨時提升資源不足的 pod。 * 根據 pod 目前的資源使用情況和過去的資源使用情況,計算可能的未來資源使用量。 * HPA 是水平擴充,而 VPA 是垂直擴充。 * VPA 無法與 HPA 同時使用。 * VPA 不會刪除沒有在副本數控管的 pod。 * VPA 需要透過 Metrics Server 來監控 pod 的資源使用量。 * VPA 是 Kubernetes 中一項強大的功能,可以幫助用戶更有效地利用集群資源,提高應用的性能和可靠性。 ## 實作 * 安裝 vpa ``` $ helm repo add cowboysysop https://cowboysysop.github.io/charts/ $ helm -n kube-system install vertical-pod-autoscaler cowboysysop/vertical-pod-autoscaler ``` * VPA pod 檢查 ``` $ kubectl -n kube-system get pod -l app.kubernetes.io/name=vertical-pod-autoscaler NAME READY STATUS RESTARTS AGE vertical-pod-autoscaler-admission-controller-65c49ccbbf-g4lpd 1/1 Running 0 35s vertical-pod-autoscaler-recommender-7f56cbf565-b88qh 1/1 Running 0 35s vertical-pod-autoscaler-updater-559fff9df-z5fhp 1/1 Running 0 35s ``` * 建立測試用 deploy,資源要求 CPU `100m`,記憶體 `50Mi` ``` $ vim deploy.yaml apiVersion: apps/v1 kind: Deployment metadata: name: hamster spec: selector: matchLabels: app: hamster replicas: 2 template: metadata: labels: app: hamster spec: securityContext: runAsNonRoot: true runAsUser: 65534 # nobody containers: - name: hamster image: registry.k8s.io/ubuntu-slim:0.1 resources: requests: cpu: 100m memory: 50Mi command: ["/bin/sh"] args: - "-c" - "while true; do timeout 0.5s yes >/dev/null; sleep 0.5s; done" ``` ``` $ kubectl apply -f deploy.yaml $ kubectl top pod NAME CPU(cores) MEMORY(bytes) hamster-59cc68d575-j96f6 493m 0Mi hamster-59cc68d575-wsxgb 504m 0Mi ``` * 建立 VPA ``` $ vim vpa.yaml apiVersion: "autoscaling.k8s.io/v1" kind: VerticalPodAutoscaler metadata: name: hamster-vpa spec: # recommenders field can be unset when using the default recommender. # When using an alternative recommender, the alternative recommender's name # can be specified as the following in a list. # recommenders: # - name: 'alternative' targetRef: apiVersion: "apps/v1" kind: Deployment name: hamster resourcePolicy: containerPolicies: - containerName: '*' minAllowed: cpu: 100m memory: 50Mi maxAllowed: cpu: 1 memory: 500Mi controlledResources: ["cpu", "memory"] ``` * 原本的 pod 經過資源調整後,pod 會被砍掉重建 ``` $ kubectl apply -f vpa.yaml verticalpodautoscaler.autoscaling.k8s.io/hamster-vpa created $ kubectl get vpa NAME MODE CPU MEM PROVIDED AGE hamster-vpa Auto 587m 262144k True 18s $ kubectl get po NAME READY STATUS RESTARTS AGE hamster-59cc68d575-j96f6 1/1 Terminating 0 4m2s hamster-59cc68d575-ndb54 1/1 Running 0 18s hamster-59cc68d575-nf8zs 1/1 Running 0 78s $ kubectl top po NAME CPU(cores) MEMORY(bytes) hamster-59cc68d575-ndb54 499m 0Mi hamster-59cc68d575-nf8zs 499m 0Mi ``` * 經過 VPA 的修改,CPU 被改成 `587m`,記憶改成 `262144k` ``` $ kubectl get pod hamster-59cc68d575-ndb54 -o yaml ...... spec: containers: - args: - -c - while true; do timeout 0.5s yes >/dev/null; sleep 0.5s; done command: - /bin/sh image: registry.k8s.io/ubuntu-slim:0.1 imagePullPolicy: IfNotPresent name: hamster resources: requests: cpu: 587m memory: 262144k ....... ``` * 環境復原 ``` $ kubectl delete -f deploy.yaml $ kubectl delete -f vpa.yaml ``` ## 驗證資源如果一開始開太高,是否會自動下修 * 設定資源 CPU `1000m`,記憶體 `1000Mi` ``` $ vim deploy2.yaml apiVersion: apps/v1 kind: Deployment metadata: name: hamster spec: selector: matchLabels: app: hamster replicas: 2 template: metadata: labels: app: hamster spec: containers: - name: hamster image: nginx resources: requests: cpu: 1000m memory: 1000Mi ``` ``` $ kubectl apply2 -f deploy.yaml deployment.apps/hamster created $ kubectl top pod NAME CPU(cores) MEMORY(bytes) hamster-68877945fb-794hx 0m 4Mi hamster-68877945fb-rhdq8 0m 5Mi ``` ``` $ vim vpa2.yaml apiVersion: "autoscaling.k8s.io/v1" kind: VerticalPodAutoscaler metadata: name: hamster-vpa spec: # recommenders field can be unset when using the default recommender. # When using an alternative recommender, the alternative recommender's name # can be specified as the following in a list. # recommenders: # - name: 'alternative' targetRef: apiVersion: "apps/v1" kind: Deployment name: hamster resourcePolicy: containerPolicies: - containerName: '*' minAllowed: cpu: 10m memory: 50Mi maxAllowed: cpu: 200m memory: 100Mi controlledResources: ["cpu", "memory"] $ kubectl apply -f vpa2.yaml ``` ``` $ kubectl get vpa NAME MODE CPU MEM PROVIDED AGE hamster-vpa Auto 200m 100Mi True 78s $ kubectl get po NAME READY STATUS RESTARTS AGE hamster-68877945fb-mkhzh 1/1 Running 0 54s hamster-68877945fb-ncfmx 1/1 Running 0 8s ``` * 已修改為 CPU `200m`,記憶體 `100Mi` ``` $ kubectl get po hamster-68877945fb-mkhzh -o yaml ...... spec: containers: - image: nginx imagePullPolicy: Always name: hamster resources: requests: cpu: 200m memory: 100Mi ..... ``` * 環境復原 ``` $ kubectl delete -f deploy2.yaml $ kubectl delete -f vpa2.yaml ``` ## 參考連結 https://medium.com/@seifeddinerajhi/kubernetes-autoscaling-achieving-scalability-and-efficiency-e0230cf6013 https://www.lixueduan.com/posts/kubernetes/12-vpa/