在 Kubernetes 中,VerticalPodAutoscaler 会自动更新工作负载管理 资源(例如 Deployment 或 StatefulSet),旨在自动调整基础设施 资源 请求和限制,以匹配实际使用情况。
垂直缩放意味着对增加的资源需求做出的响应是为已经在运行的工作负载 Pod 分配更多资源(例如:内存或 CPU)。这也称为合理调整大小 (rightsizing),有时也称为自动驾驶 (autopilot)。这与水平缩放不同,水平缩放对于 Kubernetes 而言意味着部署更多 Pod 来分担负载。
如果资源使用量减少,且 Pod 资源请求高于最佳水平,VerticalPodAutoscaler 会指示工作负载资源(Deployment、StatefulSet 或其他类似资源)调低资源请求,从而防止资源浪费。
VerticalPodAutoscaler 是作为 Kubernetes API 资源和 控制器来实现的。该资源决定了控制器的行为。垂直 Pod 自动扩缩容控制器在 Kubernetes 数据平面内运行,根据对历史资源利用率、集群中可用资源量以及实时事件(例如内存不足 (OOM) 情况)的分析,定期调整其目标(例如 Deployment)的资源请求和限制。
VerticalPodAutoscaler 在 Kubernetes 中定义为 自定义资源定义 (CRD)。与作为核心 Kubernetes API 一部分的 HorizontalPodAutoscaler 不同,VPA 必须在您的集群中单独安装。
当前的稳定 API 版本是 autoscaling.k8s.io/v1。有关 VPA 安装和 API 的更多详细信息,可以在 VPA GitHub 仓库中找到。
图 1. VerticalPodAutoscaler 控制 Deployment 中 Pod 的资源请求和限制
Kubernetes 通过多个间歇性运行的协作组件来实现垂直 Pod 自动扩缩容(这不是一个连续的过程)。VPA 由三个主要组件组成
在每个周期内,推荐器都会查询每个 VerticalPodAutoscaler 定义所针对的 Pod 的资源利用率。推荐器找到由 targetRef 定义的目标资源,然后根据目标资源的 .spec.selector 标签选择 Pod,并从资源指标 API 获取指标以分析实际的 CPU 和内存消耗。
推荐器会分析 VerticalPodAutoscaler 针对的每个 Pod 的当前和历史资源使用数据(CPU 和内存)。它会检查
基于此分析,推荐器计算三种类型的建议
这些建议存储在 VerticalPodAutoscaler 资源的 .status.recommendation 字段中。
更新器组件监控 VerticalPodAutoscaler 资源,并将当前的 Pod 资源请求与建议进行比较。当差异超过配置的阈值且更新策略允许时,更新器可以
选择的方法取决于配置的更新模式、集群功能以及所需的资源变更类型。原地更新(如果可用)可以避免 Pod 中断,但可能对可以修改的资源有限制。更新器会尊重 PodDisruptionBudget,以尽量减少对服务的影响。
准入控制器作为变更 Webhook 运行,用于拦截 Pod 创建请求。它检查 Pod 是否由 VerticalPodAutoscaler 针对,如果是,则在 Pod 创建之前应用建议的资源请求和限制。更具体地说,准入控制器使用 VerticalPodAutoscaler 资源 .status.recommendation 节中的目标建议作为新的资源请求。准入控制器确保新 Pod 以适当大小的资源分配启动,无论它们是在初始部署期间、被更新器驱逐后,还是由于缩放操作而创建的。
VerticalPodAutoscaler 要求在集群中安装指标源,例如 Kubernetes 的 Metrics Server 插件 (add-on)。VPA 组件从 metrics.k8s.io API 获取指标。Metrics Server 需要单独启动,因为它在大多数集群中默认不部署。有关资源指标的更多信息,请参阅 Metrics Server。
VerticalPodAutoscaler 支持不同的更新模式,这些模式控制如何以及何时将资源建议应用于您的 Pod。您可以使用 VPA 规范中 updatePolicy 下的 updateMode 字段来配置更新模式
---
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: my-app-vpa
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: my-app
updatePolicy:
updateMode: "Recreate" # Off, Initial, Recreate, InPlaceOrRecreate
在 Off 更新模式下,VPA 推荐器仍然会分析资源使用情况并生成建议,但这些建议不会自动应用于 Pod。建议仅存储在 VPA 对象的 .status 字段中。
您可以使用 kubectl 等工具查看 .status 及其中的建议。
在 Initial 模式下,VPA 仅在首次创建 Pod 时设置资源请求。它不会更新已运行 Pod 的资源,即使建议随时间发生变化。建议仅在 Pod 创建时应用。
在 Recreate 模式下,VPA 通过在当前资源请求与建议存在显著差异时驱逐 Pod 来积极管理 Pod 资源。当 Pod 被驱逐时,工作负载控制器(管理 Deployment、StatefulSet 等)会创建一个替换 Pod,VPA 准入控制器会将更新后的资源请求应用于新 Pod。
在 InPlaceOrRecreate 模式下,VPA 尝试在不重启 Pod 的情况下更新 Pod 资源请求和限制。但是,如果无法对特定的资源更改执行原地更新,VPA 将回退到驱逐 Pod(类似于 Recreate 模式),并允许工作负载控制器创建带有更新后资源的新 Pod。
在此模式下,更新器使用 原地调整容器资源大小 (Resize Container Resources In-Place) 功能原地应用建议。
Auto 更新模式自 VPA 1.4.0 版本起已被弃用。对于基于驱逐的更新,请使用 Recreate;对于带有驱逐回退的原地更新,请使用 InPlaceOrRecreate。Auto 模式目前是 Recreate 模式的别名,其行为相同。引入它是为了允许未来扩展自动更新策略。
资源策略允许您微调 VerticalPodAutoscaler 生成建议和应用更新的方式。您可以设置资源建议的边界,指定要管理的资源,并为 Pod 内的单个容器配置不同的策略。
您可以在 VPA 规范的 resourcePolicy 字段中定义资源策略
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: my-app-vpa
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: my-app
updatePolicy:
updateMode: "Recreate"
resourcePolicy:
containerPolicies:
- containerName: "application"
minAllowed:
cpu: 100m
memory: 128Mi
maxAllowed:
cpu: 2
memory: 2Gi
controlledResources:
- cpu
- memory
controlledValues: RequestsAndLimits
这些字段为 VPA 建议设置边界。即使实际使用数据建议不同的值,VPA 也永远不会建议低于 minAllowed 或高于 maxAllowed 的资源。
controlledResources 字段指定 VPA 应该为 Pod 中的容器管理哪些资源类型。如果不指定,VPA 默认同时管理 CPU 和内存。您可以限制 VPA 仅管理特定资源。有效的资源名称包括 cpu 和 memory。
controlledValues 字段确定 VPA 是控制资源请求、限制,还是两者都控制
请参阅 请求和限制 以了解有关这两个概念的更多信息。
准入控制器和更新器 VPA 组件会对建议进行后处理,以符合 LimitRanges 中定义的约束。Kubernetes 集群中会检查 type 为 Pod 和 Container 的 LimitRange 资源。
例如,如果超出了 Container LimitRange 资源中的 max 字段,两个 VPA 组件都会将限制降低到 max 字段中定义的值,并且请求会按比例降低,以保持 Pod 规范中的请求与限制比率。
如果您在集群中配置了自动扩缩容,您可能还需要考虑使用 节点自动扩缩容,以确保您运行的是正确数量的节点。您还可以阅读有关 水平 Pod 自动扩缩容 的更多信息。