集群自动扩缩简介


本页面介绍 Google Kubernetes Engine (GKE) 如何根据工作负载需求自动调整 Standard 集群的节点池大小。 当需求较高时,集群自动扩缩器会将节点添加到节点池中。如需了解如何配置集群自动扩缩器,请参阅自动扩缩集群

本页面适用于规划容量和基础设施需求以及优化系统架构和资源以确保公司或业务部门的总拥有成本达到最低的管理员、架构师和运维人员。如需详细了解我们在 Google Cloud 内容中提及的常见角色和示例任务,请参阅常见的 GKE Enterprise 用户角色和任务

借助 Autopilot 集群,您无需担心预配节点或节点池,因为节点池通过节点自动预配自动预配;并自动扩缩以满足工作负载的要求。

最佳实践

与贵组织的管理员和架构师、开发者或负责应用的实现和维护的其他团队一起规划和设计集群配置。

为何使用集群自动扩缩器

GKE 的集群自动扩缩器会根据工作负载的需求自动调整给定节点池中的节点数量。当需求较低时,集群自动扩缩器会将节点池缩减到您指定的最小大小。这样可以在您需要时提高工作负载的可用性,同时控制费用。您不需要手动添加或移除节点,也不需要过度预配节点池。您只需指定节点池的最小大小和最大大小即可,其他操作都是自动执行的。

在系统自动扩缩集群时,如果删除或移动资源,则工作负载可能会暂时中断。例如,如果工作负载包含具有单个副本的控制器,则在删除该副本的 Pod 的当前节点时,系统可能会将此 Pod 重新调度到其他节点上。启用集群自动扩缩器之前,请设计好工作负载以容忍潜在的中断或确保关键的 Pod 不会中断。

最佳实践

如需提高工作负载对中断的容忍度,请使用具有多个副本的控制器(例如 Deployment)部署工作负载。

您可以使用映像流式传输功能提高集群自动扩缩器的性能,该功能可远程流式传输符合条件的容器映像所需的映像数据,同时在本地缓存映像以允许新节点上的工作负载能够以更快的速度启动。

集群自动扩缩器的工作原理

集群自动扩缩器以每个节点池为单位进行扩缩。配置具有集群自动扩缩器的节点池时,您需要指定节点池的最小大小和最大大小。

通过在自动扩缩器的底层 Compute Engine 托管实例组 (MIG) 中添加或移除虚拟机 (VM) 实例,集群自动扩缩器会自动增大或减小节点池的大小。集群自动扩缩器会根据在该节点池的节点上运行的 Pod 的资源请求(而不是实际资源利用率)做出这些扩缩决策。它会定期检查 Pod 和节点的状态,并执行相应的操作:

  • 如果 Pod 在任何当前节点上调度失败,集群自动扩缩器会添加节点(最多添加到节点池的最大大小)。如需详细了解集群自动扩缩器何时更改集群的大小,请参阅集群自动扩缩器何时更改集群的大小?
  • 如果 GKE 决定将新节点添加到节点池中,集群自动扩缩器会根据需要添加尽可能多的节点(最多不超过每节点池或每集群的限制)。
  • 集群自动扩缩器不会等到一个节点启动后才创建下一个节点。一旦 GKE 决定要创建多少个节点,节点创建就会并行进行。我们的目标是尽可能缩短不可调度 Pod 变为 Active 所需的时间。
  • 如果由于配额用尽而未能创建某些节点,集群自动扩缩器会等待,直到可以成功调度资源为止。
  • 如果节点未充分利用,并且系统在节点池中的节点减少的假设下仍可以调度所有 Pod,则集群自动扩缩器会移除节点(最多移除到节点池的最小大小)。如果节点上有 Pod 无法移动到集群中的其他节点,则集群自动扩缩器不会尝试纵向缩容该节点。如果 Pod 可以移动到其他节点,但系统不能在超时期限(目前为 10 分钟)后正常排空节点,则节点会被强制终止。GKE 集群无法配置宽限期。 如需详细了解纵向缩容的工作原理,请参阅集群自动扩缩器文档

