You need to enable JavaScript to run this app.
导航
弹性资源优先级调度
最近更新时间:2024.10.09 19:42:48首次发布时间:2023.02.27 15:04:26

容器服务提供弹性资源优先级调度策略,支持通过自定义资源策略(ResourcePolicy),设置工作负载的 Pod 被弹性调度到不同类型节点(例如包年包月 ECS、按量付费 ECS、虚拟节点)的顺序。本文主要介绍通过自定义资源策略(ResourcePolicy),设置弹性资源优先级调度的方法。

前提条件

  • 集群中已安装 scheduler-plugin 组件并开启 弹性资源优先级调度。详细操作,请参见 scheduler-plugin 组件

    说明

    若您需要在 VCI 场景使用弹性资源优先级调度,请确保已创建 VCI 业务相关的集群,并在集群中安装了 scheduler-plugin 组件,开启 弹性资源优先级调度。 VCI 相关集群操作,请参见 对接 VCI

  • 在 VCI 业务中使用该能力时,建议开启 VCI 库存感知调度功能。详细操作,请参见 VCI 实例库存感知调度

使用限制

  • 目前仅支持在如下 Kubernetes 版本的集群中使用弹性资源优先级调度功能,若集群版本不满足要求,请升级集群版本,详情请参见 升级集群
  • 该功能与 Kubernetes 的 pod-deletion-cost 冲突,不能同时使用。pod-deletion-cost 相关信息,请参见 pod-deletion-cost
  • 创建 ResourcePolicy 时,请确保目标命名空间下已调度的 Pod 没有被 ResourcePolicy 管理,否则已调度的 Pod 将会被优先缩容。
  • 修改已有的 ResourcePolicy 时,已调度的 Pod 会按照原 ResourcePolicy 的顺序进行缩容,新建的 Pod 会按照更新后 ResourcePolicy 的顺序进行缩容。
  • 仅 Deployment 支持通过 ResourcePolicy 实现逆序缩容,其余工作负载不支持逆序缩容。

    说明

    逆序缩容:指设置了 ResourcePolicy 的工作负载在缩容时,从 ResourcePolicy 中设置的优先级最低的资源池开始缩容。

  • 在弹性容器实例(VCI)场景中使用该功能时,请先了解 什么是弹性容器实例VCI 使用限制

使用方法

在 ResourcePolicy 中定义弹性资源优先级。

注意

  • ResourcePolicy 仅作用于自身所在命名空间下符合指定 Label 的所有工作负载相关 Pod。
  • 下文中的 资源池 与 VKE 中定义的 节点池 不同,资源池 是集群中符合某一筛选条件的所有节点集合。
    例如下文中vci-pool为当前集群中,所有符合type=virtual-kubelet的节点集合。
apiVersion: scheduling.vke.volcengine.com/v1beta1
kind: ResourcePolicy
metadata:
  name: vke-resourcepolicy   # ResourcePolicy 对象名称。
  namespace: default   # ResourcePolicy 所属命名空间。该命名空间必须与被调度的 Pod 命名空间相同。
spec:
  selector:   # 被 ResourcePolicy 管理的 Pod 的 Label 选择器。
    app: nginx
  subsets:   # 资源池配置。
  - name: pool-1   # 资源池名称。
    maxReplicas: 100   # 调度到该资源池的 Pod 数量上限。
    maxReplicasRatio: "0.1"  # 调度到该资源池的 Pod,占所有 Pod 的比例阈值,当超过该阈值时,不再向该资源池调度 Pod。
    whenNotReachMax: ScheduleAnyWay   # 调度策略,有 DoNotSchedule 和 ScheduleAnyWay 两个取值。
    nodeSelectorTerm: 
    - key: cluster.vke.volcengine.com/machinepool-name   # 资源池标签键,此处的 machinepool-name 为资源池(节点池)ID 标签键。
      operator: In
      values:   # 资源池标签值,即实际的资源池(节点池)ID。
      - pcgc1omersf******
      - ncljdfq33h3******
  - name: vci-pool   # 资源池名称。
    maxReplicas: 100 
    maxReplicasRatio: "0.1" 
    nodeSelectorTerm:
    - key: type
      operator: In
      values:
      - virtual-kubelet  # 匹配到 VCI 资源对应的虚拟节点。
    tolerations: # 如果 Pod 被调度到该资源池,需要给 Pod 打上额外的容忍度。
    - effect: NoSchedule
      key: vci.vke.volcengine.com/node-type
      operator: Equal
      value: vci

