Kubernetes Pod垂直自動伸縮(VPA)

VPA 簡介

VPA 全稱 Vertical Pod Autoscaler,即垂直 Pod 自動擴縮容,它根據(jù)容器資源使用率自動設(shè)置 CPU 和 內(nèi)存 的requests,從而允許在節(jié)點上進行適當?shù)恼{(diào)度,以便為每個 Pod 提供適當?shù)馁Y源。
它既可以縮小過度請求資源的容器,也可以根據(jù)其使用情況隨時提升資源不足的容量。
PS: VPA不會改變Pod的資源limits值。

廢話不多說,直接上圖,看VPA工作流程


image.png

接下來開始實戰(zhàn)

部署metrics-server

1、下載部署清單文件

wget  https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.3.7/components.yaml

2、修改components.yaml文件

  • 修改了鏡像地址,gcr.io為我自己的倉庫
  • 修改了metrics-server啟動參數(shù)args,要不然會報錯unable to fully scrape metrics from source kubelet_summary...
- name: metrics-server
        image: scofield/metrics-server:v0.3.7
        imagePullPolicy: IfNotPresent
        args:
          - --cert-dir=/tmp
          - --secure-port=4443
          - /metrics-server
          - --kubelet-insecure-tls
          - --kubelet-preferred-address-types=InternalIP

3、執(zhí)行部署

kubectl  apply -f components.yaml

4、驗證

[root@k8s-node001 metrics-server]# kubectl  get po -n kube-system
NAME                                       READY   STATUS    RESTARTS   AGE
metrics-server-7947cb98b6-xw6b8            1/1     Running   0          10m

能獲取要top信息視為成功
[root@k8s-node001 metrics-server]# kubectl  top nodes
NAME          CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
k8s-node001   618m         7%       4796Mi           15%
k8s-node003   551m         6%       5522Mi           17%
k8s-node004   308m         3%       5830Mi           18%
k8s-node005   526m         6%       5997Mi           38%
k8s-node002   591m         7%       5306Mi           33%

部署vertical-pod-autoscaler

1、克隆autoscaler項目

git clone https://github.com/kubernetes/autoscaler.git

2、修改部署文件,將gcr倉庫該為我自己的倉庫

admission-controller-deployment.yaml
us.gcr.io/k8s-artifacts-prod/autoscaling/vpa-admission-controller:0.8.0
改為
scofield/vpa-admission-controller:0.8.0

recommender-deployment.yaml
us.gcr.io/k8s-artifacts-prod/autoscaling/vpa-recommender:0.8.0
改為
image: scofield/vpa-recommender:0.8.0

updater-deployment.yaml
us.gcr.io/k8s-artifacts-prod/autoscaling/vpa-updater:0.8.0
改為
scofield/vpa-updater:0.8.0

3、部署

[root@k8s-node001 vertical-pod-autoscaler]#  cd autoscaler/vertical-pod-autoscaler
[root@k8s-node001 vertical-pod-autoscaler]#  ./hack/vpa-up.sh
Warning: apiextensions.k8s.io/v1beta1 CustomResourceDefinition is deprecated in v1.16+, unavailable in v1.22+; use apiextensions.k8s.io/v1 CustomResourceDefinition
customresourcedefinition.apiextensions.k8s.io/verticalpodautoscalers.autoscaling.k8s.io created
customresourcedefinition.apiextensions.k8s.io/verticalpodautoscalercheckpoints.autoscaling.k8s.io created
clusterrole.rbac.authorization.k8s.io/system:metrics-reader created
clusterrole.rbac.authorization.k8s.io/system:vpa-actor created
clusterrole.rbac.authorization.k8s.io/system:vpa-checkpoint-actor created
clusterrole.rbac.authorization.k8s.io/system:evictioner created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-reader created
clusterrolebinding.rbac.authorization.k8s.io/system:vpa-actor created
clusterrolebinding.rbac.authorization.k8s.io/system:vpa-checkpoint-actor created
clusterrole.rbac.authorization.k8s.io/system:vpa-target-reader created
clusterrolebinding.rbac.authorization.k8s.io/system:vpa-target-reader-binding created
clusterrolebinding.rbac.authorization.k8s.io/system:vpa-evictionter-binding created
serviceaccount/vpa-admission-controller created
clusterrole.rbac.authorization.k8s.io/system:vpa-admission-controller created
clusterrolebinding.rbac.authorization.k8s.io/system:vpa-admission-controller created
clusterrole.rbac.authorization.k8s.io/system:vpa-status-reader created
clusterrolebinding.rbac.authorization.k8s.io/system:vpa-status-reader-binding created
serviceaccount/vpa-updater created
deployment.apps/vpa-updater created
serviceaccount/vpa-recommender created
deployment.apps/vpa-recommender created
Generating certs for the VPA Admission Controller in /tmp/vpa-certs.
Generating RSA private key, 2048 bit long modulus (2 primes)
............................................................................+++++
.+++++
e is 65537 (0x010001)
Generating RSA private key, 2048 bit long modulus (2 primes)
............+++++
...........................................................................+++++
e is 65537 (0x010001)
Signature ok
subject=CN = vpa-webhook.kube-system.svc
Getting CA Private Key
Uploading certs to the cluster.
secret/vpa-tls-certs created
Deleting /tmp/vpa-certs.
deployment.apps/vpa-admission-controller created
service/vpa-webhook created