集群自动扩缩器检查集群中是否有不可调度的 Pod 的频率在很大程度上取决于集群的大小。在小型集群中,检查可能会每隔几秒钟进行一次。无法定义此检查所需的确切时间范围。

如果您的 Pod 请求或默认使用的资源不足,导致节点出现短缺情况,集群自动扩缩器不会纠正此情况。您可以通过为所有工作负载发出显式资源请求,帮助确保集群自动扩缩器尽可能准确地工作。

请勿为集群节点启用针对托管式实例组的 Compute Engine 自动扩缩功能。GKE 的集群自动扩缩器独立于 Compute Engine 自动扩缩功能。这可能导致节点池无法扩缩,因为 Compute Engine 自动扩缩器将与 GKE 的集群自动扩缩器冲突。

操作条件

在调整节点池的大小时,集群自动扩缩器会做出以下假设:

  • 所有复制的 Pod 都可以在其他某些节点上重启,可能会导致短暂的中断。
  • 用户或管理员不会手动管理节点。集群自动扩缩器可以替换您执行的任何手动节点管理操作。
  • 单个节点池中的所有节点都具有一组相同的标签。
  • 集群自动扩缩器会考虑各个池中实例类型的相对费用,并尝试扩展尽可能便宜的节点池。集群自动扩缩器会考虑成本更低的包含抢占式 Spot 虚拟机的节点池。
  • 在调度 Pod 之前,集群自动扩缩器会考虑 init 容器请求。Init 容器请求可以使用节点上可用的任何未分配资源,这可能会阻止 Pod 调度。集群自动扩缩器遵循的请求计算规则与 Kubernetes 使用的规则相同。如需了解详情,请参阅有关使用 init 容器的 Kubernetes 文档
  • 初始集群或节点池创建后手动添加的标签未加以跟踪。集群自动扩缩器创建的节点在创建节点池时分配有使用 --node-labels 指定的标签。
  • 在 GKE 1.21 版或更早版本中,集群自动扩缩器会考虑使用节点池中现有节点的污点信息来表示整个节点池。从 GKE 1.22 版开始,集群自动扩缩器会将集群和节点池中现有节点的信息组合在一起。集群自动扩缩器还会检测您对节点和节点池所做的手动更改。
最佳实践

如果您的应用无法容忍中断,请勿启用集群自动扩缩器。

跨可用区保持平衡

如果您的节点池包含具有相同实例类型的多个托管式实例组,则集群自动扩缩器会尝试在扩容时保持这些托管式实例组的大小平衡。这有助于防止节点在节点池多个可用区的托管式实例组中分布不均匀。GKE 在缩容时不会考虑自动扩缩政策。

集群自动扩缩器在纵向扩容事件期间仅跨可用区进行平衡。无论节点池中底层托管式实例组的相对大小如何,集群自动扩缩器都会缩减未充分利用的节点,这可能导致节点在各可用区分布不均匀。

位置政策

从 GKE 1.24.1-gke.800 版开始,您可以更改集群自动扩缩器的位置政策。您可以通过使用以下任何值指定 location_policy 标志来控制集群自动扩缩器的分布政策:

  • BALANCED:集群自动扩缩器会考虑 Pod 要求以及每个可用区的资源可用性。这不保证类似的节点组具有完全相同的大小,因为集群自动扩缩器会考虑许多因素,包括给定可用区的可用容量以及触发扩容的 Pod 的可用区亲和性。
  • ANY:集群自动扩缩器会优先利用未使用的预留并考虑可用资源的当前限制条件。
最佳实践

如果您使用的是 Spot 虚拟机,或者想要使用可用区之间不相等的虚拟机预留,请使用 ANY 政策。

预订

