文档首页/ 云容器引擎 CCE/ 用户指南/ 调度/ Volcano调度/ 应用扩缩容优先级策略
更新时间:2024-09-29 GMT+08:00

应用扩缩容优先级策略

通过应用扩缩容优先级策略,您可以精细调整Pod在不同类型节点上的扩容和缩容顺序,实现资源管理的最优化。在使用默认扩缩容优先级策略的情况下,扩容过程中Pod优先被调度到包周期的节点,其次被调度到按需计费的节点,最后被调度到virtual-kubelet节点(弹性至CCI);缩容过程中优先删除virtual-kubelet节点(弹性至CCI)的Pod,其次删除按需计费节点上的Pod,最后删除包周期节点上的Pod。

应用扩缩容优先级策略包括两个方面:
  • 针对扩容:集群中新建的Pod,Volcano会按照设定的节点优先级进行调度。
  • 针对缩容:指定工作负载时,Volcano会按照设定的节点优先级对其进行打分,用于缩容时决定Pod删除顺序。

约束与限制

  • 集群版本为v1.23.11及以上、v1.25.6及以上、v1.27.3及以上,以及其他更高版本集群。
  • 集群中需安装Volcano调度器插件(1.12.1及以上版本,并开启应用扩缩容优先级策略开关)。
  • 当前扩缩容优先级功能默认支持对Deployment(也间接包括ReplicaSet)生效。若希望对第三方工作负载生效,可以通过高级配置指定,详情请参见配置第三方工作负载应用扩缩容优先级策略
  • 若要使用扩容调度优先级策略,需要将工作负载的spec.schedulerName设置成volcano或者将集群默认调度器设置成volcano。目前对于没有设置资源Requests和Limits属性的工作负载,扩容优先级功能不生效。
  • 以使用默认优先级策略为例,调度器在调度工作负载时会按照包周期节点 > 按需节点 > virtual-kubelet节点(弹性至CCI)的优先级进行调度。但由于调度器会从多个维度对调度结果进行考虑,本优先级策略只是其中一个维度,因此无法百分百确保完全实现上述优先级。
  • Volcano调度器存在调度性能和调度结果之间的权衡。当集群存在大量可调度节点时,Volcano出于调度性能的考虑会只选择其中一部分节点来进行调度选择,不会计算全局调度最优解,详情请参见社区文档链接。因此该行为与本优先级策略存在冲突,您可以调整Volcano可调度的节点比例,来使得Volcano选择所有节点进行调度。

应用扩缩容优先级策略介绍

开启应用扩缩容优先级策略,将会在集群中新增两类CRD资源,分别为Balancer与BalancerPolicyTemplate,并创建默认的扩缩容优先级策略,详情请参见默认应用扩缩容优先级策略。Volcano插件根据BalancerPolicyTemplate来获取各个节点的优先级,以控制应用扩容时Pod调度的优先级,同时volcano插件基于Balancer和BalancerPolicyTemplate来设置应用缩容时的优先级。

  • BalancerPolicyTemplate CRD资源用来进行优先级策略定义。以默认扩缩容优先级策略为例,默认BalancerPolicyTemplate CR资源将会把包周期节点的优先级设置为最高,按需计费节点次之,virtual-kubelet节点(弹性至CCI)设置为最低。

    BalancerPolicyTemplate CR资源不支持更新操作。

  • Balancer CRD资源用来申明扩缩容优先级的作用范围。创建Balancer CR资源时,可以指定某个命名空间下的工作负载作为生效范围,也可以具体指定某个Deployment或者某个ReplicaSet工作负载作为生效范围。

一个Balancer CR资源对应一个BalancerPolicyTemplate CR资源,两者结合共同申明哪些工作负载使用了哪些优先级策略。

插件默认的扩缩容优先级策略通过BalancerPolicyTemplate对象将包周期节点、按需计费节点、virtual-kubelet节点(弹性至CCI)三种类型分成不同的优先级,扩容时,volcano在调度新增Pod时将会考虑这些优先级,优先将Pod调度到优先级高的包周期节点上。