status:   # ResourcePolicy 的当前状态。
  policyStatuses:  # 各个资源池对应的可调度 Pod 情况。
  - name: pool-1
    missingReplicas: 50
  - name: vci-pool
    missingReplicas: "-"

重点参数说明如下所示。

参数描述
selector被 ResourcePolicy 管理的 Pod 的 Label 选择器。表示该 ResourcePolicy 作用于自身所在命名空间下指定 Label 的 Pod。

subsets

目标资源池。顺序越靠前,Pod 会优先调度到该资源池节点;Pod 缩容时,优先从最靠后的资源池节点进行缩容。
子参数说明如下:

  • name:资源池名称。
  • maxReplicas:调度到该资源池的 Pod 数量上限。不设置表示不限制。可根据 ECS 资源容量/VCI 资源配额和 Pod 的资源需求估算出maxReplicas字段的值。
  • maxReplicasRatio:调度到该资源池的 Pod,占所有被 ResourcePolicy 管理的 Pod 的比例阈值,当超过该阈值时,不再向该资源池调度 Pod。取值范围为 [0,1]。
  • whenNotReachMax:调度策略,有如下两种策略:
    • DoNotSchedule:如果该资源节点池还未达到maxReplicasRatiomaxReplicas阈值,则 Pod 只能被调度到该资源节点池或更高优先级的资源节点池。
    • ScheduleAnyWay:当该资源节点池没有可调度的资源时,无论是否已经达到maxReplicasRatiomaxReplicas阈值,考虑次优先级的资源节点池。
  • nodeSelectorTerm:通过 Label 选择可调度的资源节点池。
  • tolerations:如果 Pod 被调度到该资源池,需要给 Pod 打上额外的容忍度(Toleration)。格式与 Kubernetes 中pod.spec.tolerations相同。不配置表示不需要给 Pod 打额外的 Toleration。

policyStatuses

各个资源池对应的可调度 Pod 情况。

  • name:资源池名称。
  • missingReplicas:该资源池剩余可调度的 Pod 数量。missingReplicas: "-"表示您在创建该 ResourcePolicy 时,没有设置 maxReplicas。

使用示例

本文以如下场景为例,描述创建 ResourcePolicy,定义弹性资源优先级的方法:

您的集群中有固定的云服务器(ECS)资源,即节点所在节点池没有配置弹性伸缩,同时还有弹性容器实例(VCI)资源。在该集群中部署一个工作负载(例如 Deployment)时,为了降低资源使用成本,您希望:

  • 部署的 Pod 优先调度到固定的 ECS 资源,当 ECS 资源不足时,使用 VCI 弹性资源作为补充。
  • 在缩容时优先删除 VCI 上的 Pod,释放 VCI 资源,再删除 ECS 上的 Pod,释放 ECS 资源。

该方法主要适用于具有一定长稳流量,偶尔出现突发性峰值流量的工作负载。可通过固定的 ECS 资源承载长稳流量,通过 VCI 的快速弹性能力应对突发峰值。更多使用场景示例,请参见本文下方 场景示例

步骤一:(可选)创建集群并开启弹性资源优先级调度