从 GKE 1.27 版开始,集群自动扩缩器在进行纵向扩容决策时始终会考虑reservations。在选择纵向扩容的节点池时,自动扩缩器会优先选择具有匹配的未使用预留的节点池,即使该节点池不是最高效的节点池也是如此。此外,在对多可用区纵向扩容进行负载均衡时,始终优先使用未使用的预留。

默认值

对于 Spot 虚拟机节点池,默认的集群自动扩缩器分布政策为 ANY。在此政策中,Spot 虚拟机被抢占的风险较低。

对于非抢占式节点池,默认的集群自动扩缩器分布政策为 BALANCED

最小和最大节点池大小

创建新的节点池时,您可以为集群中的每个节点池指定最小和最大大小,集群自动扩缩器会在这些扩缩限制范围内做出重新扩缩决策。如需更新最小大小,请在指定新的最小值后,手动将集群大小调整为新的限制范围内的大小。然后,集群自动扩缩器会根据新的限制条件做出重新扩缩决策。

当前节点池大小 集群自动扩缩器操作 扩缩限制条件
低于您指定的最小值 集群自动扩缩器会纵向扩容以预配待处理的 Pod。纵向缩容功能已停用。 节点池不会纵向缩容到低于您指定的值。
在您指定的大小下限和上限内 集群自动扩缩器可根据需求进行纵向扩容或纵向缩容。 节点池会保持在您指定的大小限制内。
大于您指定的上限 集群自动扩缩器仅纵向缩容可以安全移除的节点。纵向扩容功能已停用。 节点池不会扩容到超过您指定的值。

在 Standard 集群上,集群自动扩缩器绝不会将集群自动缩容至零个节点。集群中必须始终有一个或多个节点来运行系统 Pod。此外,如果由于手动移除节点而导致当前节点数为零,集群自动扩缩器和节点自动预配功能可以从零节点集群进行扩容。

如需详细了解自动扩缩器决策,请参阅集群自动扩缩器限制

自动扩缩限制

您可以设置在扩缩节点池时要使用的集群自动扩缩器的最小和最大节点数。使用 --min-nodes--max-nodes 标志设置每个可用区的节点数下限和上限

从 GKE 1.24 版开始,您可以对新集群使用 --total-min-nodes--total-max-nodes 标志。这些标志设置所有可用区中节点池内节点总数的下限和上限。

节点数下限和上限示例

以下命令会创建一个自动扩缩的多可用区集群,该集群最初在 3 个可用区中有 6 个节点,每个可用区至少有 1 个节点,最多有 4 个节点:

gcloud container clusters create example-cluster \
    --num-nodes=2 \
    --zone=us-central1-a \
    --node-locations=us-central1-a,us-central1-b,us-central1-f \
    --enable-autoscaling --min-nodes=1 --max-nodes=4

在此示例中,集群的总大小可以介于 3 到 12 个节点之间,这些节点分布在三个可用区。如果其中某个可用区出现故障,则集群的总大小可能介于 2 到 8 个节点之间。

节点总数示例

以下命令(在 GKE 1.24 版或更高版本中提供)会创建一个自动扩缩的多可用区集群,该集群最初在 3 个可用区中有 6 个节点,所有可用区中节点池内的节点总数不得小于 3 和大于 12:

gcloud container clusters create example-cluster \
    --num-nodes=2 \
    --zone=us-central1-a \
    --node-locations=us-central1-a,us-central1-b,us-central1-f \
    --enable-autoscaling --total-min-nodes=3 --total-max-nodes=12

在此示例中,集群的总大小介于 3 到 12 个节点之间,无论这些节点在各个可用区之间的分布如何。

自动扩缩配置文件

决定何时移除节点时,需要在提高资源利用率或可用性之间进行权衡取舍。移除使用率过低的节点可以提高集群利用率,但新的工作负载可能需要等待重新预配资源才能运行。

