之前的文章我们介绍了HPA(Horizontal Pod Autoscaler)的实现,HPA一般被称为横向扩展,与HPA不同的Vertical Pod Autoscaler ( VPA ) 会自动调整 Pod 的 CPU 和内存属性,被称为纵向扩展。VPA可以给出服务运行所适合的CPU和内存配置,省去估计服务占用资源的时间,更合理的使用资源。当然,VPA也可根据资源的使用情况“调整”pod的资源。这里的调整我们用了双引号,因为他的实现机制是重建而不是动态增加。下面是一个实际的例子:假设我的memory limits是100Mi,但是现在已经用到了98Mi,如果再大的话就oom了,此时vpa会在垂直方向上提升你的memory limits的大小。这种vpa比较适合一些资源消耗比较大的应用,例如es,你给大了资源浪费,给小了,又不够。所以vpa就派上用场了。当然,vpa不像hpa默认集成在k8s里面的,需要你自己去配置的。
从根本上来说,VPA 和 HPA 之间的区别在于它们的扩展方式。HPA 通过添加或删除pod进行扩展,从而水平扩展容量。然而,VPA 通过增加或减少现有 Pod 容器内的 CPU 和内存资源来进行扩展,从而垂直扩展容量。下表更详细地解释了 Kubernetes VPA 和 HPA 之间的差异。
需要调整容量 | 水平缩放 (HPA) | 垂直缩放 (VPA) |
---|---|---|
更多资源 | 添加更多 Pod | 增加现有 pod 容器的 CPU 或内存资源 |
资源较少 | 删除 Pod | 减少现有 Pod 容器的 CPU 或内存资源 |
VPA 部署具有三个主要组件:VPA Recommender、VPA Updater和VPA Admission Controller。让我们看一下每个组件的作用。VPA Recommender:
VPA 更新程序:
VPA 准入控制器:
既然你知道了大致原理,让我们开始动手操作你吧
克隆代码
# git clone https://github.com/kubernetes/autoscaler.git
由于某些原因拉不到镜像,改yaml修改优先使用本地镜像
# cd autoscaler/vertical-pod-autoscaler/deploy
# sed -i 's/Always/IfNotPresent/g' recommender-deployment.yaml
# sed -i 's/Always/IfNotPresent/g' admission-controller-deployment.yaml
# sed -i 's/Always/IfNotPresent/g' updater-deployment.yaml
# 拉取镜像
# docker pull giantswarm/vpa-admission-controller:0.14.0
# docker pull giantswarm/vpa-recommender:0.14.0
# docker pull giantswarm/vpa-updater:0.14.0
# 修改tag
# docker tag giantswarm/vpa-updater:0.14.0 registry.k8s.io/autoscaling/vpa-updater:0.14.0
# docker tag giantswarm/vpa-recommender:0.14.0 registry.k8s.io/autoscaling/vpa-recommender:0.14.0
# docker tag giantswarm/vpa-admission-controller:0.14.0 registry.k8s.io/autoscaling/vpa-admission-controller:0.14.0
# cd autoscaler/vertical-pod-autoscaler/hack
# 安装脚本安装之前保证你的K8S集群的metrics-server已安装,并且openssl升级到1.1.1或更高版本
# ./vpa-up.sh
等待安装完成
# kubectl get pods -n kube-system | grep vpa
kube-system vpa-admission-controller-75bffbf8d8-6hxqq 1/1 Running 0 5m9s
kube-system vpa-recommender-748c55b5bf-kqqjc 1/1 Running 0 4m34s
kube-system vpa-updater-679d5dcdd6-lslc7 1/1 Running 0 4m15s
使用VPA,您需要为要自动计算资源需求的每个控制器插入一个Vertical Pod Autoscaler资源。这将是最常见的Deployment。VPA有四种运行模式
创建一个updateMode: Auto 的VPA
# 将updateMode中的requests 改为 CPU:50m,Memory: 50Mi,同时将updateMode修改为Auto
# 创建一个pod和svc
# kubectl get pods -n vpa
NAME READY STATUS RESTARTS AGE
nginx-8454bb78d8-67pth 1/1 Running 0 9s
nginx-8454bb78d8-6efsh 1/1 Running 0 9s
# kubectl get svc -n vpa
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx NodePort 10.0.200.5 <none> 80:45425/TCP 15s
# 进行压测,压测到一半时,突然连接断了,说明POD被重新创建了
# ab -c 1000 -n 100000 http://192.168.0.191:45425/
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 192.168.0.191 (be patient)
apr_socket_recv: Connection reset by peer (104)
Total of 187078 requests completed
# 查看vpa
# kubectl describe vpa nginx-vpa -n vpa | tail -n 20
Conditions:
Last Transition Time: 2023-09-07T15:41:32Z
Status: True
Type: RecommendationProvided
Recommendation:
Container Recommendations:
Container Name: nginx
Lower Bound: #容器的最小估计值
Cpu: 100m
Memory: 262144k
Target: #目标估计是我们用于设置资源请求的估计
Cpu: 350m
Memory: 262144k
Uncapped Target: #无上限目标估计是在没有minAllowed和maxAllowed限制的情况下产生的目标估计
Cpu: 350m
Memory: 262144k
Upper Bound: #上限是容器的最大建议资源估计
Cpu: 2
Memory: 405160855
Events: <none>
# 查看pod被重新创建了 稍高的配置
# kubectl get pods -n vpa
NAME READY STATUS RESTARTS AGE
nginx-daecsfv8d8-see8h 1/1 Running 0 4m
nginx-daecsfv8d8-fsise 1/1 Running 0 3m
在本文中,我们使用VPA实现了基于POD对配置进行横向扩展,合理的使用可以提高对K8S的利用率,实现降本增效。但是目前的VPA也存在一些问题,我个人觉得VPA最大的问题是会对服务进行重建,重建过程中可能会有流量损失,但是好消息是从1.27 版本动态调整容器CPU和内存资源限制,无需重启应用程序,在可见的将来,会实现动态扩容更加顺滑,让我们一起期待~