VPA 简介#
什么是 VPA?#
Vertical Pod Autoscaler(VPA,垂直 Pod 自动伸缩器)是 Kubernetes 的一个组件,它可以根据 Pod 的实际资源使用情况,自动调整 Pod 的 CPU 和内存请求值(requests)。
为什么需要 VPA?#
在实际生产环境中,我们经常遇到以下问题:
| 问题 | 影响 | VPA 解决方案 |
|---|---|---|
| 资源配置过高 | 浪费集群资源,成本增加 | 自动降低资源请求 |
| 资源配置过低 | 应用性能差,频繁重启 | 自动提高资源请求 |
| 手动调优困难 | 耗时耗力,容易出错 | 基于历史数据自动优化 |
| 动态负载变化 | 静态配置无法适应 | 持续监控和调整 |
VPA vs HPA#
| 特性 | VPA(垂直伸缩) | HPA(水平伸缩) |
|---|---|---|
| 伸缩方向 | 调整单个 Pod 的资源 | 调整 Pod 的数量 |
| 适用场景 | 单体应用、有状态应用 | 无状态应用、微服务 |
| 资源类型 | CPU、内存 | 主要基于 CPU |
| 伸缩速度 | 需要重启 Pod | 相对较快 |
| 兼容性 | 不能同时使用 | 可以组合使用 |
VPA 工作原理#
VPA 由三个核心组件组成:
1. VPA Recommender(推荐器)#
- 作用:监控 Pod 的资源使用情况
- 功能:基于历史数据和当前使用情况生成资源建议
- 算法:使用统计学方法分析资源使用模式
2. VPA Updater(更新器)#
- 作用:决定是否需要更新 Pod 的资源配置
- 功能:比较当前配置与推荐值,触发更新操作
- 策略:支持多种更新策略(自动、初始、关闭)
3. VPA Admission Controller(准入控制器)#
- 作用:在 Pod 创建时应用 VPA 推荐的资源配置
- 功能:拦截 Pod 创建请求,修改资源配置
- 时机:Pod 重启或新建时生效
环境要求#
系统要求#
| 组件 | 版本要求 | 说明 |
|---|---|---|
| Kubernetes | v1.16+ | 支持 VPA CRD |
| Metrics Server | v0.3.6+ | 提供资源使用数据 |
| OpenSSL | v1.1.1+ | CentOS 7 需要升级 |
| 操作系统 | CentOS 7+ | 或其他 Linux 发行版 |
本教程环境#
- Kubernetes 版本:v1.20.4
- 操作系统:CentOS 7
- VPA 版本:v0.9.2
- Metrics Server 版本:v0.5.0
📚 项目地址:Kubernetes VPA GitHub
VPA 安装部署#
前置条件检查#
在安装 VPA 之前,需要确保集群满足以下条件:
# 检查 Kubernetes 版本
kubectl version --short
# 检查集群节点状态
kubectl get nodes
# 检查是否已安装 Metrics Server
kubectl get deployment metrics-server -n kube-system
步骤 1:升级 OpenSSL(CentOS 7 专用)#
为什么需要升级?#
CentOS 7 默认的 OpenSSL 版本较低,VPA 安装脚本需要更高版本的 OpenSSL 支持。
升级步骤#
# 下载 OpenSSL 1.1.1k 源码
wget http://mirrors.ibiblio.org/openssl/source/openssl-1.1.1k.tar.gz
# 解压并进入目录
tar xf openssl-1.1.1k.tar.gz
cd openssl-1.1.1k/
# 配置编译选项
./config --prefix=/usr/local/openssl --openssldir=/usr/local/openssl
# 编译安装(使用所有 CPU 核心加速编译)
make -j$(nproc)
sudo make install
# 备份原有 OpenSSL
sudo mv /usr/bin/openssl{,.bak}
# 创建软链接
sudo ln -s /usr/local/openssl/bin/openssl /usr/bin/openssl
sudo ln -s /usr/local/openssl/lib/libssl.so.1.1 /usr/lib64/libssl.so.1.1
sudo ln -s /usr/local/openssl/lib/libcrypto.so.1.1 /usr/lib64/libcrypto.so.1.1
# 更新动态链接库缓存
sudo ldconfig
# 验证安装
openssl version
预期输出:
OpenSSL 1.1.1k 25 Mar 2021
⚠️ 注意:此步骤仅适用于 CentOS 7,其他系统可能不需要
步骤 2:安装 Metrics Server#
为什么需要 Metrics Server?#
Metrics Server 是 VPA 的重要依赖,它提供:
- 资源使用数据:CPU 和内存的实时使用情况
- 历史数据收集:为 VPA 推荐算法提供数据基础
- API 支持:支持
kubectl top命令
安装步骤#
📚 项目地址:Metrics Server GitHub
# 下载并安装 Metrics Server v0.5.0
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.5.0/components.yaml
配置 Metrics Server#
由于测试环境可能存在证书问题,需要添加不安全的 TLS 配置:
# 编辑 Metrics Server 部署配置
kubectl edit deployment metrics-server -n kube-system
在 args 部分添加以下参数:
spec:
template:
spec:
containers:
- name: metrics-server
args:
- --cert-dir=/tmp
- --secure-port=443
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --kubelet-use-node-status-port
- --metric-resolution=15s
- --kubelet-insecure-tls # 添加此行,跳过 TLS 验证
验证安装#
# 等待 Pod 启动完成
watch kubectl get pods -l k8s-app=metrics-server -n kube-system
# 验证 Metrics Server 功能
kubectl top nodes
预期输出:
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
node1 567m 7% 4009Mi 27%
node2 613m 8% 5181Mi 35%
node3 1446m 19% 1683Mi 11%
node4 278m 3% 1380Mi 9%
# 检查 Pod 资源使用情况
kubectl top pods --all-namespaces
✅ 成功标志:能够正常显示节点和 Pod 的资源使用情况
步骤 3:安装 VPA#
下载 VPA 源码#
# 克隆 Kubernetes Autoscaler 项目
git clone https://github.com/kubernetes/autoscaler.git
# 进入 VPA 目录
cd autoscaler/vertical-pod-autoscaler/
# 查看可用版本(可选)
git tag | grep vpa | tail -5
安装 VPA 组件#
VPA 提供了一键安装脚本:
# 执行安装脚本(默认安装 v0.9.2)
./hack/vpa-up.sh
安装过程截图:

验证 VPA 安装#
# 检查 VPA 相关 Pod 状态
kubectl get pods -n kube-system | grep vpa
预期输出:
vpa-admission-controller-6cd546c4f-dvcf9 1/1 Running 0 72s
vpa-recommender-6855ff754-9q2dw 1/1 Running 0 72s
vpa-updater-9fd7bfbd5-h7l7n 1/1 Running 0 72s
VPA 组件说明#
| 组件 | 作用 | 端口 |
|---|---|---|
| vpa-recommender | 分析资源使用情况,生成推荐值 | 8080 |
| vpa-updater | 决定何时更新 Pod 资源配置 | 8080 |
| vpa-admission-controller | 在 Pod 创建时应用推荐配置 | 8000 |
检查 VPA CRD#
# 验证 VPA 自定义资源定义
kubectl get crd | grep verticalpodautoscaler
# 查看 VPA CRD 详情
kubectl describe crd verticalpodautoscalers.autoscaling.k8s.io
检查 VPA 服务#
# 查看 VPA 相关服务
kubectl get svc -n kube-system | grep vpa
# 查看 VPA Webhook 配置
kubectl get validatingwebhookconfiguration | grep vpa
kubectl get mutatingwebhookconfiguration | grep vpa
✅ 安装成功标志:所有 VPA 组件 Pod 状态为 Running,且 CRD 正常创建
VPA 使用实战#
创建测试环境#
# 创建专用命名空间
kubectl create namespace vpa-demo
示例 1:基础 VPA 使用#
部署测试应用#
我们使用 VPA 官方提供的 hamster 示例应用:
# 应用示例配置
kubectl apply -f examples/hamster.yaml -n vpa-demo
让我们查看 hamster.yaml 的内容:
# hamster.yaml 内容解析
apiVersion: apps/v1
kind: Deployment
metadata:
name: hamster
spec:
replicas: 2
selector:
matchLabels:
app: hamster
template:
metadata:
labels:
app: hamster
spec:
containers:
- name: hamster
image: k8s.gcr.io/ubuntu-slim:0.1
resources:
requests:
cpu: 100m # 初始 CPU 请求:100 毫核
memory: 50Mi # 初始内存请求:50MB
command: ["/bin/sh"]
args:
- "-c"
- "while true; do timeout 10s yes >/dev/null; sleep 5s; done"
---
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: hamster-vpa
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: hamster
updatePolicy:
updateMode: "Auto" # 自动更新模式
查看初始资源配置#
# 获取 Pod 名称
POD_NAME=$(kubectl get pods -n vpa-demo -l app=hamster -o jsonpath='{.items[0].metadata.name}')
# 查看初始资源配置
kubectl get pod $POD_NAME -n vpa-demo -o yaml | grep -A 5 'resources:'
初始配置输出:
resources:
requests:
cpu: 100m
memory: 50Mi
观察 VPA 推荐#
# 查看 VPA 状态和推荐
kubectl describe vpa hamster-vpa -n vpa-demo
等待自动更新#
VPA 需要收集一段时间的数据才会触发更新(通常 1-2 分钟):
# 监控 Pod 变化
watch kubectl get pods -n vpa-demo
更新过程截图:

查看更新后的资源配置#
# 获取新 Pod 名称
NEW_POD_NAME=$(kubectl get pods -n vpa-demo -l app=hamster -o jsonpath='{.items[0].metadata.name}')
# 查看更新后的资源配置
kubectl get pod $NEW_POD_NAME -n vpa-demo -o yaml | grep -A 5 'resources:'
更新后配置输出:
resources:
requests:
cpu: 548m # CPU 请求增加到 548 毫核
memory: 262144k # 内存请求增加到约 256MB
分析资源变化#
| 资源类型 | 初始值 | 更新后 | 变化倍数 | 原因分析 |
|---|---|---|---|---|
| CPU | 100m | 548m | 5.48x | 应用 CPU 使用率较高 |
| Memory | 50Mi | 256Mi | 5.12x | 内存使用超出初始配置 |
📊 数据说明:VPA 基于实际资源使用情况,自动调整了资源请求值,确保应用有足够的资源运行
示例 2:VPA 更新策略#
VPA 支持多种更新策略,让我们创建不同策略的示例:
Off 模式(仅推荐)#
cat <<EOF | kubectl apply -f -
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: hamster-vpa-off
namespace: vpa-demo
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: hamster
updatePolicy:
updateMode: "Off" # 仅提供推荐,不自动更新
EOF
Initial 模式(仅新 Pod)#
cat <<EOF | kubectl apply -f -
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: hamster-vpa-initial
namespace: vpa-demo
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: hamster
updatePolicy:
updateMode: "Initial" # 仅对新创建的 Pod 生效
EOF
资源策略配置#
cat <<EOF | kubectl apply -f -
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: hamster-vpa-policy
namespace: vpa-demo
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: hamster
updatePolicy:
updateMode: "Auto"
resourcePolicy:
containerPolicies:
- containerName: hamster
minAllowed:
cpu: 100m
memory: 50Mi
maxAllowed:
cpu: 1000m
memory: 500Mi
controlledResources: ["cpu", "memory"]
EOF
VPA 监控和调试#
查看 VPA 推荐详情#
# 查看详细的 VPA 状态
kubectl describe vpa hamster-vpa -n vpa-demo
# 查看 VPA 推荐的 JSON 格式
kubectl get vpa hamster-vpa -n vpa-demo -o json | jq '.status.recommendation'
查看 VPA 组件日志#
# 查看 Recommender 日志
kubectl logs -n kube-system -l app=vpa-recommender
# 查看 Updater 日志
kubectl logs -n kube-system -l app=vpa-updater
# 查看 Admission Controller 日志
kubectl logs -n kube-system -l app=vpa-admission-controller
VPA 指标监控#
# 查看 VPA 推荐指标
curl http://<vpa-recommender-ip>:8080/metrics
# 查看 VPA 更新指标
curl http://<vpa-updater-ip>:8080/metrics
VPA 最佳实践#
适用场景#
✅ 适合使用 VPA 的场景#
- 单体应用:难以水平扩展的应用
- 有状态应用:数据库、缓存等
- 资源密集型应用:机器学习、数据处理
- 开发测试环境:快速优化资源配置
- 成本优化:减少资源浪费
❌ 不适合使用 VPA 的场景#
- 高可用要求:不能容忍 Pod 重启
- 快速扩展需求:需要快速响应负载变化
- 微服务架构:更适合使用 HPA
- 实时系统:对延迟敏感的应用
配置建议#
1. 更新策略选择#
| 模式 | 使用场景 | 优缺点 |
|---|---|---|
| Auto | 生产环境,可容忍重启 | 自动化程度高,但会重启 Pod |
| Initial | 新部署的应用 | 对现有 Pod 无影响 |
| Off | 观察和分析阶段 | 安全,但需要手动应用 |
2. 资源限制设置#
resourcePolicy:
containerPolicies:
- containerName: app
minAllowed:
cpu: 100m # 防止资源过低
memory: 128Mi
maxAllowed:
cpu: 2000m # 防止资源过高
memory: 4Gi
controlledResources: ["cpu", "memory"]
controlledValues: "RequestsAndLimits" # 同时控制 requests 和 limits
3. 监控和告警#
# 推荐配置 Prometheus 监控规则
groups:
- name: vpa.rules
rules:
- alert: VPARecommendationChanged
expr: increase(vpa_recommender_recommendations_total[5m]) > 0
labels:
severity: info
annotations:
summary: "VPA recommendation changed for {{ $labels.vpa_name }}"
故障排查#
常见问题#
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| VPA 不生效 | Metrics Server 未安装 | 安装并配置 Metrics Server |
| Pod 频繁重启 | 推荐值变化过于频繁 | 调整推荐算法参数 |
| 资源推荐不合理 | 历史数据不足 | 等待更长时间收集数据 |
| Admission Controller 失败 | Webhook 配置错误 | 检查 Webhook 配置 |
调试命令#
# 检查 VPA 状态
kubectl get vpa --all-namespaces
# 查看 VPA 事件
kubectl get events --field-selector involvedObject.kind=VerticalPodAutoscaler
# 检查 Webhook 配置
kubectl get validatingwebhookconfiguration vpa-webhook-config -o yaml
# 测试 VPA API
kubectl api-resources | grep verticalpodautoscaler
总结与展望#
VPA 的价值#
VPA 作为 Kubernetes 生态系统中的重要组件,为资源优化提供了自动化解决方案:
主要优势#
- 🎯 精确优化:基于实际使用数据进行资源调整
- 💰 成本节约:避免资源过度配置,降低成本
- 🔄 自动化管理:减少手动调优的工作量
- 📊 数据驱动:基于历史数据做出科学决策
当前限制#
- 🔄 需要重启 Pod:更新资源配置时必须重启
- ⚠️ 实验性功能:仍在快速发展中,稳定性有待提升
- 🚫 不适合有状态应用:重启可能导致服务中断
- ⏱️ 响应延迟:需要时间收集数据才能做出调整
未来发展方向#
技术改进#
- In-Place 资源更新:无需重启 Pod 即可调整资源
- 更智能的算法:结合机器学习提升推荐准确性
- 更好的集成:与 HPA、集群自动伸缩器更好协作
- 实时调整:支持更快速的资源调整响应
生产就绪#
随着 Kubernetes 的发展,VPA 正在向生产就绪的方向发展:
- 更稳定的 API
- 更完善的监控和告警
- 更丰富的配置选项
- 更好的文档和工具支持
建议#
对于开发者#
- 从测试环境开始:先在非生产环境验证效果
- 监控资源使用:建立完善的监控体系
- 渐进式采用:从不重要的应用开始尝试
- 持续优化:根据实际效果调整配置
对于运维团队#
- 制定策略:明确哪些应用适合使用 VPA
- 建立流程:制定 VPA 配置和维护流程
- 培训团队:确保团队了解 VPA 的工作原理
- 准备回滚:制定问题发生时的回滚策略
VPA 虽然还在发展中,但已经展现出巨大的潜力。随着技术的不断成熟,它将成为 Kubernetes 资源管理的重要工具,帮助我们构建更高效、更经济的容器化应用。
🚀 展望未来:期待 VPA 能够实现真正的动态资源调整,无需重启 Pod 即可优化资源配置,这将是容器编排技术的重大突破!