您可以指定在做出此类决定时使用哪种自动扩缩配置文件。 可用的配置文件包括:

  • balanced:这是默认配置文件,优先考虑为传入的 Pod 保留更多立即可用的资源,从而缩短在 Standard 集群中启用这些资源所需的时间。balanced 配置文件不适用于 Autopilot 集群。
  • optimize-utilization:优先提高利用率,而非在集群中保留空闲资源。启用此配置文件后,集群自动扩缩器会更主动地缩减集群。GKE 可以移除更多节点,并更快地移除节点。GKE 首选在已具有高 CPU、内存或 GPU 分配的节点中调度 Pod。然而,其他因素也会影响调度,例如属于同一 Deployment、StatefulSet 或 Service 的 Pod 跨节点分布。

optimize-utilization 自动扩缩配置文件可帮助集群自动扩缩器识别和移除未充分利用的节点。为了实现此优化,GKE 将 Pod 规范中的调度程序名称设置为 gke.io/optimize-utilization-scheduler。指定自定义调度程序的 Pod 不受影响。

以下命令可在现有集群中启用 optimize-utilization 自动扩缩配置文件:

gcloud container clusters update CLUSTER_NAME \
    --autoscaling-profile optimize-utilization

考虑 Pod 安排和中断

进行缩减时,集群自动扩缩器会遵循对 Pod 设置的安排和删除规则。这些限制可以防止自动扩缩器删除节点。如果节点包含满足以下任意条件的 Pod,则可以阻止删除该节点:

  • Pod 的相似性或反相似性规则阻止重新安排。
  • Pod 不受控制器(如 Deployment、StatefulSet、Job 或 ReplicaSet)管理。
  • Pod 具有本地存储空间,GKE 控制平面版本低于 1.22。在具有控制平面版本 1.22 或更高版本的 GKE 集群中,具有本地存储空间的 Pod 不再阻止缩容。
  • 该 Pod 具有 "cluster-autoscaler.kubernetes.io/safe-to-evict": "false" 注解。
  • 节点的删除将超出配置的 PodDisruptionBudget

如需详细了解集群自动扩缩器以及如何防止中断,请参阅集群自动扩缩器常见问题解答中的以下问题:

在 GKE 中自动扩缩 TPU

GKE 支持张量处理单元 (TPU) 来加速机器学习工作负载。单主机 TPU 切片节点池多主机 TPU 切片节点池都支持自动扩缩和自动预配。

通过在 GKE 集群上使用 --enable-autoprovisioning 标志,GKE 可以创建或删除具有 TPU 版本和拓扑的单主机或多主机 TPU 切片节点池,以满足待处理工作负载的要求。

使用 --enable-autoscaling 时,GKE 会根据节点池的类型扩缩节点池,如下所示:

  • 单主机 TPU 切片节点池:GKE 会在现有节点池中添加或移除 TPU 节点。节点池可以包含零到节点池最大大小(由 --max-nodes--total-max-nodes 标志确定)之间的任意数量的 TPU 节点。当节点池扩缩时,节点池中的所有 TPU 节点具有相同的机器类型和拓扑。如需详细了解如何创建单主机 TPU 切片节点池,请参阅创建节点池

  • 多主机 TPU 切片节点池:GKE 以原子方式将节点池从零扩容到满足 TPU 拓扑所需的节点数。例如,对于机器类型为 ct5lp-hightpu-4t 且拓扑为 16x16 的 TPU 节点池,节点池包含 64 个节点。GKE 自动扩缩器可确保此节点池正好包含 0 个或 64 个节点。缩容时,GKE 会逐出所有调度的 Pod,并将整个节点池排空为零。如需详细了解如何创建多主机 TPU 切片节点池,请参阅创建节点池

Spot 虚拟机和集群自动扩缩器

由于集群自动扩缩器优先扩展成本最低的节点池,因此当工作负载允许时,集群自动扩缩器会在扩容时添加抢占式 Spot 虚拟机。