若您已有可用的集群,且安装了 scheduler-plugin 组件并开启了弹性资源优先级调度,可跳过本步骤。

  1. 登录 容器服务控制台
  2. 在容器服务的左侧导航栏,选择 集群
  3. 单击 创建集群,根据系统提示和实际需求配置集群参数。
    其中部分参数按如下说明配置,其余参数的详细配置说明,请参见 创建集群
    • 因为以集群中同时存在 ECS 和 VCI 资源的场景为例,所以在 ① 集群配置 步骤中 容器网络模型 选择 VPC-CNI
      alt
    • 在 ③ 组件配置 步骤的 scheduler-plugin 参数配置 中开启 弹性资源优先级调度 按钮并配置调度权重。
      alt
  4. 确认配置并单击 确定,创建完成集群。

步骤二:创建 ResourcePolicy

  1. 通过 kubectl 连接 步骤一 中创建的 VPC-CNI 集群。具体操作说明,请参见 连接集群
  2. 创建 ResourcePolicy 的 YAML 文件。示例文件vke-resourcepolicy-nginx.yaml代码如下:
    apiVersion: scheduling.vke.volcengine.com/v1beta1
    kind: ResourcePolicy
    metadata:
      name: vke-resourcepolicy-nginx   
      namespace: default   # ResourcePolicy 所属命名空间。该命名空间必须与被调度的 Pod 命名空间相同。
    spec:
      selector:
        app: demo-nginx   # Label 为 app:demo-nginx 的 Pod 将被该 ResourcePolicy 管理。
      subsets:
      - name: pool-ecs    # 第一个 subset 为 ECS 资源池。
        maxReplicas: 2  # 调度到该资源池的 Pod 数量上限,本示例为实现 ECS 资源不足或 Pod 数量达到上限时调度 Pod 到 VCI 资源的效果,此处设置为 2。实际使用中请按“参数说明”估算。
        whenNotReachMax: ScheduleAnyWay  #配置为 ScheduleAnyWay,确保当 ECS 资源不足时 Pod 直接被调度到 VCI 资源上。
        nodeSelectorTerm: 
        - key: cluster.vke.volcengine.com/machinepool-name   
          operator: In
          values:
          - pcm5pq1r5i7aqm******   # 匹配的 ECS 资源对应节点池 ID,请确保节点池 ID 配置正确。可以配置多个节点池 ID。
      - name: pool-vci   # 第二个 subset 为 VCI 资源池。
        maxReplicas: 100  # 建议为 VCI 资源池配置可调度的 Pod 数量上限,以防止 VCI 资源配额被耗尽。
        nodeSelectorTerm:
        - key: type
          operator: In
          values:
          - virtual-kubelet  # 匹配到 VCI 虚拟节点。
        tolerations: # 如果 Pod 被调度到该资源池,需要给 Pod 打上额外的容忍度。
        - effect: NoSchedule
          key: vci.vke.volcengine.com/node-type
          operator: Equal
          value: vci
    
  3. 执行以下命令,创建 ResourcePolicy。
    kubectl apply -f vke-resourcepolicy-nginx.yaml
    

步骤三:创建工作负载

本文以创建无状态负载(Deployment)为例,更多工作负载相关操作,请参见 工作负载

  1. 创建 Deployment 的 YAML 文件。示例文件demo-nginx.yaml代码如下:
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: demo-nginx
      namespace: default  # Deployment 所属命名空间,与 ResourcePolicy 的 namespace 相匹配。
    spec:
      replicas: 5  # Pod 数量。
      selector:
        matchLabels:
          app: demo-nginx
      template:
        metadata:
          labels:
            app: demo-nginx  # Pod Label,与 ResourcePolicy 的 selector 中配置的 label 相匹配。
        spec:
          schedulerName: default-scheduler
          containers:
          - image: nginx:1.14.2  # Pod 的容器镜像地址和 Tag,请替换为您实际业务中的镜像地址。
            imagePullPolicy: IfNotPresent
            name: nginx-container
            resources:
              requests:
                cpu: 10m
                memory: 10Mi
          dnsPolicy: ClusterFirst
          restartPolicy: Always
          securityContext: {}
    
  2. 执行以下命令,创建 Deployment。
    kubectl apply -f demo-nginx.yaml
    

