3. VPA(Vertical Pod Autoscaler)原理:组件架构与核心工作流

VPA(Vertical Pod Autoscaler)是 Kubernetes 生态中实现垂直弹性伸缩的核心组件。与 HPA(Horizontal Pod Autoscaler)通过增减副本数来调整容量不同,VPA 通过动态调整 Pod 的 CPU 和内存 Request/Limit 来优化资源利用率。理解 VPA 的内部组件架构是进行压测数据驱动成本优化的前提。

3.1 VPA 三大核心组件架构

VPA 采用微服务架构,由三个独立组件协同工作:Recommender(推荐器)、Updater(更新器)和 Admission Controller(准入控制器)。三者通过 VPA 对象(Custom Resource)和 Metrics API 进行数据交互。

VPA 三大组件架构与数据流 Kubernetes 集群 Metrics API (Metrics Server / Prometheus) Recommender 资源推荐引擎 Updater Pod 驱逐与重建 Admission Controller Pod 创建时注入 VPA 对象 (CRD: VerticalPodAutoscaler) CPU/Mem 指标 读取配置 写入推荐值 读取推荐值 驱逐旧 Pod Pod (旧资源规格) 注入新资源 新 Pod (新资源规格) 读取推荐值 工作流: Recommender 读取 Metrics 和 VPA 对象 → 计算推荐值写入 VPA 对象 → Updater 读取推荐值并驱逐旧 Pod → Admission Controller 在新 Pod 创建时注入推荐资源值

3.2 Recommender:资源推荐引擎

Recommender 是 VPA 的“大脑”,负责基于历史指标和当前负载计算最优资源推荐值。其核心工作流程如下:

  1. 指标采集:从 Metrics Server 或 Prometheus 拉取 Pod 的 CPU 和内存历史使用数据(默认 8 天窗口)。
  2. 分位数计算:根据 VPA 对象中配置的 targetUtilization 和 containerPolicy,计算推荐的分位数(如 P50、P90、P95)。
  3. 边界约束:应用 minAllowed 和 maxAllowed 上下限,确保推荐值在安全范围内。
  4. 写入 VPA 对象:将计算出的 target、lowerBound、upperBound 写入 VPA 对象的 status 字段。

关键参数说明:

  • targetUtilization:目标利用率百分比,Recommender 据此反推 Request 值。例如 CPU 目标利用率 80%,若 Pod 实际使用 400m,则推荐 Request = 400m / 0.8 = 500m。
  • containerPolicy:控制是否启用 VPA 推荐,以及是否允许 OOM(Out of Memory)时自动调整。
  • updateMode:决定 VPA 的推荐行为模式,详见下文表格。

3.3 Updater:Pod 驱逐与重建

Updater 是 VPA 的“执行器”,负责将推荐值应用到运行中的 Pod。其工作流程如下:

  1. 轮询 VPA 对象:定期检查 VPA 对象的 status.recommendation 字段是否有更新。
  2. 计算偏差:比较当前 Pod 的 Request 值与推荐值,判断偏差是否超过阈值(默认 15%)。
  3. 驱逐 Pod:若偏差超过阈值,Updater 通过 Kubernetes API 驱逐(Evict)该 Pod。
  4. 触发重建:被驱逐的 Pod 由控制器(如 Deployment、StatefulSet)自动重建,重建时由 Admission Controller 注入新资源值。

⚠️ 生产环境注意事项:

  • Updater 驱逐 Pod 会导致 Pod 重建,可能引发短暂的服务中断。建议结合 PDB(PodDisruptionBudget)控制同时驱逐的 Pod 数量。
  • 对于有状态应用(如数据库),驱逐可能导致数据迁移或主从切换,需谨慎配置 updateMode。
  • Updater 默认每 60 秒检查一次 VPA 对象,可通过 --updater-interval 参数调整。

3.4 Admission Controller:资源注入

