Pod 纵向自动扩缩

本页面介绍如何使用 Pod 纵向自动扩缩功能在 Google Kubernetes Engine (GKE) 中分析和优化资源分配,以提高工作负载效率。通过分析工作负载在一段时间内的资源使用情况,您可以获得优化建议,并自动调整 Pod 中容器的 CPU 和内存请求以及限制。

在本页面中,您将了解 Pod 纵向自动扩缩的工作原理、优势和限制、使用方法最佳实践,并访问 API 参考文档,以了解 VerticalPodAutoscaler 自定义资源和相关类型。

本页面适用于预配和配置云资源、部署工作负载以及管理应用伸缩的运维人员和开发者。如需详细了解常见角色,请参阅 常见的 GKE 用户角色和任务

在阅读本页面之前,请确保您熟悉 Kubernetes 中的资源请求和限制

如果需要快速伸缩以应对突然增加的资源使用量,请使用 Pod 横向自动伸缩器

如需了解自动扩缩的最佳实践,请参阅 在 GKE 上运行费用经过优化的 Kubernetes 应用的最佳实践

为何使用 Pod 纵向自动扩缩

Pod 纵向自动扩缩具有以下优势:

  • 为工作负载设置适当的资源请求和限制可以提高稳定性和成本效益。如果 Pod 资源大小低于工作负载所需的大小,则您的应用可能会受到限制,或者由于内存不足错误而可能发生故障。如果资源大小过大,则会造成浪费,进而产生高额账单。
  • 因为 Pod 完全用其所需,所以集群节点使用效率高。
  • Pod 会被安排到具有适当可用资源的节点上。
  • 您不必运行耗时的基准测试任务来确定 CPU 和内存请求的正确值。
  • 自动扩缩器可以随时间推移调整 CPU 和内存请求,而无需您执行任何操作,所以维护时间缩短。
  • Pod 纵向自动扩缩功能最适合长时间运行的同质工作负载。

与 Kubernetes 开源自动扩缩器相比,GKE Pod 纵向自动扩缩具有以下优势:

  • 在确定推荐目标时,会考虑节点大小上限和资源配额。
  • 通知 集群自动扩缩器来 调整集群容量。
  • 使用历史数据,包括在您启用 VerticalPodAutoscaler 之前收集的指标。
  • 将 VerticalPodAutoscaler Pod 作为 控制平面 进程运行,而不是作为您的 工作器节点上的部署运行。

Pod 纵向自动扩缩的工作原理

借助 Pod 纵向自动扩缩,您可以分析和设置 Pod 所需的 CPU 和内存资源。您无需为 Pod 中的容器设置最新的 CPU 请求和限制以及内存请求和限制,而是可以配置 Pod 纵向自动扩缩,以便为可用于手动更新 Pod 的 CPU 和内存请求及限制提供建议值,也可以将 Pod 纵向自动扩缩配置为自动更新这些值。

在 Autopilot 集群中,Pod 纵向自动扩缩默认处于启用状态。

与 Kubernetes 开源 VerticalPodAutoscaler 的关系

GKE Pod 纵向自动扩缩基于开源 Kubernetes VerticalPodAutoscaler API,但它是 GKE 独有的单独实现。GKE 实现旨在通过其自己的 Recommender 进行扩缩,但保留了在开源版本中定义的相同的 VerticalPodAutoscaler API 种类和字段。

如需了解详情,请参阅 Kubernetes 文档中的 Pod 纵向自动扩缩

Pod 纵向自动扩缩模式

您可以通过应用不同的更新模式来配置 Pod 纵向自动扩缩应用资源更改的方式。

Auto (Recreate) 模式

Recreate 模式下,如果需要更改某个 Pod 的资源请求,Pod 纵向自动扩缩会逐出该 Pod。由于 Kubernetes 在 1.33 之前的版本中存在限制,修改正在运行的 Pod 的资源请求的唯一方法是重新创建该 Pod,因此需要逐出。

如需限制 Pod 重新创建的数量,请使用 Pod 中断预算。 如需确保集群可以处理新规模的工作负载,请使用 集群自动扩缩器节点自动预配

Pod 纵向自动扩缩会在更新之前通知集群自动扩缩器,并在重新创建工作负载之前提供调整规模的工作负载所需的资源,以最大限度地缩短中断时间。

Initial模式