步骤四:查看调度结果

  1. 执行如下命令,查看调度结果。
    kubectl get po -n default -o wide
    
    预期输出如下,2 个 Pod 被调度到 ECS 资源上,剩余的 Pod(3 个)被调度到 VCI 资源。
    NAME                          READY   STATUS    RESTARTS   AGE   IP               NODE                      NOMINATED NODE   READINESS GATES
    demo-nginx-6b6bfc8b7f-62qls   1/1     Running   0          66m   192.168.**.**    vci-node1-cn-shanghai-a   <none>           <none>
    demo-nginx-6b6bfc8b7f-97md6   1/1     Running   0          66m   192.168.**.**    192.168.**.**             <none>           <none>
    demo-nginx-6b6bfc8b7f-bzdnw   1/1     Running   0          66m   192.168.**.**    vci-node1-cn-shanghai-b   <none>           <none>
    demo-nginx-6b6bfc8b7f-rjrnx   1/1     Running   0          66m   192.168.**.**    vci-node1-cn-shanghai-a   <none>           <none>
    demo-nginx-6b6bfc8b7f-tjc5p   1/1     Running   0          31m   192.168.**.**    192.168.**.**             <none>           <none>
    
  2. (可选)查看 Pod 缩容时,释放资源的情况。
    1. 执行如下命令,将 Deployment 的 Pod 数量(即 replicas 参数值)降到 3。
      kubectl scale --replicas=3 deployment/demo-nginx -n default
      
    2. 查看调度结果。
      kubectl get po -n default -o wide
      
      预期输出如下,VCI 资源上的 2 个 Pod 被优先缩容,释放 VCI 资源。
      NAME                          READY   STATUS    RESTARTS   AGE   IP               NODE                      NOMINATED NODE   READINESS GATES
      demo-nginx-6b6bfc8b7f-97md6   1/1     Running   0          70m   192.168.**.**    192.168.**.**             <none>           <none>
      demo-nginx-6b6bfc8b7f-bzdnw   1/1     Running   0          70m   192.168.**.**    vci-node1-cn-shanghai-b   <none>           <none>
      demo-nginx-6b6bfc8b7f-tjc5p   1/1     Running   0          35m   192.168.**.**    192.168.**.**             <none>           <none>
      

场景示例

场景一:VCI 资源 + 自动伸缩的 ECS 资源

  • 场景说明
    所在集群的目标命名空间下有 VCI 资源和自动伸缩的 ECS 资源时,优先使用 VCI 资源。当 VCI 配额不足时,将 Pod 调度到 ECS 资源中,并在 ECS 资源池中触发弹性伸缩进行扩容。该方法主要适用于突发资源用量较大的批量作业等业务,无需维持固定的 ECS 资源成本,优先通过 VCI 获得高性价比的弹性资源。当 VCI 承载能力不够时,可以通过 ECS 的弹性伸缩来保障资源供应。
  • 配置说明
    1. 将 VCI 资源对应的虚拟节点配置为第一个subset
      建议配置subset下的maxReplicas字段,防止耗尽 VCI 资源配额。可根据 VCI 资源的配额和 Pod 的资源需求估算出maxReplicas字段的值。
    2. 将 ECS 资源对应的节点池配置为第二个subset
      其中:
      • 需配置subset下的maxReplicas字段,用于控制 ECS 资源被使用的上限。可根据 ECS 资源的容量和 Pod 的资源需求估算出maxReplicas字段的值。
      • subsetwhenNotReachMax配置为DoNotSchedule,在 ECS 资源不足时会短暂 Pending 被调度的 Pod,然后触发弹性伸缩对 ECS 资源节点池进行扩容。
      • 请确保对应的 ECS 节点池已开启了弹性伸缩配置。详情请参见 创建节点弹性伸缩
  • 配置样例
    apiVersion: scheduling.vke.volcengine.com/v1beta1
    kind: ResourcePolicy
    metadata:
      name: vke-resourcepolicy-nginx   
      namespace: default
    spec:
      selector:
        app: nginx   # Label 为 app: nginx 的 Pod 将被该 ResourcePolicy 管理。
      subsets:
      - name: pool-vci   # 第一个 subset 为 VCI  资源池,优先使用 VCI 资源。
        maxReplicas: 100  # 建议配置 maxReplicas 字段,防止耗尽 VCI 资源配额。
        nodeSelectorTerm:
        - key: type
          operator: In
          values:
          - virtual-kubelet  # 匹配到 VCI 虚拟节点。
      - name: pool-ecs    # 第二个 subset 为 ECS 资源池,作为 VCI 资源不足时的补充。
        maxReplicas: 1000  # 需配置 maxReplicas 字段,用于控制 ECS 资源被使用的上限。
        whenNotReachMax: DoNotSchedule  # 配置为 DoNotSchedule,当 ECS 节点池资源不足时,将会暂时让 Pod 处于 Pending 状态并等待节点池弹性伸缩。
        nodeSelectorTerm: 
        - key: cluster.vke.volcengine.com/machinepool-name   
          operator: In
          values:
          - pcgc1omersf******   # 匹配的 ECS 节点池 ID,可以配置多个节点池。
          - ncljdfq33h3******
        tolerations: # 如果 Pod 被调度到该资源池,需要给 Pod 打上额外的容忍度。
        - effect: NoSchedule
          key: vci.vke.volcengine.com/node-type
          operator: Equal
          value: vci   
    

