Azure Kubernetes 服务中的群集自动缩放概述

若要满足 Azure Kubernetes 服务 (AKS) 中的应用程序需求,可能需要调整运行工作负载的节点数。 集群自动扩缩容组件会监视集群中因资源限制而无法调度的 Pod。 当集群自动扩缩器检测到未调度的 Pod 时,它会增加节点池中的节点数量,以满足应用程序需求。 它还会检查未充分利用的节点,并在可以安全重新计划工作负荷时缩减符合条件的节点。

本文介绍群集自动缩放程序在 AKS 中的工作原理。 此外,还提供了为 AKS 工作负载配置群集自动缩放程序时的指导、最佳做法和注意事项。 若要为 AKS 工作负载启用、禁用或更新群集自动缩放程序,请参阅在 AKS 中使用群集自动缩放程序

关于集群自动扩缩器

群集通常需要一种自动缩放方式以适应不断变化的应用程序需求(例如,工作日与夜间或周末之间)。 可以通过以下方式缩放 AKS 群集:

  • 集群自动扩缩器会定期检查由于资源限制而无法调度到节点上的 Pod。 群集随后会自动增加节点数。 使用群集自动缩放程序时,会禁用手动缩放。 有关详细信息,请参阅 纵向扩展的工作原理?
  • 水平 Pod 自动缩放程序会在 Kubernetes 群集中使用指标服务器来监视 Pod 的资源需求。 如果应用程序需要更多资源,则会自动增加 Pod 数以满足需求。
  • 垂直 Pod 自动缩放程序可根据过去的使用情况自动设置每个工作负载的资源请求和容器限制,以确保将 Pod 计划到具有所需 CPU 和内存资源的节点上。

显示群集自动缩放程序和水平 Pod 自动缩放程序通常如何协同工作以支持所需的应用程序需求的屏幕截图。

常见做法是为节点启用群集自动缩放程序,并为 Pod 启用垂直 Pod 自动缩放程序或水平 Pod 自动缩放程序。 启用群集自动缩放程序后,当节点池大小低于最小节点计数时(上限为最大节点计数),它会应用指定的缩放规则。 群集自动缩放程序会等待生效,直到节点池中需要新节点或可从当前节点池中安全删除某个节点为止。 有关详细信息,请参阅纵向缩减的工作原理

