自定义资源优先级调度

阿里云容器计算服务ACS支持在Pod标签中声明使用计算类型(Compute Class)和算力质量(Compute QoS)。由于不同类型实例的库存是在动态变化的,可能会因为资源库存等因素导致某种类型的实例无法创建。通过自定义资源优先级调度,您可以为Pod同时指定多种计算类型或算力质量,调度器将按先后顺序依次尝试创建对应类型的Pod实例,并通过Pod deletion cost机制控制应用的逆序缩容。本文介绍如何在ACS集群中使用自定义资源优先级调度。

前提条件

  • 已安装调度器组件kube-scheduler,且版本满足以下要求。

    ACS集群版本

    调度器组件版本

    1.30

    v1.30.3-aliyun-1.1.1及以上(即当前所有版本)

    1.28

    v1.28.9-aliyun-1.1.0及以上

    1.26

    v1.26.3-aliyun-1.1.0及以上

  • 已安装acs-virtual-node组件,版本为v2.12.0-acs.4或以上。

注意事项

自定义资源优先级调度目前仅支持通用型和性能型计算类型。具体信息,请参见计算类型定义

ACS自定义资源优先级调度基于Kubernetes社区提供的Pod deletion cost功能控制Pod实例缩容顺序。Pod deletion cost代表了删除开销,通常值越小表示会被优先缩容,事实上缩容算法会考虑多种因素,这取决于应用控制器的具体实现。若Pod在创建时已经填写了controller.kubernetes.io/pod-deletion-cost注解,值会被自定义资源优先级调度策略覆盖。关于Pod deletion cost的更多信息,请参见Pod deletion cost

使用方式

ACS集群以虚拟节点的形式提供资源。Pod的资源属性主要包括可用区、计算类型和算力质量。为此,ACS定义了ResourcePolicy调度策略,支持在配置中通过spec.selector标记一类Pod,并同时配置多种资源属性。调度器将在资源库存不足时,按照配置顺序创建其他类型的实例。ResourcePolicy调度策略使用方式如下。

  1. 创建ResourcePolicy调度策略。

    apiVersion: scheduling.alibabacloud.com/v1alpha1
    kind: ResourcePolicy
    metadata:
      name: rp-demo
      namespace: default
    spec:
      selector: # 在selector中标记Pod,表示带有app=stress标签的Pod将遵循此调度策略
        app: stress
      units: # 在units中定义调度顺序
      - resource: acs # 优先申请best-effort类型的资源
        podLabels:
          alibabacloud.com/compute-class: general-purpose
          alibabacloud.com/compute-qos: best-effort
      - resource: acs # 前者库存不足时,申请default类型的资源
        podLabels:
            alibabacloud.com/compute-class: general-purpose
            alibabacloud.com/compute-qos: default
  2. 创建一个任意类型的工作负载(例如Job),并在labels中关联ResourcePolicy。

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: demo-job
      namespace: default
    spec:
      parallelism: 3
      template:
        metadata:
          labels:
            app: stress # 关联ResourcePolicy中spec.selector定义的配置
        spec:
          containers:
          - name: demo-job
            image: registry.cn-hangzhou.aliyuncs.com/acs/stress:v1.0.4
            args:
              - 'infinity'
            command:
              - sleep
            resources:
              requests:
                cpu: "1"
                memory: "1Gi"
              limits:
                cpu: "1"
                memory: "1Gi"
          restartPolicy: Never
      backoffLimit: 4

高级配置参数

以下ResourcePolicy的详细YAML示例展示了自定义资源优先级调度的高级配置参数格式。

apiVersion: scheduling.alibabacloud.com/v1alpha1
kind: ResourcePolicy
metadata:
  name: rp-demo
  namespace: default
spec:
  # 以下为应用配置,用于标记一部分pod,符合该条件的Pod将遵循此调度策略
  selector:
    app: stress
  # 以上为应用配置

  # 以下为资源配置,用于描述调度顺序
  units:
  - resource: acs # resource类型必须指定为acs
    podLabels: # 优先申请"general-purpose"+"best-effort"类型的资源
      alibabacloud.com/compute-class: general-purpose
      alibabacloud.com/compute-qos: best-effort
    nodeSelector: # 支持通过nodeSelector指定虚拟节点的可用区
      topology.kubernetes.io/zone: cn-hangzhou-i
  - resource: acs # 前者库存不足时,再申请"general-purpose"+"default"类型的资源
    podLabels:
      alibabacloud.com/compute-class: general-purpose
      alibabacloud.com/compute-qos: default
  # 以上为资源配置
 # 其他字段适用于非ACS集群,ResourcePolicy创建后会有默认值,无需关注

应用配置

应用配置由一组标签组成,只有带有该标签的Pod会遵循此策略,您可以根据应用类型配置不同的资源顺序。