通过Balancer和BalancerPolicyTemplate对象,Volcano插件对Balancer作用范围内的Pod,根据BalancerPolicyTemplate对象定义的优先级分别打上以下注解:

  • openvessel.io/workload-balancer-score:表示Pod的分值,对于高优先级节点上的Pod,其对应的分值也相对较大。
  • autoscaling.volcano.sh/dominated-by-balancer:表示当前Pod受哪个Balancer对象控制,缩容时会优先缩容分值低的Pod。

如果您原先的Pod已经存在社区支持的controller.kubernetes.io/pod-deletion-cost注解,那么缩容时将会按照该值定义的优先级来进行缩容。当两个Pod对应controller.kubernetes.io/pod-deletion-cost值相同时,才会按照openvessel.io/workload-balancer-score注解定义的优先级进行缩容

您可以通过高级配置中的“workload_balancer_score_annotation_key”参数来指定存放Pod分值的注解key,详情请参见配置第三方工作负载应用扩缩容优先级策略

配置应用扩缩容优先级策略

  1. 开启应用扩缩容优先级策略开关并成功安装Volcano插件后,会在集群中创建默认扩缩容优先级策略。

    1. 获取默认Balancer CR资源。
      # kubectl get balancer default-balancer -oyaml
      
      apiVersion: autoscaling.volcano.sh/v1alpha1
      kind: Balancer
      metadata:
        name: default-balancer
      spec:
        balancerPolicyTemplateName: default-balancerpolicytemplate
        targets:
        - namespaceSelector:
            matchExpressions:
              - key: kubernetes.io/metadata.name
                operator: Exists
        weight: 10 
    2. 获取默认BalancerPolicyTemplate CR资源。
      # kubectl get balancerpolicytemplate default-balancerpolicytemplate -oyaml
      
      apiVersion: autoscaling.volcano.sh/v1alpha1
      kind: BalancerPolicyTemplate
      metadata:
        name: default-balancerpolicytemplate
      spec:
        policy:
          policyName: Priority
          priorities:
            priorityGroups:
            - priority: 10
              requirements:
              - key: node.cce.io/billing-mode
                operator: In
                values:
                - post-paid
            - priority: 100
              requirements:
              - key: node.cce.io/billing-mode
                operator: In
                values:
                - pre-paid
            - priority: 1
              requirements:
              - key: kubernetes.io/role
                operator: In
                values:
                - virtual-kubelet
                - bursting

    具体参数含义请参见默认应用扩缩容优先级策略

  2. 部署工作负载,设定实例数为1。

    当前应用的Pod将会优先调度到包周期节点上。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: balancer-test
      namespace: default
      labels:
        virtual-kubelet.io/burst-to-cci: 'auto'  #如果集群资源不足时,支持将Pod部署到CCI集群
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: balancer-test
      template:
        metadata:
          labels:
            app: balancer-test
        spec:
          containers:
          - image: nginx:latest
            imagePullPolicy: IfNotPresent
            name: container-1
            resources:
              limits:
                cpu: 250m
                memory: 512Mi
              requests:
                cpu: 250m
                memory: 512Mi
          schedulerName: volcano

  3. 调整工作负载实例数为5。

    当前应用的Pod将会优先调度到包周期节点上。在包周期节点资源不足情况下,优先调度到按需计费节点上。在按需计费节点资源不足情况下,优先调度到virtual-kubelet节点(弹性至CCI)。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: balancer-test
      namespace: default
      labels:
        virtual-kubelet.io/burst-to-cci: 'auto'  #如果集群资源不足时,支持将Pod部署到CCI集群
    spec:
      replicas: 5
      selector:
        matchLabels:
          app: balancer-test
      template:
        metadata:
          labels:
            app: balancer-test
        spec:
          containers:
          - image: nginx:latest
            imagePullPolicy: IfNotPresent
            name: container-1
            resources:
              limits:
                cpu: 250m
                memory: 512Mi
              requests:
                cpu: 250m
                memory: 512Mi
          schedulerName: volcano

  4. 查看各种类型节点上Pod的分值。

    1. 包周期节点上的Pod。
      apiVersion: v1
      kind: Pod
      metadata:
        annotations:
          autoscaling.volcano.sh/dominated-by-balancer: default-balancer  #当前Pod通过名为default-balancer的Balancer CR资源控制扩缩优先级
          openvessel.io/workload-balancer-score: "100" #当前包周期节点对应的优先级,也代表着Pod的分值
          ...
        nodeName: 192.168.20.100 #包周期节点
    2. 按需计费节点上的Pod。
      apiVersion: v1
      kind: Pod
      metadata:
        annotations:
          autoscaling.volcano.sh/dominated-by-balancer: default-balancer #当前Pod通过名为default-balancer的Balancer CR资源控制扩缩优先级
          openvessel.io/workload-balancer-score "10"  #当前按需计费节点对应的优先级,也代表着Pod的分值
          ...
        nodeName: 192.168.20.196 #按需计费节点
    3. virtual-kubelet节点(弹性至CCI)的Pod。
      apiVersion: v1
      kind: Pod
      metadata:
        annotations:
          autoscaling.volcano.sh/dominated-by-balancer: default-balancer #当前Pod通过名为default-balancer的Balancer CR资源控制扩缩优先级
          openvessel.io/workload-balancer-score: "1"  #当前virtual-kubelet节点对应的优先级,也代表着pod的分值
          ...
        nodeName: virtual-kubelet #virtual-kubelet节点

  5. 逐步进行工作负载的缩容操作,调小实例数。

    virtual-kubelet节点(弹性至CCI)的Pod将优先被删除,其次为按需计费节点上的Pod,最后为包周期节点上的Pod。

