K8s 降本增效之 VPA 上篇
接受范围|中度
VPA使用户无需为pod中的容器设置资源请求。配置后,它将根据资源(cpu 与内存)使用情况自动设置 requests。在对 pod 的调度过程中,使得每个 pod 都可以使用适当的资源量从而分配到适合的节点上。它既可以缩小资源请求过多的 pod,也可以根据一段时间内的使用情况扩大资源请求不足的 pod。
使用场景
自动资源配置提升管理效率
提高集群资源利用率
社区现状
目前,Kubernetes并不支持pod的in-place-update,因此vpa的auto等同recreate,目前版本的in-place-update还在review当中,并有望在未来的版本中提供,当前版本兼容如下所示。
版本 |
K8s release |
0.12 |
1.25+ |
0.11 |
1.22-1.24 |
0.10 |
1.22+ |
0.9 |
1.16+ |
架构简介
VPA主要由三个组件组成,分别为recommender、updater、admission-controller
1)recommender:引入VerticalPodAutoscaler对象,其由 Pod 的标签选择器、资源策略(控制 VPA 如何计算资源)、更新策略(控制如何将更改应用于 Pod)和推荐的 Pod 资源组成,其根据metric-server获取到的容器指标并观测 OOM 事件,计算推荐指标,终更新VerticalPodAutoscaler对象
2)updater:其是负责Pod更新的组件。如果 Pod 在 "Auto" 模式下使用 VPA,则 Updater 可以决定使用推荐器资源对其进行更新。这只是通过驱逐Pod以便使用新资源重新创建它来实现的。简单来说,其是根据pod的request中设置的指标和recommend计算的推荐指标,在一定条件下驱逐pod,
3)admission-controller:这是一个webhook组件,所有 Pod 创建请求都通过 VPA Admission Controller,如果Pod与VerticalPodAutoscaler 对象匹配,把recommend计算出的指标应用到pod的request和limit,如果 Recommender 不可用,它会回退到 VPA 对象中缓存的推荐。
VerticalPodAutoscaler
该资源由用户创建,用于设置纵向扩容的目标对象和存储recommend组件计算出的推荐指标。
VerticalPodAutoscalerCheckpoint
该资源由recommend组件创建和维护,用于存储指标相关信息。一个vpa对应的多个容器,每个容器创建一个该资源。
VPA实践
VPA部署
a.获取metrics-server manifest
wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.6.2/components.yaml
b.执行部署
kubectl apply -f components.yaml
c.验证结果
[ ]
NAME READY STATUS RESTARTS AGE
metrics-server-3358ad021s-wqmc9 1/1 Running 5m
[ ]
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
master 528m 5% 4385Mi 13%
git clone https://github.com/kubernetes/autoscaler.git
[ ]
[ ]
[ ]
NAME READY STATUS RESTARTS AGE
metrics-server-3358ad021s-wqmc9 1/1 Running 15m
vpa-admission-controller-78e7f86645-67897 1/1 Running 3m
vpa-recommender-tq4f7fb9db-32776 1/1 Running 3m
vpa-updater-53er87q7qt-5p889 1/1 Running 3m
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: test
nginx :
spec:
1 :
selector:
matchLabels:
app: test
template:
metadata:
labels:
app: test
spec:
containers:
image: nginx
name: nginx
resources:
requests:
200m :
memory: 250Mi
[ ]
NAME READY STATUS RESTARTS AGE
pod/nginx-5334b745w3-qwew3 1/1 Running 1m
[root@master ~]# cat nginx-test-svc.yaml
apiVersion: v1
kind: Service
metadata:
nginx :
spec:
type: NodePort
ports:
port: 80
targetPort: 80
selector:
app: test
[root@master examples]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
31496/TCP 55s :
10.99.106.213:31496
200 OK
使用updateMode: "Off"模式,其仅计算资源的推荐而不应用Pod
[root@master ~]# cat nginx-vpa-test.yaml
apiVersion: autoscaling.k8s.io/v1beta2
kind: VerticalPodAutoscaler
metadata:
nginx-vpa-test :
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"
["cpu", "memory"] :
[root@master ~]# kubectl describe vpa nginx-vpa-test
Name: nginx-vpa-test
...
Update Policy:
Update Mode: Off
Status:
Conditions:
2022-11-28T03:21:14Z :
Status: True
Type: RecommendationProvided
Recommendation:
Container Recommendations:
Container Name: nginx
Lower Bound:
Cpu: 250m
262027k :
Target:
Cpu: 250m
Memory: 262027k
Uncapped Target:
50m :
Memory: 262027k
Upper Bound:
717m :
650210341 :
Events: <none>
for i in $(seq $(getconf _NPROCESSORS_ONLN)); do yes > /dev/null & done
://10.99.106.213:31496/
...
Benchmarking 10.99.106.213 (be patient)
Completed 1000000 requests
Completed 2000000 requests
Completed 3000000 requests
[root@master ~]# kubectl describe vpa nginx-vpa |tail -n 20
Conditions:
2022-11-28T04:14:21Z :
Status: True
Type: RecommendationProvided
Recommendation:
Container Recommendations:
Container Name: nginx
Lower Bound:
Cpu: 250m
Memory: 262027k
Target:
673m :
Memory: 262027k
Uncapped Target:
673m :
Memory: 262027k
Upper Bound:
Cpu: 2
Memory: 650210341
Events: <none>
小结
局限性
1.不要将VPA与HPA一起使用,后者基于相同的资源指标(例如CPU和MEMORY使用率)进行缩放。这是因为当指标(CPU/MEMORY)达到其定义的阈值时,VPA和HPA将同时发生缩放事件,这可能会产生未知的副作用并可能导致问题,该处可以进行优化
2. VPA 可能会推荐比集群中可用的资源更多的资源,从而导致 pod 未分配给节点(由于资源不足),因此永远不会运行。为了克服这个限制,好将LimitRange 设置为大可用资源。这将确保 pod 不会要求超过 LimitRange 定义的资源,这里会导致资源碎片或节点热点
3.VPA不会驱逐不在控制器下运行的pod,驱逐可以单独处理
优化方向
1.对于非原生workload的优化,针对非原生工作负载,VPA使用scale方式获取,效率较低
2.VPA跟其他controller一样,使用selector模式,可以进行适当优化
3.VPA的历史数据加载只在启动时才会进行,且效率跟性能较低
4.多种推荐算法的支持
5.VPA对象更新瓶颈等
由于笔者时间、视野、认知有限,本文难免出现错误、疏漏等问题,期待各位读者朋友、业界专家指正交流。
1.https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler
2. https://github.com/containerd/containerd/pull/6965
相关文章