配置项

类型

说明

示例

selector

map[string]string

同时带有这些标签的Pod将按本ResourcePolicy规则调度。

selector:
  app: stress
  stage: pre-publish

资源配置

资源配置由一个列表组成,列表中的每个单元描述了详细的资源属性,对于符合应用配置条件的Pod,调度器将按每个单元的属性依次尝试创建,当库存不足时自动尝试下一个单元。当所有单元的库存都不足时,Pod会处于Pending状态,调度器会持续按顺序重试,直至创建成功。下表中描述了每个单元中配置字段的详细含义。

配置项

类型

说明

取值

示例

resource

string

资源类型,必填。仅支持acs。

acs

resource: acs

nodeSelector

map[string]string

通过label标记筛选虚拟节点,例如可用区范围。

支持的标签范围详见节点亲和性调度

nodeSelector:
  topology.kubernetes.io/zone: cn-hangzhou-i

podLabels[alibabacloud.com/compute-class]

string

描述Pod申请的计算类型(Compute Class)。

  • general-purpose(默认值)

  • performance

general-purpose

podLabels[alibabacloud.com/compute-qos]

string

描述Pod申请的算力质量(Compute QoS)。

  • default(默认值)

  • best-effort

default

操作示例

本示例演示通过ResourcePolicy为应用依次申请default和best-effort算力质量的资源。

  1. 使用以下内容创建resource-policy.yaml。声明了对于app=stress标签的Pod,申请计算类型为performance、算力质量为default的资源。

    apiVersion: scheduling.alibabacloud.com/v1alpha1
    kind: ResourcePolicy
    metadata:
      name: stress-demo
      namespace: default
    spec:
      selector:
        app: stress
      units:
      - resource: acs
        podLabels:
          alibabacloud.com/compute-class: performance
          alibabacloud.com/compute-qos: default
  2. 执行以下命令,将ResourcePolicy部署到集群。

    kubectl apply -f resource-policy.yaml
  3. 使用以下内容创建stress-dep.yaml。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: stress
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: stress
      template:
        metadata:
          labels: # 与ResourcePolicy中的配置保持一致
            app: stress
        spec:
          containers:
          - name: stress
            image: registry-cn-hangzhou.ack.aliyuncs.com/acs/stress:v1.0.4
            command:
            - "sleep"
            - "infinity"
            resources:
              limits:
                cpu: '1'
                memory: 1Gi
              requests:
                cpu: '1'
                memory: 1Gi
  4. 执行以下命令,将stress应用部署到集群。

    kubectl apply -f stress-dep.yaml
  5. 执行以下命令,查看Pod状态。

    kubectl get pod -L alibabacloud.com/compute-class,alibabacloud.com/compute-qos

    预期输出:

    # 输出结果受资源库存等因素影响,请以实际为准
    NAME               READY   STATUS    RESTARTS   AGE   COMPUTE-CLASS   COMPUTE-QOS
    stress-xxxxxxxx1   1/1     Running   0          53s   performance     default
  6. 使用以下内容,更新上述resource-policy.yaml文件。增加了资源属性描述,要求按以下顺序申请资源:

    1. 先申请计算类型为general-purpose、算力质量为best-effort的资源。

    2. 上述资源库存不足时,再申请计算类型为performance、算力质量为default的资源。

    apiVersion: scheduling.alibabacloud.com/v1alpha1
    kind: ResourcePolicy
    metadata:
      name: stress-demo
      namespace: default
    spec:
      selector:
        app: stress
      units:
      - resource: acs
        podLabels:
          alibabacloud.com/compute-class: general-purpose
          alibabacloud.com/compute-qos: best-effort
      - resource: acs
        podLabels:
          alibabacloud.com/compute-class: performance
          alibabacloud.com/compute-qos: default
  7. 执行以下命令,更新集群内的ResourcePolicy策略。更新后的策略将对后续新创建的Pod生效。

    kubectl apply -f resource-policy.yaml
  8. 执行以下命令,将步骤3创建的stress应用,扩容为2个副本。

    kubectl scale deployment stress --replicas=2
  9. 执行以下命令,查看Pod状态。

    kubectl get pod -L alibabacloud.com/compute-class,alibabacloud.com/compute-qos

    预期输出:

    # 输出结果受资源库存等因素影响,请以实际为准
    NAME                     READY   STATUS    RESTARTS   AGE     COMPUTE-CLASS     COMPUTE-QOS
    stress-xxxxxxxx1         1/1     Running   0          2m14s   performance       default
    stress-xxxxxxxx2         1/1     Running   0          33s     general-purpose   best-effort

    可以看到新扩容的副本,计算类型和算力质量分别为general-purpose和best-effort。