自訂彈性資源優先順序調度是阿里雲提供的彈性調度策略。您可以在應用發布或擴容過程中,自訂資源策略(ResourcePolicy),設定應用執行個體Pod被調度到不同類型節點資源的順序。同時,在縮容過程中按照原調度順序逆序縮容。
自調度器版本v1.x.x-aliyun-6.4開始,自訂彈性資源優先順序功能的ignorePreviousPod欄位的預設值將修改為False,ignoreTerminatingPod欄位的預設值將修改為True。涉及這些欄位的存量ResourcePolicy不受影響,後續更新也不受影響。
前提條件
Kubernetes叢集為ACK Pro且版本為1.20.11及以上。關於如何升級,請參見升級ACK叢集K8s版本。
對於不同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。
使用限制
本功能與pod-deletion-cost衝突,不能同時使用。關於pod-deletion-cost的更多資訊,請參見pod-deletion-cost。
本功能暫不支援與使用ECI彈性調度混合使用。關於ECI彈性調度的更多資訊,請參見使用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:
ignorePreviousPod: false
ignoreTerminatingPod: true
matchLabelKeys:
- pod-template-hash
preemptPolicy: AfterAllUnits
selector:
key1: value1
strategy: prefer
units:
- nodeSelector:
unit: first
resource: ecs
- nodeSelector:
unit: second
max: 10
resource: ecs
- resource: eci
whenTryNextUnits:
policy: TimeoutOrExceedMax
timeout: 1m
selector
:聲明ResourcePolicy作用於同一命名空間下label
上打了key1=value1
的Pod。selector
為空白時將對該命名空間下所有Pod生效。strategy
:調度策略選擇,目前只支援prefer
。units
:使用者自訂的調度單元。擴容時,將按照units
下資源的順序進行擴容;縮容時,將按照逆序進行縮容。resource
:彈性資源的類型,目前支援eci
、ecs
以及elastic
三種類型。elastic
在叢集版本為1.24以上,且調度器版本為6.4.3及以上版本可用。nodeSelector
:用node
的label
標識該調度單元下的節點,只對ecs
資源生效。max
(調度器為5.0版本及以上可用):在本調度單元中最多能調度的Pod的副本數。
preemptPolicy
(調度器為6.1版本及以上可用):當ResourcePolicy中存在多個unit
時,是否允許ResourcePolicy在每個Unit調度失敗時嘗試搶佔。BeforeNextUnit表示調度器將在每個Unit調度失敗時嘗試搶佔,AfterAllUnits表示ResourcePolicy只在最後一個Unit調度失敗時嘗試搶佔。預設為AfterAllUnits。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未設定,或當前Unit中的Pod數量大於等於設定的Max值,允許Pod使用下一級資源。該策略可以與自動調整以及ECI配合,達到優先嘗試節點池自動調整的效果。重要請注意,如果自動調整節點池長時間無法彈出節點,此策略可能導致Pod Pending。
當前由於Cluster Autoscaler未感知ResourcePolicy的Max限制,實際彈出的執行個體數可能會多於設定的Max值。該問題將在後續版本中進行最佳化。
TimeoutOrExceedMax
:當滿足以下條件之一:當前Unit的Max已設定且Unit中的Pod數量小於設定的Max值時;
當前Unit的Max未設定,且當前Unit的Type為
elastic
;
若當前Unit資源不足以調度Pod,則在當前Unit中等待,等待時間的最大長度為
timeout
。該策略可以與自動調整以及ECI配合,達到優先嘗試節點池自動調整,並且在逾時後自動使用eci的效果。- 重要
請注意,若Timeout期間內彈出節點,在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
:當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可用性區域打散以及親和調度。