You need to enable JavaScript to run this app.
导航
Cluster Autoscaler 最佳实践
最近更新时间:2024.10.23 15:57:29首次发布时间:2024.04.01 14:56:21

CA(Cluster Autoscaler,集群弹性伸缩)根据 Pod 的调度状态以及集群内节点资源的使用情况,对集群进行自动扩缩容。从而保障 Pod 对应业务的正常运行,并控制集群资源数量以节约成本。本文介绍容器服务中 Cluster Autoscaler 常见的最佳实践操作。

组件部署

在 VKE 集群中,CA 以名为 cluster-autoscaler 的托管组件形式存在,您可以在容器服务控制台中安装和配置该组件。操作步骤如下:

  1. 在容器服务控制台中,安装和配置 cluster-autoscaler 组件。
  2. 开启节点池的弹性伸缩开关,并设置伸缩范围、优先级。
  3. 创建工作负载,设置合理的调度条件,使其能调度到已开启弹性伸缩节点池的节点上。

说明

具体的配置方式,请参见 创建节点弹性伸缩

节点池配置

节点池是提高可用性和降低成本的关键,为了实现有效的弹性伸缩,需要为集群正确配置节点池。配置节点池时的建议如下所示。

配置建议说明
节点池内节点规格统一节点池中的每个节点都应具有相同的调度属性,例如标签、污点和资源。当节点池开启弹性伸缩后,请勿再对节点池及其节点进行修改。如果同一节点池内的节点具有不同的标签和污点,那么 CA 可能在扩缩容时只考虑到某个节点上的调度属性,从而产生非预期操作。

将节点池对应于一个可用区

  • 如果 Pod 的调度逻辑与可用区相关,则应配置节点池只在单个可用区内,通过多个节点池来覆盖多可用区。
  • 如果单个节点池在多个可用区下,则 CA 会认为新扩容出来的节点只在其中某个可用区,与 Pod 的实际调度要求不符,导致扩容后 Pod 无法调度,或者无法触发扩容的情况。
为节点池配置标签节点池在扩容节点时会为节点自动添加若干标签,当节点池内无节点时,CA 无法感知此类标签,此时如果 Pending Pod 的调度策略涉及到这些标签,CA 将无法正常扩缩容。建议为节点池配置标签,并在创建工作负载时,为 Pod 添加节点池亲和性相关标签,从而让 CA 感知标签并扩容对应的节点池。
减少开启弹性伸缩的节点池数量CA 会定期对集群进行扫描(当前为 10s)并触发扩缩容操作。每次执行扫描前,会对所有开启弹性伸缩的节点池计算 Pending Pod 的调度情况。如果存在多个已开启弹性伸缩开关的节点池,会增大 CA 执行扫描和扩缩容的耗时。因此,对于不再需要自动扩缩容的节点池,可关闭弹性伸缩开关。
明确弹性伸缩节点池的优先级CA 支持在扩容过程中按照优先级选择节点池。用户可以根据实际需求,为集群下的多个弹性伸缩节点池配置优先级,满足一般场景下的集群伸缩需求。
保留节点不被 CA 缩容当希望保留某些特定节点不被 CA 缩容时,可以给节点打上以下 Annotation(注解)来阻止 CA 删除节点kubectl annotate node <nodename> cluster-autoscaler.kubernetes.io/scale-down-disabled=true

CA 配置

扩容策略