启用 Initial 后,Pod 纵向自动扩缩仅会在创建 Pod 时分配资源请求,之后不再进行更改。

InPlaceOrRecreate 模式

InPlaceOrRecreate 模式旨在通过尝试更新 Pod 资源而不重新创建 Pod 来减少服务中断。

如需使用 InPlaceOrRecreate 模式,请将 VerticalPodAutoscaler 对象中的 spec.updatePolicy.updateMode 字段设置为 "InPlaceOrRecreate"。此模式依赖于工作负载清单中定义的 resizePolicy 字段来确定资源更改是否需要重启。如果未定义 resizePolicy 字段,则 CPU 和内存默认设置为 NotRequired,这意味着系统会尝试就地更新。

如果容器因 OOM(内存不足)事件而终止,则 InPlaceOrRecreate 模式下的 Pod 纵向自动扩缩的行为与 Auto 模式类似:它会从失败中学习。在因崩溃而触发后续 Pod 重新创建时,Pod 纵向自动扩缩会应用包含安全缓冲区的建议(通常为额外 20% 的内存或 100 MB,以较大者为准),以防止立即重复出现 OOM 错误。

InPlaceOrRecreate 模式适用于 Kubernetes 版本 1.34.0-gke.2201000 及更高版本。

InPlaceOrRecreate 模式的回退场景

如果 Pod 纵向自动扩缩确定无法进行就地更新,则会回退到 Recreate 模式行为,即逐出并重新创建 Pod 以应用更改。Pod 纵向自动扩缩回退到重新创建的一些常见场景包括:

  • 节点容量不足 :更新后的资源请求超出了当前节点的可分配容量,并且无法就地安排更新(“不可行”或“延迟”状态超过超时时间)。
  • QoS 类更改 :资源更新会更改 Pod 的服务质量 (QoS) 类,例如从 Burstable 更改为 Guaranteed
  • RestartContainer 政策 :对于 Pod 纵向自动扩缩尝试更改的资源,Pod 的 resizePolicy 字段设置为 RestartContainer
  • 超时 :就地更新请求处于待处理状态的时间过长。

Off 模式

Off 模式下,Pod 纵向自动扩缩不会自动对 Pod 进行任何更改。 您仍然可以根据历史使用情况查看 CPU 和内存的请求和限制的建议值,但系统不会为您应用这些建议。您可以根据需要手动将建议值应用于 Pod。

资源政策

您可以使用 ContainerResourcePolicy 自定义 Pod 纵向自动扩缩为特定容器生成建议的方式。借助此政策,您可以设置限制并控制扩缩哪些资源。

最小值和最大值限制

您可以为容器指定最小 (minAllowed) 和最大 (maxAllowed) 资源值。

  • minAllowed:Pod 纵向自动扩缩不会推荐低于此限制的值。此限制非常有用,因为它有助于确保基准性能水平或满足应用特定的要求。
  • maxAllowed:Pod 纵向自动扩缩不会推荐高于此限制的值。此限制有助于控制费用或防止单个容器消耗过多的节点资源。

受控资源

默认情况下,Pod 纵向自动扩缩会计算 CPU 和内存的建议。您可以使用 controlledResources 字段指定要自动扩缩的资源。例如,您可以将自动扩缩器配置为仅提供内存建议,而 CPU 请求保持不变。

限制

  • 如需将 Pod 纵向自动扩缩与Pod 横向自动扩缩结合使用,请使用Pod 多维自动扩缩。您还可以为自定义外部指标结合使用 Pod 纵向自动扩缩和 Pod 横向自动扩缩。
  • Pod 纵向自动扩缩目前无法用于基于 JVM 的工作负载,因为对此类工作负载的实际内存用量的了解有限。
  • 在 GKE 1.35.1 及更早版本中,Pod 纵向自动扩缩的默认设置至少为两个副本,以便 Deployment 将 Pod 替换为修改后的资源值。在 1.35.2 及更高版本中,默认值为一个副本。在 1.22 及更高版本中,您可以通过 在 PodUpdatePolicy 字段中指定 minReplicas 字段的值来替换此设置。
  • 如果您使用 Pod 纵向自动扩缩的 InPlaceOrRecreate 更新模式,但无法进行就地更新(例如,当 Pod 纵向扩容超出节点容量时),Pod 纵向自动扩缩会逐出并重新创建 Pod 以应用建议。即使对于在其规范中设置了 resizePolicy 字段以避免重新创建的 Pod,也会发生逐出和重新创建。此行为适用于 Autopilot 调整大小请求, 包括应用 最小资源和 CPU:内存比率限制时。
  • Pod 纵向自动扩缩需要管理 Pod 的工作负载对象,例如 Deployment、StatefulSet、ReplicaSet 或 ReplicationControllers。您无法将 Pod 纵向自动扩缩与独立 Pod 结合使用,因为需要工作负载控制器来管理 Pod 重新创建过程。

