节点伸缩概述

当集群的容量规划无法满足应用Pod调度时,您可以使用ACK提供的节点伸缩功能,自动扩缩节点资源以进行调度容量的补充。ACK目前提供节点自动伸缩节点即时弹性两种弹性方案,后者相较于前者有着更快的弹性速度、更高的交付效率和更低的使用门槛。

阅读前提示

为了让您更好地了解ACK提供的节点伸缩方案,并结合您的业务诉求进行方案选型,建议您在启用节点伸缩能力前阅读本篇概述。

阅读本文前,推荐您参见Kubernetes官方文档了解手动伸缩、自动伸缩、水平伸缩、垂直伸缩等伸缩概念。

工作原理

在Kubernetes中,节点伸缩的工作原理与传统意义上基于使用率阈值的模型有所差别。这也是从传统IDC或其他编排系统迁移到Kubernetes集群后往往需要解决的问题。

传统的弹性伸缩模型基于使用率实现。例如,一个集群中有3个节点,当集群中的节点CPU、内存使用率超过特定的阈值时,系统将扩容新的节点。但这种模式存在以下问题。

阈值是如何选择与判断的?

在一个集群中,部分热点节点的利用率可能较高,而其他节点的利用率可能较低。

  • 如果根据整个集群的平均资源利用率来决定是否弹性伸缩,使得热点节点的差异被平均,那么会造成对热点节点的扩缩不够及时。

  • 如果依据最高的节点利用率来决定是否弹性伸缩,那么会造成弹出资源的浪费,影响集群的整体服务。

弹出实例后如何缓解压力?

在Kubernetes集群中,应用以Pod为最小单元部署在集群的不同节点上。当一个Pod资源利用率较高时,即使该Pod所在的节点或者集群触发了弹性扩容,但该应用的Pod数量以及Pod对应的Limit并没有发生变化,节点负载的压力也无法转移到新扩容的节点上。

如何判断以及执行实例的缩容?

如果基于资源利用率的方式判断节点是否缩容,那么很有可能出现Request(资源请求)较大、但Usage(实际资源使用)很小的Pod被驱逐。当集群中这种类型的Pod较多时,会占用集群大量的调度资源,导致部分Pod无法调度。

基于以上问题,ACK通过节点伸缩(资源层)和工作负载伸缩(调度层)两层弹性模型来解决。节点伸缩基于资源的使用率来触发应用副本的变化,也就是调度单元的变化。以下介绍技术细节。

如何判断节点的弹出?

节点伸缩会监听Pod是否处于调度失败的状态,以判断是否需要触发扩容。当Pod由于调度资源不足而调度失败时,节点伸缩会开始模拟调度,计算在开启弹性的节点池中哪个节点池可为这些Pod提供所需的节点资源,并在满足需求时弹出相应的节点。

说明

模拟调度时将一个开启弹性的节点池作为一个的抽象节点,开启弹性的节点池中配置的机型规格对应会成为抽象节点的CPU、内存或GPU的容量,且其配置的Label、Taint也会成为抽象节点的Label与Taint。模拟调度器会在调度模拟时,将该抽象节点纳入调度参考范围。符合调度条件时,调度模拟器会计算所需的节点数目,驱动节点池弹出节点。

如何判断节点的缩容?

节点伸缩仅缩容开启了弹性的节点池中的节点,无法管理静态节点(不在开启了弹性的节点池中的其他节点)。每个节点会单独判断是否进行缩容。当任意一个节点的调度利用率低于所设置的调度阈值时,就会触发缩容判断。此时,节点伸缩会尝试模拟驱逐节点上的负载,判断当前节点是否可以排水。部分特殊的Pod(例如kube-system命名空间的非DaemonSet Pod、PDB控制的Pod等)则会跳过该节点而选择其他的候选节点。当节点发生驱逐时,会先进行排水,将节点上的Pod驱逐到其他的节点,然后再下线该节点。

多个开启弹性的节点池之间如何选择?

不同开启弹性的节点池之间,实际上相当于不同的抽象节点之间的选择。和调度策略一样,开启弹性的节点池之间也存在打分机制。弹性组件首先筛选符合调度策略的节点,然后进一步根据affinity等亲和性策略进行选择。

