全部產品
Search
文件中心

Container Service for Kubernetes:自訂彈性資源優先順序調度

更新時間:Nov 07, 2025

自訂彈性資源優先順序調度是阿里雲提供的彈性調度策略。您可以在應用發布或擴容過程中,自訂資源策略(ResourcePolicy),設定應用執行個體Pod被調度到不同類型節點資源的順序。同時,在縮容過程中按照原調度順序逆序縮容。

警告

請勿在工作負載的標籤選取器(如Deployment的spec.selector.matchLabels)中使用系統保留標籤(如alibabacloud.com/compute-classalibabacloud.com/compute-qos)。這些標籤可能在自訂優先順序調度期間被系統修改,導致控制器頻繁重建Pod,影響應用穩定性。

前提條件

  • 已建立1.20.11及以上版本的ACK託管叢集Pro版。如需升級,請參見手動升級叢集

  • 對於不同ACK版本的叢集,調度器版本需要滿足以下要求。關於調度器各版本支援的功能,請參見kube-scheduler

    ACK版本

    調度器版本

    1.20

    v1.20.4-ack-7.0及以上

    1.22

    v1.22.15-ack-2.0及以上

    1.24及以上

    所有版本均支援

  • 需要使用ECI資源時,需已部署ack-virtual-node。具體操作,請參見ACK使用ECI

注意事項

  • 自調度器版本v1.x.x-aliyun-6.4開始,自訂彈性資源優先順序的ignorePreviousPod欄位的預設值修改為FalseignoreTerminatingPod修改為True。涉及這些欄位的存量ResourcePolicy不受影響,後續更新也不受影響。

  • 本功能與pod-deletion-cost衝突,不能同時使用。

  • 本功能暫不支援與通過ElasticResource實現ECI彈性調度混合使用。

  • 本功能目前使用BestEffort策略,無法保證一定按照逆序縮容。

  • max欄位僅在叢集版本為1.22及以上,且調度器版本為5.0及以上的版本中開啟。

  • 與彈性節點池同時使用時,可能導致彈性節點池無效彈出節點。使用時請將彈性節點池包含在某個Unit中,且彈性節點池的Unit不要設定max欄位。

  • 若您的調度器為5.0版本以下或叢集版本為1.20及以下,請注意在ResourcePolicy建立前存在的Pod會在縮容時最先被縮容。

  • 若您的調度器為6.1版本以下或叢集版本為1.20及以下,在與ResourcePolicy關聯的Pod未完全刪除時,請不要對ResourcePolicy進行修改。

使用方式

建立ResourcePolicy定義彈性資源優先順序:

apiVersion: scheduling.alibabacloud.com/v1alpha1
kind: ResourcePolicy
metadata:
  name: test
  namespace: default
