全部产品
Search
文档中心

容器服务 ACK:节点自动伸缩

更新时间:May 29, 2023

ACK的自动伸缩能力是通过节点自动伸缩组件实现的,可以按需弹出普通实例、GPU实例、竞价付费实例,支持多可用区、多实例规格、多种伸缩模式,满足不同的节点伸缩场景。

工作原理

在Kubernetes中,节点自动伸缩的工作原理与传统意义上基于使用率阈值的模型有所差别,这也是很多开发者在从传统的IDC或者其他编排系统迁移到Kubernetes后最难理解的地方。例如,将Swarm集群迁移至ACK集群。

传统的弹性伸缩模型是基于使用率的,例如:一个集群中有3个节点,当集群中的节点CPU、内存使用率超过特定的阈值时,此时弹出新的节点。但当深入思考时会发现以下几个问题:

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

在一个集群中,部分热点节点的利用率会较高,而另外一个节点的利用率会很低。如果选择平均利用率的话可能会造成弹性伸缩的不及时。如果使用最低的节点的利用率,那么也会造成弹出资源的浪费。

2.弹出实例后是如何缓解压力的?

在Kubernetes中,应用是以Pod为最小单元,部署在集群的不同节点上的。当一个Pod资源利用率较高的时候,即便此时所在的节点或者集群的总量触发了弹性扩容,但是该应用的Pod数目,以及Pod对应的Limit没有任何变换,那么负载的压力是无法转移到新扩容出的节点上的。

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

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

Kubernetes节点伸缩是怎么解决以上问题的呢?Kubernetes是通过调度与资源解耦的两层弹性模型来解决的。

基于资源的使用率来触发应用副本的变化,也就是调度单元的变化。而当集群的调度水位达到100%的时候会触发资源层的弹性扩容,当资源弹出后,无法调度的单元会自动调度到新弹出的节点上,从而降低整个应用的负载状况。以下介绍Kubernetes弹性伸缩的技术细节:

1.如何判断节点的弹出?

cluster-autoscaler是通过对处在Pending的Pod进行监听而触发的。当Pod处在Pending的原因是调度资源不足的时候,会触发cluster-autoscaler的模拟调度,模拟调度器会计算在配置的伸缩组中哪个伸缩组弹出节点后可以调度这些Pending的Pod。如果有伸缩组可以满足,那么就弹出相应的节点。

模拟调度就是将一个伸缩组当成一个抽象的Node,伸缩组中配置的机型规格对应会成为Node的CPU/内存/GPU的容量,然后设置伸缩组上面的Label、Taint,也就是Node的Label与Taint。模拟调度器会在调度模拟的时候,将该抽象的Node纳入调度参考。如果Pending的Pod可以调度到抽象的Node,那么就会计算所需的Node的数目,驱动伸缩组弹出节点。

2.如何判断节点的缩容?

首先只有弹性伸缩弹出的节点会被缩容,静态的节点是无法被cluster-autoscaler接管的。缩容的判断是通过每个节点单独判断的。当任意一个节点的调度利用率低于所设置的调度阈值时,会触发节点的缩容判断。此时cluster-autoscaler会尝试模拟驱逐节点上面的负载,判断当前节点是否可以排水彻底。有些特殊的Pod(kube-system命名空间的非DaemonSet Pod、PDB控制的Pod等),则会跳过该节点而选择其他的候选节点。当节点发生驱逐时,会先进行排水,将节点上的Pod驱逐到其他的节点,然后再下线该节点。

3.多个分组之间如何选择?

不同分组之间,实际上相当于不同的虚拟的Node之间的选择,和调度策略一样,这里也存在一个打分的机制。首先符合调度策略的Node会先过滤出来,在符合调度策略的Node中,会根据affinity等亲和性的策略进行选择。如果上述的策略都不存在,默认情况下cluster-autoscaler会通过least-waste的策略来进行抉择。least-waste的策略的核心就是模拟弹出节点后,剩余的资源最少。此外,有一个特别的场景,当有一个GPU的伸缩组和CPU的伸缩组同时可以弹出生效时,默认CPU会优先于GPU弹出。

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

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

  • 调度策略是否满足

    首先在配置好伸缩组后,开发者需要先确认下该伸缩组可以承载的Pod的调度策略范围。如果无法直接判断,最简单的方式是通过nodeSelector直接选择伸缩组的Label进行预弹模拟。

  • 资源配置是否充分

    当模拟调度通过后,会选择伸缩组进行弹出,但是伸缩组中配置的ECS规格是否有库存会直接决定是否可以成功弹出实例。因此配置多个可用区、多个不同机型组合可以大大提高弹出成功率。

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

  • 方法一:可以通过极速模式加速弹出速度,当伸缩组预热后(已完成一次扩容和缩容),伸缩组即可进入极速伸缩模式。

  • 方法二:使用自定义镜像的方式,通过Alibaba Cloud Linux 2(原Aliyun Linux 2)作为基础镜像,可以大大提升IaaS层的资源交付速度(50%)。

