必须完成Metrics Server部署、VPA组件安装、策略定义与验证四步闭环:先部署Metrics Server并用kubectl top验证;再安装VPA三组件并确保全部Running;然后为Deployment配置VPA对象(Auto或Initial模式);最后通过describe、get、watch和yaml检查四步验证生效。

要在Kubernetes集群中让Pod的CPU和内存请求值随实际负载自动优化,避免手动估算导致资源浪费或OOM,必须完成Metrics Server部署、VPA组件安装、策略定义与验证四步闭环。
确认并部署Metrics Server
Metrics Server是VPA获取Pod实时资源使用数据的唯一上游,缺失它会导致VPA Recommender无法生成任何建议。
执行kubectl get apiservices | grep metrics,若无v1beta1.metrics.k8s.io行或状态为False,说明未就绪。
运行kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.7.2/components.yaml部署最新稳定版Metrics Server(适配K8s 1.24+)。
等待30秒后执行kubectl top pods -n default,能正常输出CPU/MEM列即表示Metrics Server已生效。这一步失败,后续所有VPA操作都将无推荐依据。
安装VPA核心组件
VPA不是Kubernetes内置控制器,需单独部署Recommender、Updater、Admission Controller三个组件。
克隆官方仓库:git clone https://github.com/kubernetes/autoscaler.git && cd autoscaler/vertical-pod-autoscaler/。
执行./hack/vpa-up.sh一键部署全部组件到vpa-system命名空间——该脚本会自动处理RBAC、ServiceAccount、CRD注册等依赖项。
【必须验证】运行kubectl get pods -n vpa-system,确保vpa-recommender、vpa-updater、vpa-admission-controller三个Pod状态均为Running且READY为1/1。任一组件异常都会阻断VPA全链路。
为Deployment配置VPA对象
方法一:启用Auto模式(推荐用于生产无状态服务)
创建my-app-vpa.yaml,内容如下:
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: my-app-vpa
namespace: default
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: my-app
updatePolicy:
updateMode: "Auto"
resourcePolicy:
containerPolicies:
- containerName: "*"
minAllowed:
cpu: 100m
memory: 256Mi
maxAllowed:
cpu: 2
memory: 2Gi
应用配置:kubectl apply -f my-app-vpa.yaml。
注意:updateMode: Auto会触发Pod滚动重启,务必确认你的Deployment设置了strategy.type: RollingUpdate且容器支持优雅终止(如监听SIGTERM并完成当前请求)。
方法二:仅初始化时应用推荐(适合有状态或敏感服务)
将上述YAML中updateMode改为"Initial",VPA只在Pod首次创建时注入推荐值,后续不干预——这能规避运行中重启风险,但失去持续优化能力。
验证VPA是否生效
第一步:检查VPA推荐状态
执行kubectl describe vpa my-app-vpa -n default,在Events区域查找RecommendationComputed事件。
第二步:确认推荐值已写入
运行kubectl get vpa my-app-vpa -n default -o yaml,观察status.recommendation.containerRecommendations字段是否包含非空的target值,例如cpu: 350m, memory: 480Mi。
第三步:观察Pod是否被更新
若使用Auto模式,执行kubectl get pods -n default --watch,当看到旧Pod Terminating、新Pod Running时,说明Updater已驱逐并重建Pod,且Admission Controller已将推荐值注入新Pod的resources.requests。
第四步:比对实际效果
用kubectl get pod 查看新Pod的最终资源请求值,确认其落在你设定的minAllowed/maxAllowed范围内——超出范围的推荐会被自动截断。