默认应用扩缩容优先级策略

使用默认应用扩缩容优先级策略的情况下,集群中存在两个默认CR资源:

  • Balancer CRD对应的CR资源
    apiVersion: autoscaling.volcano.sh/v1alpha1
    kind: Balancer
    metadata:
      name: default-balancer
    spec:
      balancerPolicyTemplateName: default-balancerpolicytemplate
      targets:
      - namespaceSelector:
          matchExpressions:
            - key: kubernetes.io/metadata.name
              operator: Exists
      weight: 10 
    表1 Balancer对象关键参数说明

    字段

    含义

    类型

    备注

    metadata.name

    名称

    String

    必填字段。

    spec. balancerPolicyTemplateName

    优先级策略名称

    String

    必填字段。值为集群中相应BalancerPolicyTemplate CR资源名。

    spec.targets

    优先级策略作用范围

    Slice

    必填字段。举例:

    • 针对default命名空间下的应用生效
      spec:
        targets:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: default
    • 针对default、other、another多个命名空间下的应用生效
      spec:
        targets:
        - namespaceSelector:
            matchExpressions:
              - key: kubernetes.io/metadata.name
                operator: In
                values:
                - default
                - other
                - another
    • 针对所有命名空间下的应用生效
      spec:
        targets:
        - namespaceSelector:
            matchExpressions:
              - key: kubernetes.io/metadata.name
                operator: Exists
    • 只针对名为xxx-xxx-xxx,类型为Deployment的应用生效
      spec:
        targets:
        - objectSelectors:
            - name: xxx-xxx-xxx
              kind: Deployment
    • 只针对命名空间为default,名为xxx-xxx-xxx类型为Deployment的应用生效
      spec:
        targets:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: default
          objectSelectors:
            - name: xxx-xxx-xxx
              kind: Deployment

    spec.weight

    优先级策略权重

    int32

    必填字段。在集群存在多个Balancer 对象资源情况下,某个应用可能存在于多个Balancer对象作用范围的交集中,此时选择weight值大的Balancer对象生效。

  • BalancerPolicyTemplate CRD对应的CR资源
    apiVersion: autoscaling.volcano.sh/v1alpha1
    kind: BalancerPolicyTemplate
    metadata:
      name: default-balancerpolicytemplate
    spec:
      policy:
        policyName: Priority
        priorities:
          priorityGroups:
          - priority: 10
            requirements:
            - key: node.cce.io/billing-mode
              operator: In
              values:
              - post-paid
          - priority: 100
            requirements:
            - key: node.cce.io/billing-mode
              operator: In
              values:
              - pre-paid
          - priority: 1
            requirements:
            - key: kubernetes.io/role
              operator: In
              values:
              - virtual-kubelet
              - bursting
    表2 BalancerPolicyTemplate对象关键参数说明

    字段

    含义

    类型

    备注

    metadata.name

    名称

    String

    必填字段。

    spec.policy

    优先级策略内容

    Struct

    必填字段。

    spec.policy.policyname

    优先级策略名

    String

    必填字段。当前只支持名为“Priority”的优先级策略。

    spec.policy.priorities. priorityGroups

    优先级策略中定义的具体优先级

    Slice

    必填字段。举例:

    • 将包周期节点的优先级设置为100
            priorityGroups:
            - priority: 100
              requirements:
              - key: node.cce.io/billing-mode
                operator: In
                values:
                - pre-paid
    • 将按需计费节点的优先级设置为10
            priorityGroups:
            - priority: 10
              requirements:
              - key: node.cce.io/billing-mode
                operator: In
                values:
                - post-paid
    • 将virtual-kubelet/bursting节点的优先级设置为1
            priorityGroups:
            - priority: 1
              requirements:
              - key: kubernetes.io/role
                operator: In
                values:
                - virtual-kubelet
                - bursting