注意事项

  • 默认单个用户每个区域按量付费实例的配额是50 vCPU,在专有网络下创建的单个路由表可创建的自定义路由数限额是200条。如需更大的配额,请向对应产品方提交工单申请。

  • 单一规格的ECS库存容量波动较大,建议在伸缩组中配置多种同规格的实例类型,提高节点伸缩成功率。

  • 极速弹出模式在节点进入停机回收状态时,节点将进行停机,并处在NotReady状态,当再次伸缩弹出时,节点状态会变为Ready

  • 极速弹出模式的节点处在停机回收状态时,只收取磁盘的费用,不收取计算费用(不包含拥有本地盘的机型系列,例如,ecs.d1ne.2xlarge),在库存充裕的前提下可以极速启动。

  • 选择绑定EIP时,通过ECS控制台直接删除自动伸缩组扩容出的ECS节点会导致弹性公网EIP(Elastic IP Address)无法自动释放。

  • 由于节点标签和污点配置映射到伸缩组Tag后自动伸缩才可识别,并且伸缩组Tag有数目上限限制,开启自动伸缩的节点池配置的ECS标签、污点和节点标签的总数需要控制在12个之内。

步骤一:执行自动伸缩

  1. 登录容器服务管理控制台,在左侧导航栏选择集群
  2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,选择节点管理 > 节点池
  3. 节点池页面,单击集群自动弹性伸缩后面的去配置,即可开始自动伸缩相关的授权和配置。

步骤二:授权

授权的具体角色会根据集群不同而不同,请按照界面提示操作。自动弹性伸缩的授权操作分以下三种场景:

场景一:授权RAM角色AliyunCSManagedAutoScalerRole

对于节点权限被收敛的集群,您需要授权RAM角色AliyunCSManagedAutoScalerRole

说明

此授权每个阿里云账号只需要进行一次。

  1. 开通ESS服务。

    说明

    以下开通ESS服务的操作仅供参考,实际请按照界面提示操作。

    1. 单击提示对话框中的第一个链接,进入弹性伸缩服务ESS页面。

    2. 单击开通ESS服务,进入云产品开通页

    3. 选中我已阅读并同意复选框,单击立即开通

    4. 开通成功后,在开通完成页签,单击管理控制台,进入弹性伸缩服务ESS页面。

    5. 单击前往授权,进入云资源访问授权页面,配置对云资源的访问权限。

    6. 单击同意授权

  2. 授权角色。

    1. 单击弹出对话框中的第二个链接。

      说明

      此处需要以阿里云账号登录控制台。

    2. 云资源访问授权页面,单击同意授权

场景二:授权集群WorkerRole

  1. 开通ESS服务。

    说明

    以下开通ESS服务的操作仅供参考,实际请按照界面提示操作。

    1. 单击弹出对话框中的第一个链接,进入弹性伸缩服务ESS页面。autoess

    2. 单击开通ESS服务,进入云产品开通页

    3. 选中我已阅读并同意复选框,单击立即开通

    4. 开通成功后,在开通完成页签,单击管理控制台,进入弹性伸缩服务ESS页面。

    5. 单击前往授权,进入云资源访问授权页面,配置对云资源的访问权限。

    6. 单击同意授权

    页面自动跳转至弹性伸缩控制台,说明授权成功。关闭页面,继续配置授权角色

  2. 授权角色。

    1. 单击弹出对话框中的第二个链接,进入RAM角色管理详情页面。aliyunrole

      说明

      此处需要以阿里云账号登录控制台。

    2. 权限管理页签,单击目标授权策略名称,进入授权策略详情页面。permission

    3. 单击修改策略内容,从右侧滑出侧边栏修改策略内容面板。

      policycontent
    4. 策略内容Action字段中补充以下策略,然后单击确定

      说明

      在策略内容的任意一个Action字段的最后一行补充英文半角逗号()。

      "ess:Describe*", 
      "ess:CreateScalingRule", 
      "ess:ModifyScalingGroup", 
      "ess:RemoveInstances", 
      "ess:ExecuteScalingRule", 
      "ess:ModifyScalingRule", 
      "ess:DeleteScalingRule", 
      "ecs:DescribeInstanceTypes",
      "ecs:DescribeImages",
      "ess:DetachInstances",
      "ess:ScaleWithAdjustment",
      "vpc:DescribeVSwitches"