不过,即使集群自动扩缩器优先添加 Spot 虚拟机,此偏好设置也不能保证您的大多数 Pod 会在这些类型的虚拟机上运行。Spot 虚拟机可能会被抢占。由于这种抢占,Spot 虚拟机上的 Pod 更有可能被逐出。被逐出后,它们只有 15 秒的时间来终止

例如,假设您有 10 个 Pod,其中混合了按需虚拟机和 Spot 虚拟机:

  • 由于 Spot 虚拟机不可用,因此您一开始在按需虚拟机上运行 10 个 Pod。
  • 您不需要全部 10 个 Pod,因此集群自动扩缩器会移除两个 Pod 并关闭额外的按需虚拟机。
  • 当您再次需要 10 个 Pod 时,集群自动扩缩器会添加 Spot 虚拟机(因为它们更便宜),并在这些虚拟机上安排两个 Pod。其他八个 Pod 仍保留在按需虚拟机上。
  • 如果集群自动扩缩器需要再次缩减,Spot 虚拟机很可能首先被抢占,您的大多数 Pod 仍在按需虚拟机上运行。

如需优先使用 Spot 虚拟机并避免上述情况,我们建议您使用自定义计算类。自定义计算类可让您创建优先级规则,通过为 Spot 虚拟机赋予高于按需节点的优先级,在扩容期间优先使用 Spot 虚拟机。如需进一步提高您的 Pod 在由 Spot 虚拟机提供支持的节点上运行的可能性,请配置主动迁移

以下示例展示了使用自定义计算类以优先使用 Spot 虚拟机的一种方法:

apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
  name: prefer-l4-spot
spec:
  priorities:
  - machineType: g2-standard-24
    spot: true
    gpu:
      type: nvidia-l4
      count: 2
  - machineType: g2-standard-24
    spot: false
    gpu:
      type: nvidia-l4
      count: 2
  nodePoolAutoCreation:
    enabled: true
  activeMigration:
    optimizeRulePriority: true

在上面的示例中,优先级规则声明了使用 g2-standard-24 机器类型和 Spot 虚拟机创建节点的偏好设置。如果没有可用的 Spot 虚拟机,GKE 会使用按需虚拟机作为后备选项。此计算类还启用了 activeMigration,使集群自动扩缩器能够在容量可用时将工作负载迁移到 Spot 虚拟机。

如果您无法使用自定义计算类,请添加节点亲和性、污点或容忍。例如,以下节点亲和性规则声明了在由 Spot 虚拟机提供支持的节点上安排 Pod 的偏好设置(GKE 会自动为这类节点添加 cloud.google.com/gke-spot=true 标签):

affinity:
  nodeAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 1
    preference:
      matchExpressions:
      - key: cloud.google.com/gke-spot
        operator: Equal
        values:
        - true

如需详细了解如何使用节点亲和性、污点和容忍来安排 Spot 虚拟机,请参阅博文在 Spot 节点上运行 GKE 应用并使用按需节点作为后备

ProvisioningRequest CRD

ProvisioningRequest 是一种使用命名空间的自定义资源,可让用户向集群自动扩缩器为一组 Pod 请求容量。对于具有相互关联的 Pod 且必须作为一个整体进行调度的应用,这一方法特别有用。

支持的预配类

有三种受支持的 ProvisioningClass:

  • queued-provisioning.gke.io:此 GKE 专用类与动态工作负载调度器集成,可让您将请求加入队列,并在资源可用时完成这些请求。这非常适合批量作业或可容忍延迟的工作负载。如需了解如何在 GKE 中使用排队预配,请参阅使用动态工作负载调度器为批量工作负载和 AI 工作负载部署 GPU。在 Standard 集群中,从 GKE 1.28.3-gke.1098000 版开始支持;在 Autopilot 集群中,从 GKE 1.30.3-gke.1451000 版开始支持。

  • check-capacity.autoscaling.x-k8s.io:此开源类会先验证资源的可用性,然后再尝试调度 Pod。从 GKE 版本 1.30.2-gke.1468000 开始支持。

  • best-effort-atomic.autoscaling.x-k8s.io:此开源类会尝试将请求中的所有 Pod 的资源一起预配。如果无法为所有 Pod 预配足够的资源,则不会预配任何资源,并且整个请求都会失败。从 GKE 1.31.27 开始支持。