自定义应用扩缩容优先级策略

BalancerPolicyTemplate 资源用来进行优先级策略定义,如果用户需要自定义应用扩缩容优先级策略,则需要针对其内容进行修改。

如果存在多个BalancerPolicyTemplate资源,扩缩策略执行结果将受到这些资源对象的共同作用。因此,如果用户不存在默认扩缩容优先级策略的应用场景,可以执行如下命令对默认优先级策略进行删除。

kubectl delete balancerpolicytemplate default-balancerpolicytemplate

以“扩容时优先将工作负载调度到HCE2.0操作系统的节点,其次调度到欧拉操作系统的节点;缩容时优先删除欧拉操作系统节点上的工作负载,其次删除HCE2.0操作系统上的工作负载”为例:

  1. 编写新BalancerPolicyTemplate 资源对象。

    vim new-balancerpolicytemplate.yaml
    内容如下:
    apiVersion: autoscaling.volcano.sh/v1alpha1
    kind: BalancerPolicyTemplate
    metadata:
      name: new-balancerpolicytemplate
    spec:
      policy:
        policyName: Priority
        priorities:
          priorityGroups:
          - priority: 10    # 设置欧拉操作系统节点优先级为10
            requirements:
            - key: os.name  # 节点操作系统标签
              operator: In
              values:
              - EulerOS_2.0_SP9x86_64  # 可能涉及操作系统的小版本号,用户可以根据自身场景,任意添加
          - priority: 100   # 设置HCE2.0操作系统节点优先级为100
            requirements:
            - key: os.name  # 节点操作系统标签
              operator: In
              values:
              - Huawei_Cloud_EulerOS_2.0_x86_64

  2. 创建新BalancerPolicyTemplate资源对象。

    kubectl create -f new-balancerpolicytemplate.yaml

  3. 修改default-balancer对象内容,也可以按需进行新建balancer对象

    kubectl edit balancer default-balancer
    修改内容如下:
    apiVersion: autoscaling.volcano.sh/v1alpha1
    kind: Balancer
    metadata:
      name: default-balancer
    spec:
      balancerPolicyTemplateName: new-balancerpolicytemplate
      targets:
      - namespaceSelector:
          matchExpressions:
            - key: kubernetes.io/metadata.name
              operator: Exists
      weight: 10 

  4. 查看各个Pod的注解中openvessel.io/workload-balancer-score对应的值是否满足预期。

    EulerOS节点上Pod的openvessel.io/workload-balancer-score注解对应值是10;HCE2.0节点上的pod 的openvessel.io/workload-balancer-score注解对应值是100。