场景三:为节点池绑定EIP

如果节点池需要绑定EIP,授权步骤如下。

  1. 开通ESS服务。

    说明

    以下开通ESS服务的操作仅供参考,实际请按照界面提示操作。

    1. 单击弹出对话框中的第一个链接,进入弹性伸缩服务ESS页面。autoess

    2. 单击开通ESS服务,进入云产品开通页

    3. 选中我已阅读并同意复选框,单击立即开通

    4. 开通成功后,在开通完成页签,单击管理控制台,进入弹性伸缩服务ESS页面。

    5. 单击前往授权,进入云资源访问授权页面,配置对云资源的访问权限。

    6. 单击同意授权

    页面自动跳转至弹性伸缩控制台,说明授权成功。关闭页面,继续配置授权角色

  2. 授权角色。

    1. 单击弹出对话框中的第二个链接,进入RAM角色管理详情页面。aliyunrole

      说明

      此处需要以阿里云账号登录控制台。

    2. 权限管理页签,单击目标授权策略名称,进入授权策略详情页面。permission

    3. 单击修改策略内容,从右侧滑出侧边栏修改策略内容面板。

      policy
    4. 策略内容Action字段中补充以下策略,然后单击确定

      "ecs:AllocateEipAddress",
      "ecs:AssociateEipAddress",
      "ecs:DescribeInstances",
      "ecs:DescribeEipAddresses",
      "ecs:DescribeInvocationResults",
      "ecs:DescribeInvocations",
      "ecs:ReleaseEipAddress",
      "ecs:RunCommand",
      "ecs:UnassociateEipAddress",
      "ess:CompleteLifecycleAction",
      "vpc:AllocateEipAddress",
      "vpc:AssociateEipAddress",
      "vpc:DescribeEipAddresses",
      "vpc:ReleaseEipAddress",
      "vpc:UnassociateEipAddress",
      "vpc:TagResources"
      说明

      在策略内容的任意一个Action字段的最后一行补充英文逗号()。

    5. RAM角色管理详情页,单击信任策略管理页签,在修改信任策略中添加oos.aliyuncs.com,然后单击确定

      oos