4、查看結(jié)果,可以看到metrics-server和vpa都已經(jīng)正常運行了

[root@k8s-node001 autoscaler-master]# kubectl  get po -n kube-system
NAME                                        READY   STATUS    RESTARTS   AGE
metrics-server-7947cb98b6-xw6b8             1/1     Running   0          46m
vpa-admission-controller-7d87559549-g77h9   1/1     Running   0          10m
vpa-recommender-84bf7fb9db-65669            1/1     Running   0          10m
vpa-updater-79cc46c7bb-5p889                1/1     Running   0          10m

示例1 updateMode: "Off"

1、首先我們部署一個nginx服務(wù),部署到namespace: vpa中

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: vpa
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx
        resources:
          requests:
            cpu: 100m
            memory: 250Mi

看下結(jié)果,正常運行了2個pod

[root@k8s-node001 examples]# kubectl  get po -n vpa
NAME                         READY   STATUS    RESTARTS   AGE
pod/nginx-6884b849f7-fswx5   1/1     Running   0          5m54s
pod/nginx-6884b849f7-wz6b8   1/1     Running   0          5m54s

2、為了便宜壓測,我們創(chuàng)建一個NodePort類型的service

[root@k8s-node001 examples]# cat  nginx-vpa-ingress.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: vpa
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx

[root@k8s-node001 examples]# kubectl  get svc -n vpa
NAME    TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
nginx   NodePort   10.97.250.131   <none>        80:32621/TCP   55s

[root@k8s-node001 examples]# curl -I   192.168.100.185:32621
HTTP/1.1 200 OK

3、創(chuàng)建VPA
這里先使用updateMode: "Off"模式,這種模式僅獲取資源推薦不更新Pod

[root@k8s-node001 examples]# cat   nginx-vpa-demo.yaml
apiVersion: autoscaling.k8s.io/v1beta2
kind: VerticalPodAutoscaler
metadata:
  name: nginx-vpa
  namespace: vpa
spec:
  targetRef:
    apiVersion: "apps/v1"
    kind: Deployment
    name: nginx
  updatePolicy:
    updateMode: "Off"
  resourcePolicy:
    containerPolicies:
    - containerName: "nginx"
      minAllowed:
        cpu: "250m"
        memory: "100Mi"
      maxAllowed:
        cpu: "2000m"
        memory: "2048Mi"

4、查看部署結(jié)果

[root@k8s-node001 examples]# kubectl  get vpa -n vpa
NAME        AGE
nginx-vpa   2m34s

5、使用describe查看vpa詳情,主要關(guān)注Container Recommendations

[root@k8s-node001 examples]# kubectl  describe  vpa nginx-vpa   -n vpa
Name:         nginx-vpa
Namespace:    vpa
....略去10000字 哈哈......
  Update Policy:
    Update Mode:  Off
Status:
  Conditions:
    Last Transition Time:  2020-09-28T04:04:25Z
    Status:                True
    Type:                  RecommendationProvided
  Recommendation:
    Container Recommendations:
      Container Name:  nginx
      Lower Bound:
        Cpu:     250m
        Memory:  262144k
      Target:
        Cpu:     250m
        Memory:  262144k
      Uncapped Target:
        Cpu:     25m
        Memory:  262144k
      Upper Bound:
        Cpu:     803m
        Memory:  840190575
Events:          <none>

其中

Lower Bound:                 下限值
Target:                           推薦值
Upper Bound:                 上限值
Uncapped Target:           如果沒有為VPA提供最小或最大邊界,則表示目標利用率
上述結(jié)果表明,推薦的 Pod 的 CPU 請求為 25m,推薦的內(nèi)存請求為 262144k 字節(jié)。

