VPA 简介
VPA 全称 vertical pod autoscaler :垂直POD自动扩缩容。 它根据容器资源使用率自动设置 CPU 和 内存 的requests,自动驱逐POD触发其在节点上进行适当的调度,以便为每个 Pod 提供适当的资源。它既可以缩小过度请求资源的容器,也可以根据其使用情况随时提升资源不足的容量。
VPA原理
架构
VPA主要由三个组件组成,分别为recommender、updater、admission-controller。 (PS:VPA 依赖Metrics Server)
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 、VerticalPodAutoscalerCheckpoint
1)VerticalPodAutoscaler
该资源由用户创建,用于设置纵向扩容的目标对象和存储recommend组件计算出的推荐指标。
apiVersion: autoscaling.k8s.io/v1beta2
kind: VerticalPodAutoscaler
metadata:
name: nginx-vpa
namespace: vpa
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: nginx
updatePolicy:
updateMode: "Auto"
resourcePolicy:
containerPolicies:
- containerName: "nginx"
minAllowed:
cpu: "100m"
memory: "100Mi"
maxAllowed:
cpu: "2000m"
memory: "2600Mi"
VPA有几种更新模式
"Auto":VPA 在创建 pod 时分配资源请求,并使用首选更新机制在现有 pod 上更新它们。目前这相当于"Recreate"。一旦 pod 请求的免重启(“就地”)更新可用,它可能会被该"Auto"模式用作首选的更新机制。注意: VPA 的此功能是实验性的,可能会导致您的应用程序停机,当目前运行的pod的资源达不到VPA的推荐值,就会执行pod驱逐,重新部署新的足够资源的服务
"Recreate":VPA 在创建 Pod 时分配资源请求,并在现有 Pod 上更新它们,当请求的资源与新建议有很大差异时(尊重 Pod 中断预算,如果定义)。这种模式应该很少使用,只有当您需要确保在资源请求发生变化时重新启动 Pod 时。否则,更喜欢这种"Auto"模式,一旦它们可用,就可以利用重新启动免费更新。注意: VPA 的此功能是实验性的,可能会导致您的应用程序停机
"Initial":VPA 仅在创建 pod 时分配资源请求,以后不会自动更改它们。
"Off":VPA 不会自动更改 Pod 的资源需求。这些建议是经过计算的,并且可以在 VPA 对象中进行检查。这种模式仅获取资源推荐值,但是不更新Pod.
2) VerticalPodAutoscalerCheckpoint
该资源由recommend组件创建和维护,用于存储指标相关信息。一个vpa对应的多个容器,每个容器创建一个该资源。
工作流程
vpa 工作流程可以使用下图表示
1.用户配置 VPA 资源 (VerticalPodAutoScaler )
2. VPA Recommender 从API Service读取 VPA 配置
3. VPA Recommender 实时更新资源利用率指标(来自MetriceServer),对目标POD进行计算,提供 pod 资源推荐
4.VPA Updater监听读取 pod 资源建议
5.VPA Updater 得到新的建议后终止 pod ( Kubernetes 不支持动态更改正在运行的 pod 的资源限制,因此 VPA 无法使用更新现有 pod)
6. POD部署控制器意识到 pod 已终止,并将重新创建 pod 以匹配其副本配置
7. 当 Pod 处于重新创建过程中时,VPA Admission controller获取 Pod 资源推荐.
8. VPA Admission controoler将建议覆盖到 pod。 (如示例中,VPA 准入控制器向 pod 设置“250m”的 CPU 的资源限制,替换POD定义中的设置)
VPA 实践
1) 部署VPA 组件
#下载项目特定版本 如 vpa-release-0.10
kubernetes/autoscaler
cd autoscaler/vertical-pod-autoscaler
./hack/vpa-up.sh
# 关闭vpa组件 ./hack/vpa-down.sh
部署输出日志如上,查看部署的三个组件:
2)配置业务负载的 VPA
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: "100m"
memory: "100Mi"
maxAllowed:
cpu: "2000m"
memory: "2600Mi"
查看VPA 对象:
kubectl get vpa
#显示 MODE 为 Auto
3)启动业务负载 如Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: 100m
memory: 50Mi
---
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
type: NodePort
ports:
- port: 808
targetPort: 80
nodePort: 32008
selector:
app: nginx
4) 压测服务端口,观察VPA的变化
#如使用ab 工具进行压力测试
yum -y install httpd-tools
ab -c 3000 -n 10000000 xxx
查看metric 指标,POD的cpu 发生了变化
kubectl top pod
查看VPA的情况,也发现recommendation 变化了
kubectl get vpa nginx-vpa -o yaml
查看POD 的资源,也相应发生了变化,与开始的配置值不一样:
kubectl get pod -o yaml
总结
VPA的使用在哪些场景? 我们知道 HPA 也能扩缩容,它是对POD的数量进行扩缩容,但单POD的资源不会变化,适用于进程增加线性增加性能的场景,这种场景一般是对应无状态服务。而有些场景增加进程并不能提高服务性能,而更多的CPU或内存才能有效提供服务的性能,如带有主从架构的服务,这些往往有状态的服务。因此HPA 更适用于解决有状态服务的扩缩容问题。 另外一个场景,业务部署时并不能很正确地设置CPU和MEM的相对大小,设置不合理存在资源浪费的情况,这时VPA就能动态调整CPU和MEM的值,减少资源浪费。
VPA 也有一些缺陷,VPA扩缩容会重新调度POD,可能带来短暂的服务抖动。 在最新的v1.27 版本新增alpha 特性,提供 in place update ,避免了重启POD。另外VPA可能推荐较大的资源限制超出了k8s集群可用的资源,可能出现POD不能调度成功。