自訂彈性資源優先順序調度是阿里雲提供的彈性調度策略。您可以在應用發布或擴容過程中,自訂資源策略(ResourcePolicy),設定應用執行個體Pod被調度到不同類型節點資源的順序。同時,在縮容過程中按照原調度順序逆序縮容。
請勿在工作負載的標籤選取器(如Deployment的spec.selector.matchLabels)中使用系統保留標籤(如alibabacloud.com/compute-class、alibabacloud.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欄位的預設值修改為False;ignoreTerminatingPod修改為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: 1mselector:聲明ResourcePolicy作用於同一命名空間下label上打了key1=value1的Pod。selector為空白時將對該命名空間下所有Pod生效。strategy:調度策略選擇,目前只支援prefer。units:使用者自訂的調度單元。擴容時,將按照units下資源的順序進行擴容;縮容時,將按照逆序進行縮容。resource:彈性資源的類型,目前支援eci、ecs、elastic以及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:用node的label標識該調度單元下的節點,只對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採用的策略。可選值包括ExceedMax、LackResourceAndNoTerminating、TimeoutOrExceedMax、LackResourceOrExceedMax(預設值)。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.137和cn-beijing.10.0.3.138屬於節點池A, cn-beijing.10.0.6.47和cn-beijing.10.0.6.46屬於節點池B,節點規格均為2核4 GB。基於節點池優先順序調度的具體操作步驟如下:
使用以下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可以從所在叢集的節點管理 > 節點池中擷取。具體操作,請參見建立和管理節點池。
使用以下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建立應用Nginx並查看部署結果。
執行以下命令,建立應用Nginx。
kubectl apply -f nginx.yaml預期輸出:
deployment.apps/nginx created執行以下命令,查看部署結果。
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的節點上。
對Pod進行擴容。
執行以下命令,將Pod擴容到4個。
kubectl scale deployment nginx --replicas 4預期輸出:
deployment.apps/nginx scaled執行以下命令,查看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的節點上。
對Pod進行縮容。
執行以下命令,將Pod從4個副本縮容到2個。
kubectl scale deployment nginx --replicas 2預期輸出:
deployment.apps/nginx scaled執行以下命令,查看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混合調度的具體操作步驟如下:
執行以下命令,對不同付費類型的節點分別打不同的
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使用以下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使用以下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建立應用Nginx並查看部署結果。
執行以下命令,建立應用Nginx。
kubectl apply -f nginx.yaml預期輸出:
deployment.apps/nginx created執行以下命令,查看部署結果。
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被調度到
label為paidtype=subscription的節點上。
對Pod進行擴容。
執行以下命令,將Pod擴容到4個。
kubectl scale deployment nginx --replicas 4預期輸出:
deployment.apps/nginx scaled執行以下命令,查看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>由預期輸出得到,當
label為paidtype=subscription的節點資源不足時,調度到label為paidtype=pay-as-you-go的節點上。執行以下命令,將Pod擴容到6個。
kubectl scale deployment nginx --replicas 6預期輸出:
deployment.apps/nginx scaled執行以下命令,查看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的資源上。
對Pod進行縮容。
執行以下命令,將Pod從6個副本縮容到4個。
kubectl scale deployment nginx --replicas 4預期輸出:
deployment.apps/nginx scaled執行以下命令,查看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。
執行以下命令,將4個副本縮容到2個。
kubectl scale deployment nginx --replicas 2預期輸出:
deployment.apps/nginx scaled執行以下命令,查看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>由預期輸出得到,根據調度節點的逆序,優先縮容位於
label為paidtype=pay-as-you-go節點上的Pod。執行以下命令,查看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>由預期輸出得到,當前只存在
label為paidtype=subscription節點上的Pod。
相關文檔
在ACK叢集中部署服務時,您可以使用容忍度和節點親和性來聲明只使用ECS或ECI彈性資源,或者是在ECS資源不足時自動申請ECI資源。通過配置調度策略,您可以在不同工作負載情境下實現對彈性資源的不同需求。詳細資料,請參見指定ECS和ECI的資源分派。
高可用以及高效能是分布式任務執行過程中的重要要求。在ACK託管叢集Pro版中,您可以通過Kubernetes原生調度語義實現分布式任務的跨可用性區域打散,以達到高可用性區域部署的要求,或者通過Kubernetes原生調度語義實現分布式任務在指定可用性區域中的親和性部署,以達到高效能部署的要求。詳細資料,請參見實現ECI Pod可用性區域打散以及親和調度。