如果基于上述策略无法选择合适的节点,默认情况下节点自动伸缩会通过least-waste的策略进行选择。least-waste策略的核心是模拟弹出节点后,找到剩余资源最少的节点。

说明

当有一个开启弹性的GPU节点池和开启弹性的CPU节点池同时可以弹出生效时,默认CPU会优先于GPU弹出。

而默认情况下,节点即时弹性会通过比较库存和成本进行选择,以在多个可行的扩容方案中选择库存保障较高且成本较低的方案。

如何提高弹性伸缩的成功率?

弹性伸缩的成功率主要取决于以下两个因素:

  • 调度策略是否满足

    配置开启弹性的节点池后,您需要先确认该节点池可以承载的Pod的调度策略范围。如果无法直接判断,您可以通过nodeSelector直接选择节点池的Label,来进行预弹模拟。

  • 资源配置是否充分

    当模拟调度通过后,系统会选择开启弹性的节点池,以弹出实例。但开启弹性的节点池中配置的ECS规格库存会直接影响是否可以成功弹出实例。因此,推荐您配置多个可用区、多个不同机型组合,以提高弹出成功率。

如何提高弹性伸缩的速度?

  • 方法一:使用极速模式加速弹出速度。当开启弹性的节点池预热后(已完成一次扩容和一次缩容),节点池即可进入极速伸缩模式。更多信息,请参见启用节点自动伸缩

  • 方法二:使用自定义镜像的方式,以Alibaba Cloud Linux 3作为基础镜像,大大提升IaaS层的资源交付速度(50%)。更多信息,请参见弹性优化之自定义镜像

弹性方案:节点自动伸缩节点即时弹性

节点伸缩指资源层弹性,即当集群的容量规划无法满足应用Pod调度时,自动扩缩节点资源,以进行调度容量的补充。ACK在节点伸缩层面提供两种弹性方案。

方案介绍

重要

本文中提供的弹性测量数据为理论值,均基于弹性优化的自定义镜像实现,实际数据以您的实际业务环境为准。关于自定义镜像的更多信息,请参见弹性优化之自定义镜像

方案

实现组件

说明

方案一:节点自动伸缩

cluster-autoscaler组件

以轮询的方式,周期性地维护和检查集群状态,以发现满足扩缩容条件的情况,从而自动扩缩容集群节点。

方案二:节点即时弹性

节点即时弹性组件

一个基于事件驱动的节点伸缩控制器。在大规模集群(例如弹性节点池中节点数大于100,或弹性节点池数大于20)和连续多次弹性扩容等场景下,能够保证更好的弹性资源交付。伸缩速度(即从Pod首次调度失败到Pod调度成功的耗时)稳定在45s、成功率可达99%、资源碎片度降低约30%。同时,在扩缩容自定义策略上有更好的扩展性。

方案对比

如果您的集群节点池已开启自动弹性伸缩且节点池的伸缩模式非极速模式节点即时弹性可兼容原弹性节点池的语义与行为,并支持所有类型的应用无感开启与使用。所以,本小节重点阐述节点即时弹性相较于节点自动伸缩的优化特性。

优化特性

节点自动伸缩

节点即时弹性

伸缩速度与效率

单次伸缩时,标准模式的伸缩速度约为60s,极速模式为50s。

通过事件驱动的机制来触发扩缩行为,结合阿里云的ContainerOS能力进行弹性加速,伸缩速度大约为45±10s。

当达到1分钟的伸缩量级时,伸缩速度会遇到瓶颈,并且在不同规模(多节点池)、不同场景(连续伸缩)下,弹性速度也会有比较明显的抖动。例如,当节点池数量超过100时,伸缩速度将衰减为100~150s。

不会随着节点池的规模与Pod的规模的增大而产生明显的衰减,更适用于对弹性交付速度高的场景。

使用轮询式模型,且受制于对集群状态维护的依赖,弹性灵敏度最低为5s。

基于事件驱动,使用响应式模型,弹性灵敏度为1~3s。

资源交付确定性