了解、选择合适的扩容策略可以更好地满足用户的扩容需求。CA 在制定策略时会估计节点池对 Pending Pod 调度要求满足程度,对于可满足调度要求的节点池,CA 会再从这些节点池中按照扩容策略选择最合适的。CA 提供了以下几种扩容策略:

  • 随机(random):CA 先对所有的节点池做筛选,排除不满足 Pending Pod 调度要求的节点池,然后再从剩余的节点池中随机选取一个。
  • 优先级(priority):对于满足 Pending Pod 调度要求的节点池,按照设置的优先级,选择优先级最高的节点池。如果有多个节点池优先级相同,则退化为随机选择。
  • 最少浪费(lease-waste):对于满足 Pending Pod 调度要求的节点池,CA 会根据 CPU 和内存的用量,对每个节点池计算一个得分,来表示扩容后整体的资源浪费情况,得分越低则浪费越少,CA 从中选择得分最低的节点池。如果多个节点池都是最低分,则退化为随机选择。
  • 最多 Pod(most-pods):对于满足 Pending Pod 调度要求的节点池,CA 会计算每个节点池扩容后可以共调度多少个 Pod,计算过程中不考虑节点池伸缩范围的限制。如果 Pending Pod 都来自相同的工作负载,则所有节点池的计算结果都是相同的,退化为随机选择。

说明

对于一般场景来说,随机策略和优先级策略可能是更好的选择。

缩容阈值

CA 支持配置 GPU 节点和非 GPU 节点的缩容阈值。计算公式为:节点资源请求量/节点资源总量

  • GPU 节点如果未开启 mGPU,那么 CA 将以 GPU 卡数作为缩容阈值的计算指标。

说明

mGPU 功能目前处于 公测 阶段,更多说明参见 mGPU 概述

  • GPU 节点如果开启 mGPU,那么 CA 将以 mGPU 核数、显存数、CPU 核数、内存数作为缩容阈值的计算指标,并取最大值和阈值进行比较。
  • CPU 节点,CA 会以 CPU 核数、内存数作为缩容阈值的计算指标,并取最大值和阈值进行比较。

由于缩容操作通常会触发 Pod 的重新调度,并且节点层面的缩容操作代价较大,因此缩容阈值的选择可以相对保守。此外,CA 也支持在 Pod 层面抑制缩容行为,将其运行节点配置为不缩容,包括:

  • 包含本地存储的 Pod。
  • kube-system命名空间下的非 DaemonSet Pod。
  • 包含cluster-autoscaler.kubernetes.io/safe-to-evict=false标签的 Pod。

更多配置

CA 其他相关配置可参考 创建节点弹性伸缩

性能和可扩展性

性能

CA 的性能主要受其可使用的资源以及扫描间隔影响,对于以托管形式存在的 CA,其会每隔 10 秒对集群进行 1 次扫描,并制定扩缩容决策。

托管 CA 所能管理伸缩组的数量通常没有额外限制,用户可以根据开启弹性伸缩的节点池的实际伸缩记录对伸缩组进行调整,避免节点池内节点数量始终处于低位或高位的情况出现。但是 CA 管理的节点池越多,那么其扫描和制定决策的时间也会相应有所增长。

可扩展性

CA 的可扩展性主要受其配置参数及节点池影响,考虑到过多的 Pending Pod 会增大 CA 每次执行的耗时,同时无法加速扩容速度,因此将 CA 单次扩容节点上限限制为 90 个节点,如果用户需要针对其业务场景提高 CA 的可扩展性,可联系相关人员进行专业支持。

  • 通过自定义镜像优化可扩展性:一个 Pod 由 Pending 变为 Running,除了节点资源准备的耗时外,还有容器镜像的拉取耗时。如果容器镜像比较大,且同时启动的 Pod 数量比较多,可能会在镜像拉取和加载两个环节产生较大的压力,导致节点已经扩容完成但业务 Pod 迟迟无法正常运行。此时可利用自定义镜像的方式,提前把容器镜像打包进 ECS 的系统镜像中,规避镜像的拉取耗时。自定义镜像可参考 如何打包和使用自定义镜像
  • 通过占位 Pod 优化可扩展性:占位 Pod 指具有低优先级的 Pod,当有 Pending Pod 被创建时,低优先级的 Pod 所对应的资源会被 Pending Pod 抢占,此时 Pending Pod 因为具备运行资源可被正常调度和创建,而低优先级的 Pod 则会重新变为 Pending 状态从而触发 CA 扩容。这种方式可以有效提升业务容器就绪的效率,但也会产生额外成本。Pod 优先级抢占可参考 如何设置 Pod 的优先级实现抢占功能