步骤三:配置自动伸缩

  1. 集群自动弹性伸缩配置页面,填写以下信息,并单击提交

    配置

    说明

    备注

    允许缩容

    是否允许进行节点缩容。若设置为不允许缩容,缩容相关配置将不生效,请谨慎设置。

    -

    缩容阈值

    cluster-autoscaler管理的伸缩组中,单个节点的资源申请值(Request)/单个节点的资源容量。当低于配置的阈值时,节点才可能被缩容。

    说明

    弹性伸缩中,扩容会基于调度自动触发,只需设置缩容条件即可。

    • 对于非GPU类型的节点,以下条件是缩容的必要条件,满足以下条件,节点才可能被缩容,不满足任意一个条件,节点都不会被缩容。

      • cluster-autoscaler管理的伸缩组中,单个节点的资源申请值(Request)与单个节点资源容量的比值低于缩容阈值

      • 时间满足缩容触发时延

      • 距离最近一次扩容已超过静默时间

    • 对于GPU类型的节点,以下条件是缩容的必要条件,满足以下条件,节点才可能被缩容,不满足任意一个条件,节点都不会被缩容。

      • cluster-autoscaler管理的伸缩组中,单个节点的资源申请值(Request)单个节点的资源容量的比值低于GPU缩容阈值

      • 时间满足缩容触发时延

      • 距离最近一次扩容已超过静默时间

    GPU缩容阈值

    GPU类型实例的缩容阈值,当低于配置的阈值时,GPU类型节点才可能被缩容。

    缩容触发时延

    集群满足配置的缩容阈值时,在配置的缩容触发时延到达后,集群才有可能开始缩容。单位:分钟。默认情况下是10分钟。

    静默时间

    最近一次扩容后,弹性组件不执行缩容的时间。在静默时间内不缩容节点,但是仍然会判断节点是不是可以缩容。超过静默时间后,如果节点满足了缩容条件且时间大于缩容触发时延的条件,则会被缩容。

    配置的静默时间为10分钟,缩容触发时延为5分钟。那扩容活动后的10分钟内自动伸缩不会缩容节点,但是系统会在静默时间10分钟内会判断节点是否符合缩容条件。如果静默时间结束后,节点符合缩容条件且时间超过缩容触发时延5分钟,节点会被缩容。

    弹性灵敏度

    集群自动弹性伸缩配置支持设置弹性灵敏度,以调整系统判断伸缩的间隔时间。

    -

    节点池扩容顺序策略

    least-waste

    默认策略。如果可扩容节点池有多个,从中选择一个资源浪费最少的节点池进行扩容。

    -

    random

    随机策略。如果可扩容节点池有多个,从中任意选择一个节点池进行扩容。

    -

    priority

    优先级策略。如果可扩容节点池有多个,会按照您自定义的伸缩组顺序,选择优先级高的节点池进行扩容。

    优先级的配置存储在kube-system命名空间下ConfigMap的cluster-autoscaler-priority-expander中。当自动伸缩进行扩容时,实时读取此配置,把可扩容的伸缩组ID与配置中伸缩组ID进行匹配,在匹配上的伸缩组中选取优先级最大值的伸缩组作为扩容对象。

    说明
    • 优先级取值1~100,必须为正整数。

    • 如果选择优先级策略,开启自动伸缩节点池的伸缩组ID必须配置优先级,一个伸缩组ID属于且只属于一个优先级。

    • 如果伸缩组ID没有配置在ConfigMap中,即使满足扩容需求,也会由于优先级未配置而不扩容。因此,如果选择使用priority策略,所有开启自动伸缩的节点池对应伸缩ID需要配置在ConfigMap的cluster-autoscaler-priority-expander 中。

    配置的优先级策略示例如下:

    kind: ConfigMap
    metadata:
      name: cluster-autoscaler-priority-expander
    data:
      priorities: |-
        10:
          - asg-1largeid     #asg-1largeid优先级为10。
          - asg-2largeid     #asg-2largeid优先级为10。
        50:
          - asg-3largeid     #asg-3largeid优先级为50。

    假设某场景下扩容asg-2largeid和asg-3largeid都可以满足集群扩容需求,但由于asg-3largeid优先级较高,自动伸缩会按照优先级对asg-3largeid扩容。

    -

  2. 单击页面右侧的创建节点池

  3. 创建节点池对话框,设置伸缩组的配置项。

    有关配置项的详细说明,请参见创建Kubernetes托管版集群。部分配置项说明如下:

    配置

    说明

    地域

    所创建伸缩组将要部署到的地域。与伸缩组所在集群的地域一致,不可变更。

    专有网络

    所创建伸缩组的网络,与伸缩组所在集群的网络一致。

    虚拟交换机

    所创建伸缩组的虚拟交换机,包含伸缩组的可用区及Pod地址段。

    自动伸缩

    根据需要选择弹性伸缩的节点资源类型(包含普通实例GPU实例共享GPU实例抢占式实例),与创建集群时所选择的节点类型一致。

    实例规格

    伸缩组内实例的规格。

    已选规格

    所选择的伸缩组的实例规格,最多可以选择10种实例规格。

    系统盘

    伸缩组的系统盘。

    挂载数据盘

    是否在创建伸缩组时挂载数据盘,默认情况下不挂载。

    实例数量

    伸缩组所包含的实例数量。

    说明
    • 实例不包含客户已有的实例。

    • 默认情况,实例的最小值是0台,超过0台的时候,集群会默认向伸缩组中添加实例,并将实例加入到伸缩组对应的Kubernetes集群中。

    操作系统

    在开启自动伸缩时,支持选择Alibaba Cloud Linux、CentOS、Windows镜像、Windows Core镜像。

    说明

    当所选镜像是Windows镜像或Windows Core镜像时,系统将自动配置污点(Taints){ effect: 'NoSchedule', key: 'os', value: 'windows' }

    密钥对

    登录伸缩后的节点时所使用的密钥对。可以在ECS控制台新建密钥对。

    说明

    目前只支持密钥对方式登录。

    RDS白名单

    弹性伸缩后的节点可以访问的RDS实例。

    节点标签

    在集群中添加节点标签(Label)后,会自动添加到弹性伸缩扩容出的节点上。

    扩缩容策略

    • 优先级策略:根据以上配置的虚拟交换机的优先级进行扩缩容(选择的虚拟交换机的顺序,由上到下优先级递减)。当优先级较高的虚拟交换机所在可用区无法创建ECS实例时,自动使用下一优先级的虚拟交换机创建ECS实例。

    • 成本优化策略:按vCPU单价从低到高尝试创建。当伸缩配置已设置抢占式计费方式的多实例规格时,优先创建对应抢占式计费实例。当抢占式计费实例规格由于库存等原因无法创建时,自动尝试以按量付费的方式创建。

      付费类型抢占式实例时,还可配置以下参数:

      • 按量实例所占比例%:节点池实例中按量实例应占的比例,取值范围为[0,100]。

      • 开启抢占式实例补偿:开启后,当收到抢占式实例将被回收的系统消息时(即抢占式实例被回收前5分钟左右),伸缩组将尝试创建新的实例,替换掉将被回收的抢占式实例。

      • 允许按量实例补偿:开启后,如果因价格或库存等原因无法创建足够的抢占式实例,伸缩组将自动尝试创建按量实例,以满足ECS实例数量要求。

    • 均衡分布策略:只有设置多个专有网络交换机时,均衡分布策略才能生效。在伸缩组指定的多可用区(即指定多个专有网络交换机)之间均匀分配ECS实例。如果由于库存不足等原因造成可用区之间不平衡,您可以再次进行均衡操作,以平衡资源的可用区分布。

    伸缩模式

    支持标准模式极速模式

    • 标准模式:根据资源申请值的使用量,通过创建、释放ECS的方式进行伸缩。

    • 极速模式:通过创建、停机、启动的方式进行伸缩,提高再次伸缩的速度。

      说明

      极速模式实例停机再次启动时,如果启动失败不会自动释放实例,请注意按需手动释放。

    污点(Taints)

    添加污点后,集群将不会将Pod调度到该节点上。

  4. 单击确认配置,创建伸缩组。

