相对于HPA横向弹性伸缩增、减POD,VPA垂直弹性会在现有POD基础上对POD的CPU与内存进行弹性,它根据容器资源使用率自动设置 CPU 和 内存 的requests,从而允许在节点上进行适当的调度,以便为每个 Pod 提供适当的资源。VPA既可以缩小过度请求资源的容器,也可以根据其使用情况随时提升资源不足的容量。
说明:VPA与HPA不能同时工作,二者只能选其一,且VPA目前还未大规模推广商用,仅供测试。
依赖条件 :
metrics-server:跟HPA一样,需要有metrics-server识别CPU、内存指标数据。
vertical-pod-autoscaler:是Kubernetes的CRD对象,可在https://github.com/kubernetes/autoscaler.git获取安装包到集群中安装使用。
metrics-server与vertical-pod-autoscaler也是通过POD的方式运行在kube-system命名空间下,查看如下结果则表示安装成功。
1 2 3 4 5 $ kubectl get po -nkube-system |grep -E "metrics|vpa" metrics-server-5458746495-pfv4d 1/1 Running 5 63d vpa-admission-controller-657857bfb7-bjgrm 1/1 Running 0 94m vpa-recommender-77dccb87b8-4rg69 1/1 Running 0 94m vpa-updater-5f574b5d57-vblz9 1/1 Running 0 93m
下面部署一个负载,指定POD的CPU与内存大小,并通过压测触发VPA弹性策略,增加其CPU与内存,压测结束后CPU与内存缩小。
1. 部署Nginx负载 nginx-deploy.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx name: nginx spec: replicas: 2 selector: matchLabels: app: nginx_vpa template: metadata: labels: app: nginx_vpa spec: containers: - image: nginx imagePullPolicy: IfNotPresent name: nginx resources: requests: cpu: 100m memory: 250Mi
这里指定容器的request资源为CPU 100m,内存 250Mi。
1 2 3 4 5 6 7 $ kubectl apply -f nginx_vpa.yaml deployment.apps/nginx created $ kubectl get po -l app=nginx_vpa NAME READY STATUS RESTARTS AGE nginx-79c77f8bc7-fn574 1/1 Running 0 18s nginx-79c77f8bc7-g8jzx 1/1 Running 0 18s
apply资源文件后生成两个nginx的POD。
2. 部署Nginx service服务 为了测试服务,给POD加上前端serice服务作为业务入口Endpoint。
nginx-vpa-svc.yaml
1 2 3 4 5 6 7 8 9 10 11 apiVersion: v1 kind: Service metadata: name: nginx spec: ports: - port: 80 targetPort: 80 selector: app: nginx_vpa
这里我们可以设置service类型为ClusterIP或者NodePort,前者是在集群内部互通,后者可通过节点在外部访问,默认不指定服务类型的时候,使用的类型为ClusterIP,为测试方便可选择默认ClusterIP并在集群的节点上直接压测。
apply资源对象文件:
1 2 $ kubectl apply -f nginx-svc.yaml service/nginx created
查看生成的服务:
1 2 3 $ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx ClusterIP 10.1.41.177 <none> 80/TCP 4s
可在集群节点上直接测试curl -I 10.1.41.177:80
。
1 2 3 4 5 6 7 8 9 10 11 [lm@node2 ~]$ curl -I 10.1.41.177:80 curl -I 10.1.41.177:80 HTTP/1.1 200 OK Server: nginx/1.21.5 Date: Thu, 31 Mar 2022 08:13:55 GMT Content-Type: text/html Content-Length: 615 Last-Modified: Tue, 28 Dec 2021 15:28:38 GMT Connection: keep-alive ETag: "61cb2d26-267" Accept-Ranges: bytes
3. 部署VPA策略 nginx-vpa.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 apiVersion: autoscaling.k8s.io/v1beta2 kind: VerticalPodAutoscaler metadata: name: nginx-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"
这里我们指定的策略为CPU最小弹性至250m,内存到100Mi,CPU最大2000m,内存最大2048Mi。另外还有一个重要参数:updateMode: "Auto"
。这里指将触发VPA弹性动作。如果该值为OFF表示只推荐,但是不会真的触发弹性值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 $ kubectl apply -f nginx-vpa-demo.yaml verticalpodautoscaler.autoscaling.k8s.io/nginx-vpa created $ kubectl get vpa NAME MODE CPU MEM PROVIDED AGE nginx-vpa Off 250m 262144k True 8s $ kubectl describe vpa nginx-vpa |tail -n 20 Conditions: Last Transition Time: 2022-03-31T08:18:08Z 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: 429m Memory: 448631544 Events: <none>
从策略里看有几个关键点:
上述结果表明,推荐的 Pod 的 CPU 请求为 250m,推荐的内存请求为 262144k 字节。
4. 对Nginx服务进行压测触发VPA弹性 由于我们的Endpoint为clusterIP类型的service,所需需在集群内部访问,可在节点上测试Nginx服务。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [root@node2 ~] This is ApacheBench, Version 2.3 <$Revision : 1430300 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 10.1.41.177 (be patient) Completed 1000000 requests Completed 2000000 requests Completed 3000000 requests Completed 4000000 requests Completed 5000000 requests Completed 6000000 requests Completed 7000000 requests Completed 8000000 requests Completed 9000000 requests apr_pollset_poll: The timeout specified has expired (70007) Total of 9999808 requests completed
在压测过程中查看vpa详情,只关注Container Recommendations部分:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 $ kubectl describe vpa nginx-vpa |tail -n 20 Conditions: Last Transition Time: 2022-03-31T08:18:08Z 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: 2 Memory: 545717993 Events: <none>
这里Target为Cpu: 250m ,Memory: 262144k
,继续查看event事件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 $ kubectl get event LAST SEEN TYPE REASON OBJECT MESSAGE 2m42s Warning FailedGetScale horizontalpodautoscaler/hpa-example deployments/scale.apps "hpa-example" not found 11m Normal EvictedByVPA pod/nginx-79c77f8bc7-fn574 Pod was evicted by VPA Updater to apply resource recommendation. 11m Normal Killing pod/nginx-79c77f8bc7-fn574 Stopping container nginx 12m Normal Scheduled pod/nginx-79c77f8bc7-g68rc Successfully assigned default/nginx-79c77f8bc7-g68rc to master 12m Normal Pulled pod/nginx-79c77f8bc7-g68rc Container image "nginx" already present on machine 12m Normal Created pod/nginx-79c77f8bc7-g68rc Created container nginx 12m Normal Started pod/nginx-79c77f8bc7-g68rc Started container nginx 12m Normal EvictedByVPA pod/nginx-79c77f8bc7-g8jzx Pod was evicted by VPA Updater to apply resource recommendation. 12m Normal Killing pod/nginx-79c77f8bc7-g8jzx Stopping container nginx 11m Normal Scheduled pod/nginx-79c77f8bc7-vtknc Successfully assigned default/nginx-79c77f8bc7-vtknc to node2 11m Normal Pulled pod/nginx-79c77f8bc7-vtknc Container image "nginx" already present on machine 11m Normal Created pod/nginx-79c77f8bc7-vtknc Created container nginx 11m Normal Started pod/nginx-79c77f8bc7-vtknc Started container nginx 12m Normal SuccessfulCreate replicaset/nginx-79c77f8bc7 Created pod: nginx-79c77f8bc7-g68rc 11m Normal SuccessfulCreate replicaset/nginx-79c77f8bc7 Created pod: nginx-79c77f8bc7-vtknc
从事件里可以看出,vpa执行了EvictedByVPA
,自动停掉了老的POD,pod/nginx-79c77f8bc7-fn574
与pod/nginx-79c77f8bc7-g8jzx
,然后使用 VPA推荐的资源启动了新的nginx : pod/nginx-79c77f8bc7-g68rc
与pod/nginx-79c77f8bc7-vtknc
。分别查看这两个POD的资源requests情况:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 $ kubectl describe pod nginx-79c77f8bc7-g68rc Name: nginx-79c77f8bc7-g68rc Namespace: default Priority: 0 Node: master/192.168.0.114 Start Time: Thu, 31 Mar 2022 16:38:40 +0800 Labels: app=nginx_vpa pod-template-hash=79c77f8bc7 Annotations: vpaObservedContainers: nginx vpaUpdates: Pod resources updated by nginx-vpa: container 0: cpu request, memory request Status: Running IP: 10.244.0.126 IPs: IP: 10.244.0.126 Controlled By: ReplicaSet/nginx-79c77f8bc7 Containers: nginx: Container ID: docker://d45c8eeada45b8bc8e932cd28d7e72c6ac412c90568689f4090c97f207a99914 Image: nginx Image ID: docker-pullable://nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31 Port: <none> Host Port: <none> State: Running Started: Thu, 31 Mar 2022 16:38:41 +0800 Ready: True Restart Count: 0 Requests: cpu: 250m memory: 262144k Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-g4ktr (ro)
可见其申请了新的CPU与内存值。不过压测半小时过去了,也没见VPA将POD的requests缩回去。。。可能等的时间不够,或者VPA本身不成熟吧。
5.总结
VPA垂直弹性可对POD进行CPU与内存requests修改,kill掉老POD,生成新POD。
VPA与HPA不能同时使用,从上面的event事件中可看出VPA测试过程中确实影响了HPA弹性。
VPA压测很久之后POD还没有垂直缩回去,功能应该还不成熟。
欢迎关注公众号-梅旭红,记录技术之旅,不定期更新.