容量规划

CA 在容量方面会同时受节点池和配额限制。当节点池开启弹性伸缩时,需要为其配置节点数量的上下限,而配额则通常是在用户账户层面产生影响。

节点池节点数量的上下限由用户自行配置,用户可根据实际业务需求进行实时修改和调整。用户可用节点的数量和节点池数量等资源会受账户配额影响,提升配额可参考 如何提升配额(Quota)

可观测性

CA 是托管组件,无需用户人工运维,对于关心 CA 指标的用户,容器服务可观测性提供了 CA 观测面板,详情请参见 控制面服务观测
alt

具体面板的说明如下。

面板名称面板描述
伸缩状态集群是否正常、可以进行自动缩放。
Unschedulable Pod集群中未调度的 Pod。
最近检查扩容时间CA 历史扩容的时间。
最近检查缩容时间CA 历史缩容的时间。
缩容冷却是否在缩容冷却。
CA 循环失败CA 循环失败次数。
弹性伸缩耗时CA 伸缩阶段耗时。
CA 添加节点数CA 实际添加节点数。
CA 移除节点数CA 实际移除节点数。
CA 驱逐Pod数CA 驱逐 Pod 数量。
CA 扩容失败次数CA 扩容失败次数以及原因。

说明

CA 提供的相关监控指标与社区一致,可参考 CA 监控指标

高危操作

以下操作可能导致 CA 无法进行符合预期的扩缩容行为,请您配置时额外注意:

  • 节点池内节点调度属性不统一

节点池是具有相同调度属性的节点集合,但是用户也可以通过控制台修改节点池和节点的调度属性,此时可能出现非预期的扩缩容行为。例如:用户为同一节点池内的节点配置了不同的标签和污点,那么由于 CA 在制定扩缩容决策时会优先参考节点池已存在节点的调度属性,并且至多只会选取一个节点进行参考,从而可能导致 CA 受单个节点调度属性的影响导致无法正常扩缩容。

  • 可用区亲和性调度场景下为节点池配置了多个可用区

可用区亲和性调度场景下,如果节点池配置了多个可用区,则 CA 会认为新扩容出来的节点只在其中某个可用区,与 Pod 的实际调度要求不符,可能会出现扩容后 Pod 调度不上去,或者无法触发扩容的情况。建议用户可配置多个节点池,每个节点池对应一个可用区。

  • Pod 配置节点亲和性且亲和性关联到无节点的节点池中

节点池会为内部节点自动添加若干标签,比如通过标签标记某个节点属于某个节点池。如果节点池自身未配置该标签且节点池无节点,那么 CA 将无法感知到这类标签的存在,从而导致 CA 在制定扩容策略时忽视了 Pod 对节点池等亲和性的满足,从而无法扩容节点。

  • 配置了过多的 DaemonSet Pod 及静态 Pod

CA 在扩容时会考虑 DaemonSet Pod 及静态 Pod,如果节点池的待扩容节点模版扣除 DaemonSet Pod 及静态 Pod 所需资源后,剩余的资源无法满足调度 Pending Pod 所需资源,那么 CA 将不会触发扩容。

说明

容器服务中的更多高危操作,请参见 高危操作及恢复方案

与 VCI 的对比

CA 根据工作负载的需求自动调整 Kubernetes 集群的大小,其主要优点在于可以根据实际需求动态调整集群大小,避免资源浪费,但是 CA 扩缩容节点的过程可能需要较长的时间。因此,CA 更适合长期运行且需要根据工作负载变化动态调整的应用,而对于短期、大量、突发性工作负载的支持则存在限制。

因此,您也可以使用火山引擎弹性容器实例(Volcengine Container Instance,简称 VCI)来构建快速伸缩、按实际使用付费的集群。VCI 是一种 Serverless 和容器化的计算服务,支持秒级启动、高并发创建、沙箱容器安全隔离等能力,使得用户可以专注于构建应用本身,而无需购买和管理底层云服务器等基础设施。详情请参见 什么是弹性容器实例