配置第三方工作负载应用扩缩容优先级策略

若工作负载不是Deployment类型,而是通过CRD进行管理,则可以通过在高级配置中进行相应设置,使volcano支持该工作负载的扩缩容优先级策略。

  1. 登录CCE控制台,单击集群名称进入集群。
  2. 单击左侧导航栏的“配置中心”,在“调度配置”页面,选择Volcano调度器找到对应的“专家模式”,单击“开始使用”。

  3. 单击左侧导航栏的“插件中心”,在右侧找到Volcano调度器,单击“安装”或“编辑”,并在“参数配置”中设置Volcano调度器配置参数。
  4. 指定需要支持的第三方工作负载类型,JSON示例如下:

    {
        "default_scheduler_conf": {
    ...
        },
        "workload_balancer_score_annotation_key": "",
        "workload_balancer_third_party_types": "apps.kruise.io/v1alpha1/clonesets,apps.kruise.io/v1beta1/statefulsets"
    }
    • workload_balancer_score_annotation_key:指定Pod的分值注解key,目前支持“openvessel.io/workload-balancer-score”或者“controller.kubernetes.io/pod-deletion-cost”,除此之外的值会导致volcano异常退出。
    • workload_balancer_third_party_types:第三方工作负载的group + version + kind拼接成的字符串,多个CRD间以英文逗号分隔。

      例如“apps.kruise.io/v1alpha1/clonesets,apps.kruise.io/v1beta1/statefulsets”,注意kind需要为复数形式,例如 “apps.kruise.io/v1alpha1/cloneset”的非复数形式会导致监听不到对应的CRD。

      如果格式错误,会导致volcano异常退出;如果指定的CRD在集群上不存在,会导致应用扩缩容优先级策略无法正常工作。

    若期望配置的CRD可以按照优先级缩容,则需要管理该CRD的controller可以在缩容时感知到Pod的分值注解,并按照得分控制缩容顺序。

附录:调整Volcano可调度的节点比例

编写volcano-scheduler资源对象。
kubectl edit deploy volcano-scheduler -nkube-system

内容如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: volcano-scheduler
    app.kubernetes.io/managed-by: Helm
    release: cceaddon-volcano
  name: volcano-scheduler
  namespace: kube-system
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: volcano-scheduler
  strategy:
    rollingUpdate:
      maxSurge: 10%
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: volcano-scheduler
        release: cceaddon-volcano
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - volcano-scheduler
              topologyKey: topology.kubernetes.io/zone
            weight: 100
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - volcano-scheduler
            topologyKey: kubernetes.io/hostname
      containers:
      - command:
        - /bin/sh
        - -c
        - /volcano-scheduler --leader-elect=true --lock-object-namespace=kube-system
          --feature-gates=CSIMigrationFlexVolumeFuxi=true,CSIMigrationFlexVolumeFuxiComplete=true,MultiGPUScheduling=true
          --kube-api-qps=200 --alsologtostderr --listen-address=$(MY_POD_IP):8080
          --enable-healthz=true --healthz-address=$(MY_POD_IP):11251 --enable-metrics=true --percentage-nodes-to-find=100
          --scheduler-conf=/volcano.scheduler/default-scheduler.conf -v=3 1>>/var/log/volcano/volcano-scheduler.log

其中--percentage-nodes-to-find=100表示Volcano在进行调度选择时可以遍历集群中的所有节点。