相对于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命名空间下,查看如下结果则表示安装成功。
$ 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。
$ 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
apiVersion : v1
kind : Service
metadata :
name : nginx
spec :
#type: NodePort
ports :
- port : 80
targetPort : 80
selector :
app : nginx_vpa
这里我们可以设置service类型为ClusterIP或者NodePort,前者是在集群内部互通,后者可通过节点在外部访问,默认不指定服务类型的时候,使用的类型为ClusterIP,为测试方便可选择默认ClusterIP并在集群的节点上直接压测。
apply资源对象文件:
$ kubectl apply -f nginx-svc.yaml
service/nginx created
查看生成的服务:
$ 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
。
[ 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 ~] # ab -c 100 -n 10000000 http://10.1.41.177:80/
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还没有垂直缩回去,功能应该还不成熟。
全文完。