spec:
  selector:
    key1: value1
  strategy: prefer
  units:
  - nodeSelector:
      unit: first
    podLabels:
      key1: value1
    podAnnotations:
      key1: value1
    resource: ecs
  - nodeSelector:
      unit: second
    max: 10
    resource: ecs
  - resource: eci
  # Optional, Advanced Configurations
  preemptPolicy: AfterAllUnits
  ignorePreviousPod: false
  ignoreTerminatingPod: true
  matchLabelKeys:
  - pod-template-hash
  whenTryNextUnits:
    policy: TimeoutOrExceedMax
    timeout: 1m
  • selector:聲明ResourcePolicy作用於同一命名空間下label上打了key1=value1的Pod。selector為空白時將對該命名空間下所有Pod生效。

  • strategy:調度策略選擇,目前只支援prefer

  • units:使用者自訂的調度單元。擴容時,將按照units下資源的順序進行擴容;縮容時,將按照逆序進行縮容。

    • resource:彈性資源的類型,目前支援eciecselastic以及acs四種類型。elastic在叢集版本為1.24以上,且調度器版本為6.4.3及以上版本可用。acs在叢集版本為1.26以上,且調度器版本為6.7.1及以上版本可用。

      說明

      elastic即將廢棄。建議通過PodLabels中的k8s.aliyun.com/resource-policy-wait-for-ecs-scaling: "true"的方式使用自動調整節點池。

      說明

      acs類型將會預設為Pod添加alibabacloud.com/compute-class: default以及alibabacloud.com/compute-class: general-purpose的標籤。您可以通過在PodLabels中聲明不同的Value來對預設值進行覆蓋。當PodAnnotation聲明了alpha.alibabacloud.com/compute-qos-strategy時,將不會預設添加alibabacloud.com/compute-class: default

      說明

      acs以及eci類型將會預設為Pod添加虛擬節點的汙點容忍,Pod無需額外配置汙點容忍即可被調度到虛擬節點上。

      重要

      在調度器6.8.3以下的版本中,不支援同時使用多個acs的Unit。

    • nodeSelector:用nodelabel標識該調度單元下的節點,只對ecs資源生效。

    • max(調度器為5.0版本及以上可用):在本調度單元中最多能調度的Pod的副本數。

    • maxResources(調度器為6.9.5版本及以上可用):在本調度單元中最多能調度的Pod的資源量。

    • podAnnotations:類型是map[string]string{},配置在podAnnotations中Key-Value將會由調度器更新到Pod上。在進行該Unit中的Pod數量統計時只有帶有這些Key-Value的Pod會被統計。

    • podLabels:類型是map[string]string{},配置在podLabels中Key-Value將會由調度器更新到Pod上。在進行該Unit中的Pod數量統計時只有帶有這些Key-Value的Pod會被統計。

      說明

      當Unit的PodLabels中包含k8s.aliyun.com/resource-policy-wait-for-ecs-scaling: "true",或當前Unit的Pod數量低於設定的Max值時。Scheduler會讓Pod在當前的Unit中等待。等待的時間可以在whenTryNextUnits中設定。並且k8s.aliyun.com/resource-policy-wait-for-ecs-scaling: "true"不會被更新到Pod上。統計Pod數量時也不要求Pod上帶有該標籤。

      說明

      ResourcePolicy與自動調整一起使用時,需要與即時彈性一起使用。cluster-autoscaler可能觸發錯誤的節點池伸縮。

  • preemptPolicy(調度器為6.1版本及以上可用,該參數對ACS不生效):當ResourcePolicy中存在多個unit時,是否允許ResourcePolicy在每個Unit調度失敗時嘗試搶佔。BeforeNextUnit表示調度器將在每個Unit調度失敗時嘗試搶佔,AfterAllUnits表示ResourcePolicy只在最後一個Unit調度失敗時嘗試搶佔。預設為AfterAllUnits。

    您可以通過配置ACK Scheduler參數,開啟搶佔
  • ignorePreviousPod(調度器為6.1版本及以上可用):需要與units中的max一起使用。該值為true時,在進行Pod數量統計時將忽略ResourcePolicy建立之前已經調度的Pod。

  • ignoreTerminatingPod(調度器為6.1版本及以上可用):需要與units中的max一起使用。該值為true時,在進行Pod數量統計時將忽略處於Terminating狀態的Pod。

  • matchLabelKeys(調度器為6.2版本及以上可用):需要與units中的max一起使用,Pod會根據自身Label的值進行分組,不同分組的Pod將適用於不同的max計數。當使用該功能時,若Pod上缺少任務matchLabelKeys中聲明的Label,Pod將被拒絕調度。

  • whenTryNextUnits(叢集版本1.24及以上,調度器為6.4版本及以上可用):描述Pod在何種情況下被允許使用後續Unit中的資源。

    • policy:代表Pod採用的策略。可選值包括ExceedMaxLackResourceAndNoTerminatingTimeoutOrExceedMaxLackResourceOrExceedMax(預設值)。

      • ExceedMax:若當前Unit的Max以及MaxResources未設定,或當前Unit中的Pod數量大於等於設定的Max值(或當前Unit中的已使用資源量加上當前Pod超過MaxResource),允許Pod使用下一級資源。該策略可以與自動調整以及ECI配合,達到優先嘗試節點池自動調整的效果。

        重要
        • 請注意,如果自動調整節點池長時間無法彈出節點,此策略可能導致Pod處於Pending狀態。

        • 當前由於Cluster Autoscaler未感知ResourcePolicy的Max限制,實際彈出的執行個體數可能會多於設定的Max值。該問題將在後續版本中進行最佳化。

      • TimeoutOrExceedMax:當滿足以下條件之一:

        • 當前Unit的Max已設定且Unit中的Pod數量小於設定的Max值或MaxResources已設定且已調度資源量加上當前調度Pod資源量小於設定的MaxResources時;

        • 當前Unit的Max未設定,且當前Unit的PodLabels中包含k8s.aliyun.com/resource-policy-wait-for-ecs-scaling: "true"

        若當前Unit資源不足以調度Pod,則在當前Unit中等待,等待時間的最大長度為timeout。該策略可以與自動調整以及ECI配合,達到優先嘗試節點池自動調整,並且在逾時後自動使用ECI的效果。

        重要

        請注意,若Timeout期間內彈出節點,且節點未達到Ready狀態,且Pod未容忍NotReady的汙點,則Pod仍然會被調度到ECI上。

      • LackResourceOrExceedMax:若當前Unit中的Pod數量大於等於設定的Max值,或當前Unit中已沒有多餘資源,允許Pod使用下一級資源。該策略為預設策略,適合大部分情境的基本需求。

      • LackResourceAndNoTerminating:若當前Unit中的Pod數量大於等於設定的Max值,或當前Unit中已沒有多餘資源,並且當前Unit中無處於Terminating狀態的Pod時,允許Pod使用下一級資源。該策略適合與變換策略配置使用,以確保在變換時不會由於Terminating導致新Pod滾動到後續Unit上的效果。

    • timeout(ACS Unit不支援timeout參數,只受到Max限制):當policy為timeoutOrExceedMaxPolicy時,該欄位可以被用來描述逾時時間長度,當該欄位為空白值時,我們將此值視為15分鐘。