6、現(xiàn)在我們對nginx進行壓測
執(zhí)行壓測命令

[root@k8s-node001 examples]# ab -c 100 -n 10000000 http://192.168.100.185:32621/
This is ApacheBench, Version 2.3 <$Revision: 1843412 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.100.185 (be patient)
Completed 1000000 requests
Completed 2000000 requests
Completed 3000000 requests

7、幾分鐘后再觀察VPA Recommendation變化

[root@k8s-node001 ~]# kubectl  describe  vpa nginx-vpa   -n vpa |tail -n 20 
  Conditions:
    Last Transition Time:  2020-09-28T04:04:25Z
    Status:                True
    Type:                  RecommendationProvided
  Recommendation:
    Container Recommendations:
      Container Name:  nginx
      Lower Bound:
        Cpu:     250m
        Memory:  262144k
      Target:
        Cpu:     476m
        Memory:  262144k
      Uncapped Target:
        Cpu:     476m
        Memory:  262144k
      Upper Bound:
        Cpu:     2
        Memory:  387578728
Events:          <none>

從輸出信息可以看出,VPA對Pod給出了推薦值:Cpu: 476m,因為我們這里設(shè)置了updateMode: "Off",所以不會更新Pod

示例2 updateMode: "Auto"

1、現(xiàn)在我把updateMode: "Auto",看看VPA會有什么動作
這里我把resources改為:memory: 50Mi,cpu: 100m

[root@k8s-node001 examples]# kubectl  apply -f nginx-vpa.yaml
deployment.apps/nginx created
[root@k8s-node001 examples]# cat nginx-vpa.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
  namespace: vpa
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx
        resources:
          requests:
            cpu: 100m
            memory: 50Mi

[root@k8s-node001 examples]# kubectl  get po  -n vpa
NAME                     READY   STATUS    RESTARTS   AGE
nginx-7ff65f974c-f4vgl   1/1     Running   0          114s
nginx-7ff65f974c-v9ccx   1/1     Running   0          114s

2、再次部署vpa,這里VPA部署文件nginx-vpa-demo.yaml只改了updateMode: "Auto"name: nginx-vpa-2

[root@k8s-node001 examples]# cat  nginx-vpa-demo.yaml
apiVersion: autoscaling.k8s.io/v1beta2
kind: VerticalPodAutoscaler
metadata:
  name: nginx-vpa-2
  namespace: vpa
spec:
  targetRef:
    apiVersion: "apps/v1"
    kind: Deployment
    name: nginx
  updatePolicy:
    updateMode: "Auto"
  resourcePolicy:
    containerPolicies:
    - containerName: "nginx"
      minAllowed:
        cpu: "250m"
        memory: "100Mi"
      maxAllowed:
        cpu: "2000m"
        memory: "2048Mi"

[root@k8s-node001 examples]# kubectl apply -f nginx-vpa-demo.yaml
verticalpodautoscaler.autoscaling.k8s.io/nginx-vpa created

[root@k8s-node001 examples]# kubectl  get vpa -n vpa
NAME        AGE
nginx-vpa-2   9s

3、再次壓測

ab -c 1000 -n 100000000 http://192.168.100.185:32621/

4、幾分鐘后,使用describe查看vpa詳情,同樣只關(guān)注Container Recommendations

[root@k8s-node001 ~]# kubectl  describe  vpa nginx-vpa-2    -n vpa |tail -n 30
      Min Allowed:
        Cpu:     250m
        Memory:  100Mi
  Target Ref:
    API Version:  apps/v1
    Kind:         Deployment
    Name:         nginx
  Update Policy:
    Update Mode:  Auto
Status:
  Conditions:
    Last Transition Time:  2020-09-28T04:48:25Z
    Status:                True
    Type:                  RecommendationProvided
  Recommendation:
    Container Recommendations:
      Container Name:  nginx
      Lower Bound:
        Cpu:     250m
        Memory:  262144k
      Target:
        Cpu:     476m
        Memory:  262144k
      Uncapped Target:
        Cpu:     476m
        Memory:  262144k
      Upper Bound:
        Cpu:     2
        Memory:  262144k
Events:          <none>

Target變成了Cpu: 587m ,Memory: 262144k

5、來看下event事件