场景二:按比例将 Pod 调度到 ECS 资源和 VCI 资源

  • 场景说明
    按照一定的比例,将工作负载中的 Pod 调度到 ECS 资源和 VCI 资源中,以维持固定资源和弹性资源之间的平衡。该方法适用于业务从 ECS 资源向 VCI 弹性资源切换的过程中通过调整调度比例,实现逐步过渡。

  • 配置说明

    1. 将 ECS 资源对应的节点池配置为第一个subset
      需要配置subset下的maxReplicasRatio字段,按照比例调度 Pod 到 ECS 资源。
    2. 将 VCI 资源对应的虚拟节点配置为第二个subset
      需要配置subset下的maxReplicasRatio字段,按照比例调度 Pod 到 VCI 资源。建议保障所有subsetmaxReplicasRatio字段比例阈值之和为 1。

    注意

    由于调度比例的计算在 Pod 数量较少时存在一定误差,不建议maxReplicasRatiowhenNotReachMax: DoNotSchedule同时配置,否则可能出现部分 Pod 在预期外被 Pending 的情况。

  • 配置样例

    apiVersion: scheduling.vke.volcengine.com/v1beta1
    kind: ResourcePolicy
    metadata:
      name: vke-resourcepolicy-nginx   
      namespace: default
    spec:
      selector:
        app: nginx   # Label 为 app: nginx 的 Pod 将被该 ResourcePolicy 管理。
      subsets:
      - name: pool-ecs    # 第一个 subset 为 ECS 资源池。
        maxReplicasRatio: "0.6"  # 为第一个资源池配置调度比例为 0.6。
        whenNotReachMax: ScheduleAnyWay  # 建议配置为 ScheduleAnyWay。
        nodeSelectorTerm: 
        - key: cluster.vke.volcengine.com/machinepool-name   
          operator: In
          values:
          - pcgc1omersf******   # 匹配的 ECS 节点池 ID,可以配置多个节点池。
          - ncljdfq33h3******
      - name: pool-vci   # 第二个 subset 为 VCI 资源池。
        maxReplicasRatio: "0.4"  # 为第二个资源池配置调度比例为 0.4。
        whenNotReachMax: ScheduleAnyWay  # 建议配置为 ScheduleAnyWay 。 
        nodeSelectorTerm:
        - key: type
          operator: In
          values:
          - virtual-kubelet  # 匹配到 VCI 虚拟节点。
        tolerations: # 如果 Pod 被调度到该资源池,需要给 Pod 打上额外的容忍度。
        - effect: NoSchedule
          key: vci.vke.volcengine.com/node-type
          operator: Equal
          value: vci