使用情境樣本

情境一:基於節點池優先順序調度

當您需要部署一個Deployment,此時叢集有兩個節點池,一個是節點池A,一個是節點池B。您希望優先調度節點池A,資源不足時調度節點池B。當進行縮容時,優先縮容在節點池B中的Pod,然後縮容節點池A中的Pod。如下樣本中,cn-beijing.10.0.3.137cn-beijing.10.0.3.138屬於節點池A, cn-beijing.10.0.6.47cn-beijing.10.0.6.46屬於節點池B,節點規格均為2核4 GB。基於節點池優先順序調度的具體操作步驟如下:

  1. 使用以下YAML內容,建立ResourcePolicy自訂節點池調度順序。

    apiVersion: scheduling.alibabacloud.com/v1alpha1
    kind: ResourcePolicy
    metadata:
      name: nginx
      namespace: default
    spec:
      selector:
        app: nginx # 此處要與後續建立的Pod的label相關聯。
      strategy: prefer
      units:
      - resource: ecs
        nodeSelector:
          alibabacloud.com/nodepool-id: np7ec79f2235954e879de07b780058****
      - resource: ecs
        nodeSelector:
          alibabacloud.com/nodepool-id: npab2df797738644e3a7b7cbf532bb****
    說明

    節點池ID可以從所在叢集的節點管理 > 節點池中擷取。具體操作,請參見建立和管理節點池

  2. 使用以下YAML內容建立Deployment,部署2個Pod。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          name: nginx
          labels:
            app: nginx # 此處要與上一步建立的ResourcePolicy的selector相關聯。
        spec:
          containers:
          - name: nginx
            image: nginx
            resources:
              limits:
                cpu: 2
              requests:
                cpu: 2
  3. 建立應用Nginx並查看部署結果。

    1. 執行以下命令,建立應用Nginx。

      kubectl apply -f nginx.yaml

      預期輸出:

      deployment.apps/nginx created
    2. 執行以下命令,查看部署結果。

      kubectl get pods -o wide

      預期輸出:

      NAME                    READY   STATUS    RESTARTS   AGE   IP               NODE                    NOMINATED NODE   READINESS GATES
      nginx-9cdf7bbf9-b****   1/1     Running   0          17s   172.29.112.216   cn-beijing.10.0.3.137   <none>           <none>
      nginx-9cdf7bbf9-k****   1/1     Running   0          17s   172.29.113.24    cn-beijing.10.0.3.138   <none>           <none>

      由預期輸出得到,前兩個Pod被調度在節點池A的節點上。

  4. 對Pod進行擴容。

    1. 執行以下命令,將Pod擴容到4個。

      kubectl scale deployment nginx --replicas 4                      

      預期輸出:

      deployment.apps/nginx scaled
    2. 執行以下命令,查看Pod狀態。

      kubectl get pods -o wide

      預期輸出:

      NAME                    READY   STATUS    RESTARTS   AGE    IP               NODE                    NOMINATED NODE   READINESS GATES
      nginx-9cdf7bbf9-b****   1/1     Running   0          101s   172.29.112.216   cn-beijing.10.0.3.137   <none>           <none>
      nginx-9cdf7bbf9-k****   1/1     Running   0          101s   172.29.113.24    cn-beijing.10.0.3.138   <none>           <none>
      nginx-9cdf7bbf9-m****   1/1     Running   0          18s    172.29.113.156   cn-beijing.10.0.6.47    <none>           <none>
      nginx-9cdf7bbf9-x****   1/1     Running   0          18s    172.29.113.89    cn-beijing.10.0.6.46    <none>           <none>

      由預期輸出得到,當節點池A的節點資源不足時,調度到節點池B的節點上。

  5. 對Pod進行縮容。

    1. 執行以下命令,將Pod從4個副本縮容到2個。

      kubectl scale deployment nginx --replicas 2

      預期輸出:

      deployment.apps/nginx scaled
    2. 執行以下命令,查看Pod狀態。

      kubectl get pods -o wide

      預期輸出:

      NAME                    READY   STATUS        RESTARTS   AGE     IP               NODE                    NOMINATED NODE   READINESS GATES
      nginx-9cdf7bbf9-b****   1/1     Running       0          2m41s   172.29.112.216   cn-beijing.10.0.3.137   <none>           <none>
      nginx-9cdf7bbf9-k****   1/1     Running       0          2m41s   172.29.113.24    cn-beijing.10.0.3.138   <none>           <none>
      nginx-9cdf7bbf9-m****   0/1     Terminating   0          78s     172.29.113.156   cn-beijing.10.0.6.47    <none>           <none>
      nginx-9cdf7bbf9-x****   0/1     Terminating   0          78s     172.29.113.89    cn-beijing.10.0.6.46    <none>           <none>

      由預期輸出得到,根據調度的逆序,優先縮容在節點池B中的Pod。