Admission Controller 是 VPA 的“守门员”,负责在 Pod 创建时动态修改资源 Request/Limit。其工作流程如下:

  1. 拦截 Pod 创建请求:当 Pod 被创建时,Admission Controller 通过 MutatingWebhookConfiguration 拦截请求。
  2. 查询 VPA 对象:根据 Pod 的标签选择器匹配对应的 VPA 对象,读取 status.recommendation 中的推荐值。
  3. 注入资源值:将推荐值写入 Pod 的 spec.containers[].resources.requests 和 limits 字段。
  4. 放行 Pod:修改完成后,Admission Controller 将修改后的 Pod 定义返回给 API Server,完成创建。

💡 最佳实践:Admission Controller 仅在 Pod 创建时生效。对于已运行的 Pod,必须由 Updater 驱逐后重建才能应用新推荐值。因此,在压测场景中,建议先通过 Recommender 生成推荐值,再手动触发滚动更新以批量应用新资源规格。

3.5 VPA 更新模式对比

VPA 支持三种更新模式,通过 updateMode 字段配置,适用于不同场景:

模式 值 行为描述 适用场景
Auto Auto Recommender 自动计算推荐值,Updater 自动驱逐 Pod,Admission Controller 自动注入新值 生产环境自动化资源优化
Initial Initial 仅在新 Pod 创建时注入推荐值,不驱逐已有 Pod 滚动更新、新部署场景
Off Off Recommender 继续计算推荐值并写入 VPA 对象,但不执行任何 Pod 修改操作 仅查看推荐值、压测数据收集阶段

3.6 VPA 对象定义示例

以下是一个完整的 VPA 对象 YAML 定义,展示了核心字段的配置方式:

apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: my-app-vpa
  namespace: production
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  updatePolicy:
    updateMode: Auto          # 可选:Auto / Initial / Off
  resourcePolicy:
    containerPolicies:
    - containerName: "*"      # 匹配所有容器
      minAllowed:
        cpu: 100m
        memory: 128Mi
      maxAllowed:
        cpu: 4
        memory: 8Gi
      controlledResources: ["cpu", "memory"]
      controlledValues: RequestsAndLimits  # 同时控制 Request 和 Limit
status:
  recommendation:
    containerRecommendations:
    - containerName: my-app
      target:
        cpu: 500m
        memory: 512Mi
      lowerBound:
        cpu: 300m
        memory: 256Mi
      upperBound:
        cpu: 1
        memory: 1Gi
      uncappedTarget:
        cpu: 600m
        memory: 768Mi

字段说明:

  • targetRef:指定 VPA 要管理的目标对象(Deployment、StatefulSet 等)。
  • updatePolicy.updateMode:控制 VPA 的自动执行行为。
  • resourcePolicy.containerPolicies:定义每个容器的资源上下限和策略。
  • status.recommendation:Recommender 写入的推荐结果,包含 target(目标值)、lowerBound(下限)、upperBound(上限)和 uncappedTarget(未约束的原始推荐值)。

3.7 组件协作时序图

以下时序图展示了 VPA 三大组件在 Auto 模式下的完整协作流程:

VPA Auto 模式组件协作时序 Metrics Recommender VPA Object Updater Pod ① 拉取 CPU/Mem 历史指标 ② 读取 VPA 配置 ③ 写入 target/lowerBound/upperBound ④ 轮询推荐值变化 ⑤ 驱逐旧 Pod Pod 重建 ⑥ 查询推荐值 ⑦ 注入新资源值 新 Pod 运行

3.8 压测场景下的 VPA 配置建议

在进行压测数据驱动成本优化时,建议按以下阶段配置 VPA:

阶段 updateMode 目标 操作说明
数据收集 Off 仅收集推荐值,不修改 Pod 运行压测负载,让 Recommender 积累历史数据并生成推荐值
基线校准 Initial 在新 Pod 创建时应用推荐值 手动触发滚动更新,批量应用推荐值,验证容量基线
自动化优化 Auto 全自动资源优化 结合 PDB 和 HPA,实现弹性伸缩与资源优化的联动

⚠️ 证书轮换与 VPA 的关联:在证书轮换场景中,VPA 的 Updater 驱逐 Pod 可能导致证书挂载路径变化或证书文件重新加载。建议在证书轮换完成后,再触发 VPA 的批量更新操作,避免证书与资源调整同时进行导致服务中断。