什么是 VPA?#
Vertical Pod Autoscaler(VPA,垂直 Pod 自动伸缩器)会根据 Pod 的资源使用情况调整 CPU 和内存 requests。它适合解决资源请求长期偏高或偏低的问题,但更新资源时通常需要重启 Pod。
为什么需要 VPA?#
在实际生产环境中,我们经常遇到以下问题:
| 问题 | 影响 | VPA 解决方案 |
|---|---|---|
| 资源配置过高 | 浪费集群资源,成本增加 | 自动降低资源请求 |
| 资源配置过低 | 应用性能差,频繁重启 | 自动提高资源请求 |
| 手动调优困难 | 耗时耗力,容易出错 | 基于历史数据自动优化 |
| 动态负载变化 | 静态配置无法适应 | 持续监控和调整 |
VPA vs HPA#
| 特性 | VPA(垂直伸缩) | HPA(水平伸缩) |
|---|---|---|
| 伸缩方向 | 调整单个 Pod 的资源 | 调整 Pod 的数量 |
| 适用场景 | 单体应用、有状态应用 | 无状态应用、微服务 |
| 资源类型 | CPU、内存 | 主要基于 CPU |
| 伸缩速度 | 需要重启 Pod | 相对较快 |
| 兼容性 | 不能同时使用 | 可以组合使用 |
VPA 工作原理#
VPA 由三个组件组成。Recommender 持续读取 Pod 的资源使用情况并生成建议;Updater 比较当前配置和建议值,决定是否更新;Admission Controller 在 Pod 创建或重启时把建议值写入资源配置。更新策略和是否自动执行,取决于 VPA 对象的配置。
环境要求#
系统要求#
| 组件 | 版本要求 | 说明 |
|---|---|---|
| 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
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 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 的建议依赖历史数据,刚部署时不会立刻得到稳定结果。自动更新可能重启 Pod,因此先在测试环境验证,并为重要工作负载准备回滚方案。它和 HPA 同时使用时要明确 CPU、内存和副本数分别由谁负责,避免两个控制器互相影响。