云上资源的库存变化较为频繁。由于实例规格组合问题、库存不足等原因,节点自动伸缩的弹性成功率在97%左右。

支持库存自动选择策略,可根据您配置的筛选条件与顺序,从阿里云上千个实例规格组合中过滤无库存的实例规格,并选择最为合适的规格进行扩容,或在库存不足时补偿符合条件的规格。这大大降低了运维人员选择规格的压力,同时提升了交付的成功率,可达99%。

支持按照节点池配置的规格扩容相同类型的规格。在类型不同时,会选择最小的规格进行扩容。

支持扩容不同类型的规格。

资源交付失败时,会进行周期性重试,手段较为滞后。

资源交付失败时,支持库存预警能力,提前通知规格组合的潜在风险。

使用及运维门槛

相较于节点自动伸缩节点即时弹性的使用门槛更低。主要体现在以下方面。

  • 节点池配置维护:节点即时弹性能够根据实例属性在多规格和多可用区中自动选择实例,容纳等待调度的Pod。但在节点自动伸缩模式下,您需要自行维护节点池各项配置,以保证Pod的正常调度。因此,当Pods配置发生变更时,往往意味着对应节点池配置也需要更新。

  • 节点运维:对于开发者来说,在扩缩容过程中,相关异常都可以通过Pod事件同步,他们只需管理Pod的生命周期。

  • 功能拓展:支持扩展机制,例如结合Descheduler准备弹性资源。节点即时弹性支持无侵入式地将资源供给策略、节点生命周期管理与您的自定义行为进行联动,提供更多二次开发的可能性。

调度策略

除支持节点自动伸缩所有的调度特性之外,节点即时弹性还支持以下特性:

  • Topology:常用于满足跨可用区维度的高可用需求。

  • Pod Disruption Budgets:可限制在同一时间因自愿干扰导致的多副本应用中发生宕机的Pod数量。

节点即时弹性支持根据Pod选择最优装箱策略(Bin Packing)预绑定(PreBind)策略(自定义特性),可将调度碎片率优化30%。

节点即时弹性的使用限制

在评估节点即时弹性方案时,您需要同时了解节点即时弹性的使用限制。

方案选型建议

参见前文的方案对比节点即时弹性的使用限制,如果您的业务对弹性速度、资源交付确定性和使用及运维成本要求相对较低,且无法容忍节点即时弹性的使用限制时,节点自动伸缩可能能够满足您的业务需求。但如果您有以下业务诉求,我们更推荐您使用节点即时弹性。

  • 集群规模较大,例如弹性节点池中节点数大于100,或弹性节点池数大于20集群规模变大时,节点自动伸缩的扩容效率会明显衰减,而节点即时弹性的性能波动较小。

  • 对资源交付速度,即弹性速度,有更高要求。单次伸缩场景下,标准模式下的节点自动伸缩的弹性速度为60s左右,而节点即时弹性为45s左右。

  • 业务负载批次不可控,对同一个弹性节点池通常有连续扩容的需求。连续伸缩模式下,节点自动伸缩的性能会衰减且抖动较为明显,而节点即时弹性仍然能实现45s左右的伸缩速度。

注意事项

配额与限制

  • 在专有网络下创建的单个路由表可创建的自定义路由数限额是200条。如需更大的配额,请前往配额中心提交申请。关于其他资源的配额限制及升配详情,请参见依赖底层云产品配额限制

  • 请合理配置开启自动伸缩的节点池的最大实例数,保证此范围内的节点所依赖的资源和配额充足,例如合理规划VPC网段、交换机等网络资源,以避免节点扩容失败。配置开启自动伸缩的节点池的最大实例数,请参见配置实例数量。关于ACK的网络规划,请参见Kubernetes集群网络规划

  • 节点伸缩功能不支持包年包月付费类型的节点。如需新建开启自动伸缩的节点池,请勿选择付费类型为包年包月。如需为已有节点池开启自动伸缩,请确保节点池内没有包年包月付费类型的节点。

依赖资源的维护

选择绑定EIP时,请勿通过ECS控制台直接删除节点伸缩扩容出的ECS节点,否则会导致EIP无法自动释放。

后续阅读