最佳做法和注意事项

  • 使用群集自动缩放程序实现可用性区域时,请为每个区域使用单个节点池。 将 --balance-similar-node-groups 参数设置为 True,以便在扩容期间使您的工作负载的节点在各可用区之间保持均衡分布。 如果不使用此方法,缩减操作可能会中断跨区域节点的平衡。 对于多区域节点池,还可以使用 自动区域放置(--zones auto让 AKS 动态选取区域,从而将节点置于具有容量的区域,同时应用每个区域的最大实例百分比为 50%。 创建节点池或更新现有节点池时,可以使用自动区域放置。

    注释

    群集自动缩放器不感知可用区,而底层的虚拟机规模集负责可用区分配。 在单个多可用区节点池上使用基于可用区的 Pod 拓扑分布约束 时,上述最佳做法显得更为重要,因为过于严格的约束可能会导致 Pod 处于 Pending 状态,尤其是在容量受限的区域中或可用区发生故障时。

  • 对于节点数超过 400 的群集,请使用 Azure CNI 或 Azure CNI 覆盖层。

  • 若要 在现成和按需节点池上同时运行工作负荷,请考虑使用 优先级扩展器。 优先级扩展器使用 ConfigMap 中的 cluster-autoscaler-priority-expander 优先级和节点池名称模式在纵向扩展期间选择节点池。 以下配置说明了此设置。

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: cluster-autoscaler-priority-expander
      namespace: kube-system
    data:
      priorities: |-
        10:
          - .*spotpool1.*
          - .*spotpool2.*
        50:
          - .*ondemandpool1.*
    
  • 在 Pod 上分配 CPU 和内存请求时,请谨慎行事。 集群自动扩缩容器是根据处于 Pending 状态的 Pod 进行扩容,而不是根据节点上的 CPU 或内存压力。

  • 对于 同时托管长时间运行的工作负荷(例如 Web 应用)和短作业工作负荷或突发作业工作负荷的群集,请使用 地缘规则扩展器将它们分成不同的节点池。

  • 使用 PodDisruptionBudget 来帮助防止不必要的节点耗尽或缩减操作。 在 Pod 规范中指定注解 cluster-autoscaler.kubernetes.io/safe-to-evict: "false" 也会防止 Pod 被驱逐。 请谨慎使用此批注,因为它可能会导致群集自动缩放程序在耗尽包含此批注的正在运行的 Pod 的节点时遇到问题。

  • 在启用了自动缩放程序的节点池中,请勿手动更改当前节点计数。 若要更改允许的缩放范围,请在评估工作负荷和容量要求后 更新群集自动缩放程序最小和最大节点计数

  • 如果 Pod 的 PriorityClass 值低于 -10,则节点不会纵向扩展。 优先级 -10 保留给超量预配 Pod。 有关详细信息,请参阅将群集自动缩放程序与 Pod 优先级和抢占结合使用

  • 请勿将其他节点自动缩放机制(例如虚拟机规模集自动缩放程序)与群集自动缩放程序结合使用

  • 如果 Pod 无法移动,群集自动缩放程序可能无法缩减规模,例如在以下情况下:

    • 直接创建且没有控制器对象(如 Deployment 或 ReplicaSet)作为后盾的 Pod。
    • Pod 中断预算 (PDB) 过于严格,不允许 Pod 数量降至某个阈值以下。
    • Pod 使用了节点选择器或反亲和性规则,如果调度到其他节点则无法满足这些规则。 有关详细信息,请参阅哪些类型的 Pod 可防止群集自动缩放程序移除节点?

重要

不要对自动缩放节点池中的单个节点进行更改。 同一节点组中的所有节点都应具有一致的容量、标签、污点以及其上运行的系统 Pod。

  • 集群自动扩缩器并不负责在不考虑 Pod 调度因素的情况下,对集群节点池强制执行“最大节点数”限制。 如果任何非群集自动缩放程序执行组件将节点池计数设置为超出群集自动缩放程序配置的最大值的数字,则群集自动缩放程序不会自动移除节点。 群集自动缩放的缩减行为仍限于删除未充分利用的节点。 群集自动缩放程序的最大节点计数配置的唯一用途是强制实施纵向扩展操作的上限。 它不会对缩容方面的考量产生任何影响。

集群自动缩放程序配置文件

群集自动缩放程序配置文件是一组控制群集自动缩放程序行为的参数。 可以在创建群集或更新现有群集时配置群集自动缩放器配置文件。

优化集群自动扩缩容器配置文件

应根据特定的工作负载场景微调群集自动缩放程序配置文件设置,同时还要考虑性能和成本之间的权衡。 本部分提供了演示这些权衡的示例。

请务必注意,群集自动缩放程序配置文件设置是群集范围的,并应用于所有启用自动缩放的节点池。 在一个节点池中执行的任何缩放操作都可能会影响其他节点池的自动缩放行为,这可能会导致意外结果。 务必在所有相关节点池中应用一致且同步的配置文件配置,以确保获得所需的结果。

示例 1:优化性能

对于主要关注性能且处理大量突发工作负载的集群,请使用较短的 scan-interval,以便集群自动扩缩器能够频繁重新评估集群。 增加此间隔可减少重新评估频率和相关 API 活动,但会增加群集自动缩放程序响应之前的时间。 减少 scale-down-utilization-threshold 以降低利用率不足节点被缩减的可能性。 此外,增加 ok-total-unready-countmax-total-unready-percentage

对于具有 DaemonSet pod 的集群,将 ignore-daemonsets-utilization 设置为 true,这样在集群自动扩缩器计算用于缩容的节点利用率时,就不会将 DaemonSet pod 的资源请求计入其中。 此设置可能使节点更容易降到低于 scale-down-utilization-threshold 的水平,并满足缩容条件。 请参阅 为突发性工作负载配置集群自动缩放器配置文件

示例 2:优化成本

如果您想使用成本优化配置,我们建议您将以下参数设置为:

  • 减少 scale-down-unneeded-time,即节点在被视为不再需要后,符合缩容条件之前所需的时间。
  • 减少 scale-down-delay-after-add,即添加节点后在考虑纵向缩减节点之前等待的时间。
  • 增加 scale-down-utilization-threshold,即删除节点的利用率阈值。
  • 增加 max-empty-bulk-delete,即可以在单个调用中删除的最大节点数。
  • skip-nodes-with-local-storage设置为 false。
  • 增加 ok-total-unready-countmax-total-unready-percentage

常见问题和缓解建议

通过CLI 或门户网站查看缩放失败和未触发扩容的事件。

未触发扩容操作

常见原因 缓解建议
PersistentVolume 节点亲和性冲突,可能会在将集群自动扩缩器与多个可用区配合使用时出现,或者在 Pod 或持久卷所在的可用区与节点所在的可用区不一致时出现。 为每个可用性区域使用一个节点池并启用 --balance-similar-node-groups。 还可以在 Pod 规范中将 volumeBindingMode 字段设置为 WaitForFirstConsumer,以防止卷在创建使用该卷的 Pod 之前绑定到节点上。
污点和容忍/节点亲和性冲突 检查分配给节点的污点,并查看在 Pod 中定义的容忍度。 如有必要,请调整污点和容忍,以确保 Pod 能够高效地调度到节点上。
限制性 Pod 拓扑分布约束 群集自动缩放程序在启动扩容作业之前运行调度模拟。 如果它确定由于限制性的拓扑分布约束而无法在新节点上调度 Pod,则不会尝试扩展规模。 若要缓解此问题,请考虑放宽拓扑分布约束。

扩容操作失败

常见原因 缓解建议
子网中的 IP 地址耗尽 在同一虚拟网络中添加另一个子网,并将另一个节点池添加到新子网中。
核心配额耗尽 批准的核心配额已耗尽。 当群集自动缩放程序经历多次失败的纵向扩展尝试时,会在特定节点组内进入指数退避状态
节点池的最大大小 增加节点池中的最大节点数或创建新的节点池。
请求/调用超出速率限制 请参阅“429 请求过多”错误

缩减操作失败

常见原因 缓解建议
Pod 阻止节点耗尽/无法逐出 Pod • 查看哪些类型的 Pod 会阻止缩容
• 对于使用本地存储的 Pod(如 hostPath 和 emptyDir),请将集群自动扩缩容器的配置标志 skip-nodes-with-local-storage 设置为 false
• 在 Pod 规范中,将 cluster-autoscaler.kubernetes.io/safe-to-evict 注释设置为 true
• 检查您的 PDB,因为它可能受到限制。
节点池的最小大小 减小节点池的最小大小。
请求/调用超出速率限制 请参阅“429 请求过多”错误
写入操作被锁定 请勿对完全托管的 AKS 资源组进行任何更改(请参阅 AKS 支持策略)。 删除或重置之前应用于资源组的任何资源锁

其他问题

常见原因 缓解建议
优先级配置映射不匹配组 确保每个需要自动扩缩容的节点组都与 priorities ConfigMap 的 cluster-autoscaler-priority-expander 数据中至少一个节点池名称模式匹配。 有关常规扩展器行为,请参阅 什么是扩展器?

节点池处于退避状态

版本 0.6.2 引入了处于退避状态的节点池,这会导致集群自动扩缩器在发生故障后暂缓对该节点池进行扩缩。

根据缩放操作遇到故障的时间,自动缩放程序可能等待长达 30 分钟,然后再进行另一次尝试。 可以通过禁用然后再重新启用自动缩放来重置节点池的回退状态。