情境二:ECS和ECI混合調度

當您需要部署一個Deployment,此時叢集中有3種類型的資源,分別是訂用帳戶的ECS、隨用隨付的ECS和彈性執行個體ECI。為了降低資源使用成本,您希望部署的服務優先調度順序依次為:訂用帳戶的ECS、隨用隨付的ECS、彈性執行個體ECI。同時在服務縮容時優先刪除ECI上的Pod,釋放ECI的節點資源,然後刪除隨用隨付的ECS上的Pod,最後刪除訂用帳戶的ECS上的Pod。樣本節點為2核4 GB,ECS和ECI混合調度的具體操作步驟如下:

  1. 執行以下命令,對不同付費類型的節點分別打不同的label(此處也可以通過節點池的功能自動標識label)。

    kubectl label node cn-beijing.10.0.3.137 paidtype=subscription
    kubectl label node cn-beijing.10.0.3.138 paidtype=subscription
    kubectl label node cn-beijing.10.0.6.46 paidtype=pay-as-you-go
    kubectl label node cn-beijing.10.0.6.47 paidtype=pay-as-you-go
  2. 使用以下YAML內容,建立ResourcePolicy自訂節點池調度順序。

    apiVersion: scheduling.alibabacloud.com/v1alpha1
    kind: ResourcePolicy
    metadata:
      name: nginx
      namespace: default
    spec:
      selector:
        app: nginx # 此處要與後續建立的Pod的label相關聯。
      strategy: prefer
      units:
      - resource: ecs
        nodeSelector:
          paidtype: subscription
      - resource: ecs
        nodeSelector:
          paidtype: pay-as-you-go
      - resource: eci
  3. 使用以下YAML內容建立Deployment,部署2個Pod。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          name: nginx
          labels:
            app: nginx # 此處要上一步建立的ResourcePolicy的selector相關聯。
        spec:
          containers:
          - name: nginx
            image: nginx
            resources:
              limits:
                cpu: 2
              requests:
                cpu: 2
  4. 建立應用Nginx並查看部署結果。

    1. 執行以下命令,建立應用Nginx。

      kubectl apply -f nginx.yaml

      預期輸出:

      deployment.apps/nginx created
    2. 執行以下命令,查看部署結果。

      kubectl get pods -o wide

      預期輸出:

      NAME                    READY   STATUS    RESTARTS   AGE   IP               NODE                    NOMINATED NODE   READINESS GATES
      nginx-9cdf7bbf9-b****   1/1     Running   0          66s   172.29.112.215   cn-beijing.10.0.3.137   <none>           <none>
      nginx-9cdf7bbf9-r****   1/1     Running   0          66s   172.29.113.23    cn-beijing.10.0.3.138   <none>           <none>

      由預期輸出得到,前兩個Pod被調度到labelpaidtype=subscription的節點上。

  5. 對Pod進行擴容。

    1. 執行以下命令,將Pod擴容到4個。

      kubectl scale deployment nginx --replicas 4

      預期輸出:

      deployment.apps/nginx scaled
    2. 執行以下命令,查看Pod狀態。

      kubectl get pods -o wide

      預期輸出:

      NAME                    READY   STATUS    RESTARTS   AGE     IP               NODE                    NOMINATED NODE   READINESS GATES
      nginx-9cdf7bbf9-4****   1/1     Running   0          16s     172.29.113.155   cn-beijing.10.0.6.47    <none>           <none>
      nginx-9cdf7bbf9-b****   1/1     Running   0          3m48s   172.29.112.215   cn-beijing.10.0.3.137   <none>           <none>
      nginx-9cdf7bbf9-f****   1/1     Running   0          16s     172.29.113.88    cn-beijing.10.0.6.46    <none>           <none>
      nginx-9cdf7bbf9-r****   1/1     Running   0          3m48s   172.29.113.23    cn-beijing.10.0.3.138   <none>           <none>

      由預期輸出得到,當labelpaidtype=subscription的節點資源不足時,調度到labelpaidtype=pay-as-you-go的節點上。

    3. 執行以下命令,將Pod擴容到6個。

      kubectl scale deployment nginx --replicas 6

      預期輸出:

      deployment.apps/nginx scaled
    4. 執行以下命令,查看Pod狀態。

      kubectl get pods -o wide

      預期輸出:

      NAME                    READY   STATUS    RESTARTS   AGE     IP               NODE                           NOMINATED NODE   READINESS GATES
      nginx-9cdf7bbf9-4****   1/1     Running   0          3m10s   172.29.113.155   cn-beijing.10.0.6.47           <none>           <none>
      nginx-9cdf7bbf9-b****   1/1     Running   0          6m42s   172.29.112.215   cn-beijing.10.0.3.137          <none>           <none>
      nginx-9cdf7bbf9-f****   1/1     Running   0          3m10s   172.29.113.88    cn-beijing.10.0.6.46           <none>           <none>
      nginx-9cdf7bbf9-r****   1/1     Running   0          6m42s   172.29.113.23    cn-beijing.10.0.3.138          <none>           <none>
      nginx-9cdf7bbf9-s****   1/1     Running   0          36s     10.0.6.68        virtual-kubelet-cn-beijing-j   <none>           <none>
      nginx-9cdf7bbf9-v****   1/1     Running   0          36s     10.0.6.67        virtual-kubelet-cn-beijing-j   <none>           <none>

      由預期輸出得到,ECS上的資源不足,Pod被調度到ECI的資源上。

  6. 對Pod進行縮容。

    1. 執行以下命令,將Pod從6個副本縮容到4個。

      kubectl scale deployment nginx --replicas 4

      預期輸出:

      deployment.apps/nginx scaled
    2. 執行以下命令,查看Pod狀態。

      kubectl get pods -o wide

      預期輸出:

      NAME                    READY   STATUS        RESTARTS   AGE     IP               NODE                           NOMINATED NODE   READINESS GATES
      nginx-9cdf7bbf9-4****   1/1     Running       0          4m59s   172.29.113.155   cn-beijing.10.0.6.47           <none>           <none>
      nginx-9cdf7bbf9-b****   1/1     Running       0          8m31s   172.29.112.215   cn-beijing.10.0.3.137          <none>           <none>
      nginx-9cdf7bbf9-f****   1/1     Running       0          4m59s   172.29.113.88    cn-beijing.10.0.6.46           <none>           <none>
      nginx-9cdf7bbf9-r****   1/1     Running       0          8m31s   172.29.113.23    cn-beijing.10.0.3.138          <none>           <none>
      nginx-9cdf7bbf9-s****   1/1     Terminating   0          2m25s   10.0.6.68        virtual-kubelet-cn-beijing-j   <none>           <none>
      nginx-9cdf7bbf9-v****   1/1     Terminating   0          2m25s   10.0.6.67        virtual-kubelet-cn-beijing-j   <none>           <none>

      由預期輸出得到,根據調度節點的逆序,優先縮容在ECI上的Pod。

    3. 執行以下命令,將4個副本縮容到2個。

      kubectl scale deployment nginx --replicas 2

      預期輸出:

      deployment.apps/nginx scaled
    4. 執行以下命令,查看Pod狀態。

      kubectl get pods -o wide

      預期輸出:

      NAME                    READY   STATUS        RESTARTS   AGE     IP               NODE                    NOMINATED NODE   READINESS GATES
      nginx-9cdf7bbf9-4****   0/1     Terminating   0          6m43s   172.29.113.155   cn-beijing.10.0.6.47    <none>           <none>
      nginx-9cdf7bbf9-b****   1/1     Running       0          10m     172.29.112.215   cn-beijing.10.0.3.137   <none>           <none>
      nginx-9cdf7bbf9-f****   0/1     Terminating   0          6m43s   172.29.113.88    cn-beijing.10.0.6.46    <none>           <none>
      nginx-9cdf7bbf9-r****   1/1     Running       0          10m     172.29.113.23    cn-beijing.10.0.3.138   <none>           <none>

      由預期輸出得到,根據調度節點的逆序,優先縮容位於labelpaidtype=pay-as-you-go節點上的Pod。

    5. 執行以下命令,查看Pod狀態。

      kubectl get pods -o wide

      預期輸出:

      NAME                    READY   STATUS    RESTARTS   AGE   IP               NODE                    NOMINATED NODE   READINESS GATES
      nginx-9cdf7bbf9-b****   1/1     Running   0          11m   172.29.112.215   cn-beijing.10.0.3.137   <none>           <none>
      nginx-9cdf7bbf9-r****   1/1     Running   0          11m   172.29.113.23    cn-beijing.10.0.3.138   <none>           <none>

      由預期輸出得到,當前只存在labelpaidtype=subscription節點上的Pod。

相關文檔

  • 在ACK叢集中部署服務時,您可以使用容忍度和節點親和性來聲明只使用ECS或ECI彈性資源,或者是在ECS資源不足時自動申請ECI資源。通過配置調度策略,您可以在不同工作負載情境下實現對彈性資源的不同需求。詳細資料,請參見指定ECS和ECI的資源分派

  • 高可用以及高效能是分布式任務執行過程中的重要要求。在ACK託管叢集Pro版中,您可以通過Kubernetes原生調度語義實現分布式任務的跨可用性區域打散,以達到高可用性區域部署的要求,或者通過Kubernetes原生調度語義實現分布式任務在指定可用性區域中的親和性部署,以達到高效能部署的要求。詳細資料,請參見實現ECI Pod可用性區域打散以及親和調度