预期结果

  1. 集群自动弹性伸缩配置页面,可以在普通实例下看到新创建的一个伸缩组。

    自动伸缩配置
  2. 集群列表页面,单击目标集群名称或者目标集群右侧操作列下的详情
  3. 在集群管理页左侧导航栏,选择工作负载 > 无状态
  4. 无状态页面,选择kube-system命名空间,可以看到名称为cluster-autoscaler的组件,表示伸缩组已创建成功。

常见问题

为什么节点自动伸缩组件无法弹出节点?

请检查是否存在如下几种场景:

  • 配置伸缩组的实例类型无法满足Pod的资源申请(Request)。ECS实例规格给出的资源大小是实例的售卖规格,实际运行时请考虑以下资源预留。

  • 对可用区有约束的Pod,无法触发配置了多可用区的节点池扩容。

  • 是否完整按照步骤执行了授权操作。授权操作是集群维度的,需要每个集群操作一次。关于授权,请参见步骤二:授权

  • 开启自动伸缩的节点池中出现如下异常情况。

    • 实例未加入到集群且超时。

    • 节点未ready且超时。

    为保证后续扩缩准确性,弹性组件以阻尼方式处理异常情况,在处理完异常情况节点前,不进行扩缩容。

为什么节点自动伸缩组件无法缩容节点?

请检查是否存在如下几种场景:

  • 节点Pod的资源申请(Request)阈值高于设置的缩容阈值。

  • 节点上运行kube-system命名空间的Pod。

  • 节点上的Pod包含强制的调度策略,导致其他节点无法运行此Pod。

  • 节点上的Pod拥有PodDisruptionBudget,且到达了PodDisruptionBudget的最小值。

您可以在开源社区得到更多关于节点自动伸缩组件的常见问题与解答。

多个伸缩组在弹性伸缩的时候是如何被选择的?

在Pod处在无法调度时,会触发弹性伸缩组件的模拟调度逻辑,会根据伸缩组配置的标签和污点以及实例规格等信息进行判断。当配置的伸缩组可以模拟调度Pod的时候,就会被选择进行节点弹出。当同时有多个伸缩组满足模拟调度条件的时候,默认采用的是最少浪费原则,即根据模拟弹出后节点上剩余的资源最小为原则进行抉择。

什么类型的Pod可以阻止CA移除节点?

cluster-autoscaler使用了哪些调度策略来判断不可调度Pod能否调度到开启自动伸缩节点池?

使用的调度策略如下所示。

  • PodFitsResources

  • GeneralPredicates

  • PodToleratesNodeTaints

  • MaxGCEPDVolumeCount

  • NoDiskConflict

  • CheckNodeCondition

  • CheckNodeDiskPressure

  • CheckNodeMemoryPressure

  • CheckNodePIDPressure

  • CheckVolumeBinding

  • MaxAzureDiskVolumeCount

  • MaxEBSVolumeCount

  • ready

  • MatchInterPodAffinity

  • NoVolumeZoneConflict