最佳做法

  • 限制 VerticalPodAutoscaler 对象的数量。为避免集群更新中断,我们建议您将每个集群的 VerticalPodAutoscaler 对象数量保持在 1,000 以下。
  • Pod 纵向自动扩缩功能最适合长时间运行的同质工作负载。
    • 长时间运行 :运行时间至少为 24 小时的工作负载。Pod 纵向自动扩缩需要大量历史数据才能生成高可信度的建议。在 AutoRecreate 模式下,更新通常在 Pod 至少运行 24 小时后发生,这有助于防止频繁的 Pod 重启和流失。
    • 同质 :单个 VerticalPodAutoscaler 对象(例如 Deployment 中的所有副本)所针对的 Pod 应表现出相似的资源消耗模式。Pod 纵向自动扩缩器通过汇总所有目标 Pod 的使用情况数据来生成建议。如果您的副本具有异构使用情况(例如,某些 Pod 处于空闲状态,而其他 Pod 处于高负载状态),则 Pod 纵向自动扩缩器可能会提供过度预配空闲 Pod 或预配不足繁忙 Pod 的建议。
  • 对于需求突然激增的工作负载,请使用 Pod 横向自动扩缩。Pod 纵向自动扩缩专为稳态调整大小而设计,并非针对突然的短期资源激增的解决方案。 对于流量或 CPU 或内存需求快速波动的工作负载,请改用 Pod 横向自动扩缩器
  • 利用 OOM 保护。虽然 Pod 纵向自动扩缩器是反应式的,但它确实包含针对内存不足 (OOM) 事件的自动保护。如果 Pod 为 OOMKilled,则 Pod 纵向自动扩缩器会立即观察到该事件,并将内存建议增加大约 20%(或 100 MB,以较大者为准),以在重新创建 Pod 时提高稳定性。如需详细了解 OOM 事件,请参阅排查 OOM 事件问题

API 参考文档

这是 v1 API 参考文档。我们强烈建议您使用此版本的 API。

VerticalPodAutoscaler v1 autoscaling.k8s.io

字段

TypeMeta

API 组、版本和种类。

metadata

ObjectMeta

标准对象元数据

spec

VerticalPodAutoscalerSpec

VerticalPodAutoscaler 的行为。

status

VerticalPodAutoscalerStatus

最近观察到的 VerticalPodAutoscaler 的状态。

VerticalPodAutoscalerSpec v1 autoscaling.k8s.io

字段
targetRef

CrossVersionObjectReference

引用用于管理一组 Pod 以供自动扩缩器控制的控制器,例如 Deployment 或 StatefulSet 控制器。您可以将 VerticalPodAutoscaler 指向任何具有 Scale 子资源的控制器。一般而言,VerticalPodAutoscaler 从控制器的 ScaleStatus 中检索 Pod 集合 。如果是 DaemonSet 等一些众所周知的控制器,VerticalPodAutoscaler 会从控制器的规范中检索 Pod 集合。

updatePolicy

PodUpdatePolicy

指定在 Pod 启动时是否应用推荐的更新,以及在 Pod 的生命周期内是否应用推荐的更新。

resourcePolicy

PodResourcePolicy

指定如何为各个容器调整 CPU 和内存请求的政策。资源政策可用于设置针对各个容器的建议约束。如果未 指定,自动扩缩器将计算 Pod 中所有 容器的推荐资源,且不受其他限制。

recommenders

VerticalPodAutoscalerRecommenderSelector array

负责为此 VPA 对象生成建议的 Recommender。留空可使用 GKE 提供的默认 Recommender。否则,列表只能为用户提供的备用 Recommender 提供一个条目。从 GKE 1.22 开始受支持。

VerticalPodAutoscalerList v1 autoscaling.k8s.io

字段

TypeMeta

API 组、版本和种类。

metadata

ObjectMeta

标准对象元数据

items

VerticalPodAutoscaler array

VerticalPodAutoscaler 对象的列表。