[root@k8s-node001 ~]# kubectl  get event -n vpa
LAST SEEN   TYPE      REASON              OBJECT                        MESSAGE
33m         Normal    Pulling             pod/nginx-7ff65f974c-f4vgl    Pulling image "nginx"
33m         Normal    Pulled              pod/nginx-7ff65f974c-f4vgl    Successfully pulled image "nginx" in 15.880996269s
33m         Normal    Created             pod/nginx-7ff65f974c-f4vgl    Created container nginx
33m         Normal    Started             pod/nginx-7ff65f974c-f4vgl    Started container nginx
26m         Normal    EvictedByVPA        pod/nginx-7ff65f974c-f4vgl    Pod was evicted by VPA Updater to apply resource recommendation.
26m         Normal    Killing             pod/nginx-7ff65f974c-f4vgl    Stopping container nginx
35m         Normal    Scheduled           pod/nginx-7ff65f974c-hnzr5    Successfully assigned vpa/nginx-7ff65f974c-hnzr5 to k8s-node005
35m         Normal    Pulling             pod/nginx-7ff65f974c-hnzr5    Pulling image "nginx"
34m         Normal    Pulled              pod/nginx-7ff65f974c-hnzr5    Successfully pulled image "nginx" in 40.750855715s
34m         Normal    Scheduled           pod/nginx-7ff65f974c-v9ccx    Successfully assigned vpa/nginx-7ff65f974c-v9ccx to k8s-node004
33m         Normal    Pulling             pod/nginx-7ff65f974c-v9ccx    Pulling image "nginx"
33m         Normal    Pulled              pod/nginx-7ff65f974c-v9ccx    Successfully pulled image "nginx" in 15.495315629s
33m         Normal    Created             pod/nginx-7ff65f974c-v9ccx    Created container nginx
33m         Normal    Started             pod/nginx-7ff65f974c-v9ccx    Started container nginx

從輸出信息可以了解到,vpa執(zhí)行了EvictedByVPA,自動停掉了nginx,然后使用 VPA推薦的資源啟動了新的nginx
,我們查看下nginx的pod可以得到確認

[root@k8s-node001 ~]# kubectl  describe po nginx-7ff65f974c-2m9zl -n vpa
Name:         nginx-7ff65f974c-2m9zl
Namespace:    vpa
Priority:     0
Node:         k8s-node004/192.168.100.184
Start Time:   Mon, 28 Sep 2020 00:46:19 -0400
Labels:       app=nginx
              pod-template-hash=7ff65f974c
Annotations:  cni.projectcalico.org/podIP: 100.67.191.53/32
              vpaObservedContainers: nginx
              vpaUpdates: Pod resources updated by nginx-vpa: container 0: cpu request, memory request
Status:       Running
IP:           100.67.191.53
IPs:
  IP:           100.67.191.53
Controlled By:  ReplicaSet/nginx-7ff65f974c
Containers:
  nginx:
    Container ID:   docker://c96bcd07f35409d47232a0bf862a76a56352bd84ef10a95de8b2e3f6681df43d
    Image:          nginx
    Image ID:       docker-pullable://nginx@sha256:c628b67d21744fce822d22fdcc0389f6bd763daac23a6b77147d0712ea7102d0
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Mon, 28 Sep 2020 00:46:38 -0400
    Ready:          True
    Restart Count:  0
    Requests:
      cpu:        476m
      memory:     262144k

看重點Requests:cpu: 476m,memory: 262144k
再回頭看看部署文件

          requests:
            cpu: 100m
            memory: 50Mi

現(xiàn)在可以知道VPA做了哪些事了吧。當然,隨著服務(wù)的負載的變化,VPA的推薦之也會不斷變化。當目前運行的pod的資源達不到VPA的推薦值,就會執(zhí)行pod驅(qū)逐,重新部署新的足夠資源的服務(wù)。

VPA使用限制

  • 不能與HPA(Horizontal Pod Autoscaler )一起使用
  • Pod比如使用副本控制器,例如屬于Deployment或者StatefulSet

VPA有啥好處

  • Pod 資源用其所需,所以集群節(jié)點使用效率高。
  • Pod 會被安排到具有適當可用資源的節(jié)點上。
  • 不必運行基準測試任務(wù)來確定 CPU 和內(nèi)存請求的合適值。
  • VPA 可以隨時調(diào)整 CPU 和內(nèi)存請求,無需人為操作,因此可以減少維護時間。

最后滴最后,VPA是Kubernetes比較新的功能,還沒有在生產(chǎn)環(huán)境大規(guī)模實踐過,不建議在線上環(huán)境使用自動更新模式,但是使用推薦模式你可以更好了解服務(wù)的資源使用情況。
更多信息請前往官網(wǎng)查看

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容