如需详细了解 CheckCapacity 和 BestEffortAtomicScaleUp 类,请参阅开源文档

使用 ProvisioningRequest 时的限制

  • GKE 集群自动扩缩器仅支持每个 ProvisioningRequest 1 个 PodTemplate。
  • GKE 集群自动扩缩器一次只能扩容一个节点池。如果您的 ProvisioningRequest 需要来自多个节点池的资源,您必须为每个节点池分别创建 ProvisioningRequest。

使用 ProvisioningRequest 时的最佳实践

  • 使用 total-max-nodes:使用 --total-max-nodes 来限制应用使用的总资源,而无需限制节点数上限 (--max nodes)。
  • 使用 location-policy=ANY:此设置可让您的 Pod 在任何可用位置进行调度,从而加快预配速度并优化资源利用率。
  • (可选)与 Kueue 集成:Kueue 可以自动创建 ProvisioningRequest,从而简化工作流。如需了解详情,请参阅 Kueue 文档

其他信息

您可以在开源 Kubernetes 项目中的自动扩缩常见问题解答中详细了解集群自动扩缩器。

限制

集群自动扩缩器具有以下限制:

  • 集群自动扩缩器不支持本地 PersistentVolume
  • 在 1.24.5-gke.600 之前的 GKE 控制平面版本中,当 Pod 请求临时存储时,集群自动扩缩器不支持对使用本地 SSD 作为临时存储的节点为零的节点池进行纵向扩容。
  • 集群大小限制:最多 15,000 个节点。运行此规模的集群时,请考虑其他集群限制和我们的最佳实践
  • 进行缩减时,集群自动扩缩器会保留 10 分钟的正常终止时间段,以便将节点的 Pod 重新调度到其他节点上,然后再强制终止该节点。
  • 有时,集群自动扩缩器无法完全缩减,缩减后还会有额外节点存在。当所需的系统 Pod 被安排到其他节点上时会发生这种情况,因为没有任何触发器适用于任何这些移动到其他节点的 Pod。请参阅我有一些利用率较低的节点,但它们没有被缩减。为什么?。 要解决此限制,您可以配置 Pod 中断预算
  • 不支持使用更改的过滤条件进行的自定义调度。
  • 如果 Pod 的 PriorityClass 值低于 -10,则节点不会纵向扩容。如需了解详情,请参阅集群自动扩缩器如何使用 Pod 优先级和抢占?
  • 集群自动扩缩器可能没有足够的未分配 IP 地址空间来用于添加新节点或 Pod,从而导致纵向扩容失败(由 eventResult 事件指示,其原因为 scale.up.error.ip.space.exhausted)。您可以通过扩展主要子网为节点添加更多 IP 地址,或使用不连续的多 Pod CIDR 为 Pod 添加新的 IP 地址。如需了解详情,请参阅 Pod 没有足够的可用 IP 地址空间
  • GKE 集群自动扩缩器不同于开源 Kubernetes 项目的集群自动扩缩器。GKE 集群自动扩缩器的参数取决于集群配置,并且可能会发生变化。如果您需要对自动扩缩行为有更多的控制,请停用 GKE 集群自动扩缩器并运行开源 Kubernetes 的集群自动扩缩器。不过,开源 Kubernetes 不支持 Google Cloud 。

已知问题

  • 在 1.22 之前的 GKE 控制平面版本中,GKE 集群自动扩缩器会停止对空(零节点)集群的所有节点池进行扩容。GKE 1.22 及更高版本中不会出现此行为。

问题排查

如需获取问题排查建议,请参阅以下页面:

后续步骤