PodUpdatePolicy v1 autoscaling.k8s.io

字段
updateMode

string

指定在 Pod 启动时是否应用推荐的更新,以及在 Pod 的生命周期内是否应用推荐的更新。可能的值如下:

  • "Off":系统会生成建议的更新,但不会自动将其应用于 Pod。
  • "Initial":仅在首次启动 Pod 时应用建议的更新。在 Pod 已经运行时发生的更新不会自动应用。
  • "Recreate":通过重新创建 Pod 来应用建议的更新。现有 Pod 会终止,并创建一个具有更新后的配置的新 Pod。
  • "Auto":默认值,实际上会强制执行 "Recreate" 模式。
  • "InPlaceOrRecreate":如果可能,在不重新创建 Pod 的情况下应用建议的更新。
minReplicas

int32

尝试 Pod 逐出所需的最小活跃副本数(等待其他检查,如 Pod 中断预算)。 仅允许使用正值。在 GKE 1.35.2 及更高版本中,默认值为 1,而在 1.35.1 及更早版本中,默认值为 2。从 GKE 1.22 开始受支持。

PodResourcePolicy v1 autoscaling.k8s.io

字段
containerPolicies

ContainerResourcePolicy array

各个容器的一系列资源政策。 每个命名容器最多只能有 1 个条目,可以选择性地使用 `containerName =“*”单个通配符条目,该条目可以处理所有不具有单独政策的容器。

ContainerResourcePolicy v1 autoscaling.k8s.io

字段
containerName

string

政策适用的容器的名称。如果未指定,则政策将用作默认政策。

mode

ContainerScalingMode

指定在容器启动时是否将推荐的更新应用于容器,以及在容器的生命周期内是否应用推荐的更新。可能的值为“关闭”和“自动”。 如果您未指定值,则默认值为“自动”。

minAllowed

ResourceList

指定容器允许的最小 CPU 请求和内存请求。默认情况下,不会应用最小值。

maxAllowed

ResourceList

指定容器允许的最大 CPU 请求和内存请求。默认情况下,不会应用最大值。

ControlledResources

[]ResourceName

指定将由 VerticalPodAutoscaler 计算(且可能会应用)的建议类型。如果为空,则默认使用 [ResourceCPU, ResourceMemory]

VerticalPodAutoscalerRecommenderSelector v1 autoscaling.k8s.io

字段
name

string

负责为此对象生成建议的 Recommender 的名称。

VerticalPodAutoscalerStatus v1 autoscaling.k8s.io

字段
recommendation

RecommendedPodResources

最近推荐的 CPU 和内存请求。

conditions

VerticalPodAutoscalerCondition array

描述 VerticalPodAutoscaler 的当前状态。

RecommendedPodResources v1 autoscaling.k8s.io

字段
containerRecommendation

RecommendedContainerResources array

针对各个容器的一系列资源推荐。

RecommendedContainerResources v1 autoscaling.k8s.io

字段
containerName

string

推荐适用的容器的名称。

target

ResourceList

容器的推荐 CPU 请求和内存请求。

lowerBound

ResourceList

容器的最小推荐 CPU 请求和内存请求。该数量不足以保证应用的稳定性。使用较小的 CPU 和内存请求运行可能会对性能或可用性产生重大影响。

upperBound

ResourceList

容器的最大推荐 CPU 请求和内存请求。高于推荐值的 CPU 和内存请求可能会被浪费。

uncappedTarget

ResourceList

由自动扩缩器计算的最新资源推荐 基于实际资源使用情况,而不考虑 ContainerResourcePolicy。如果 实际资源使用情况会导致目标违反 ContainerResourcePolicy,则此值可能与限定的建议 不同。此字段不会影响实际的 资源分配。而是仅用于指示状态。

VerticalPodAutoscalerCondition v1 autoscaling.k8s.io

字段
type

VerticalPodAutoscalerConditionType

正在描述的条件的类型。可能的值为“RecommendationProvided”、“LowConfidence”、“NoPodsMatched”和“FetchingHistory”。

status

ConditionStatus

条件的状态。可能的值为True、False和Unknown。

lastTransitionTime

Time

条件上次从一种状态转换到另一种状态的时间。

reason

string

上次从一种状态转换到另一种状态的原因。

message

string

人类可读的字符串,提供有关上次从一种状态转换到另一种状态的详细信息。

后续步骤