自定义弹性资源优先级调度是阿里云提供的弹性调度策略。您可以在应用发布或扩容过程中,自定义资源策略(ResourcePolicy),设置应用实例Pod被调度到不同类型节点资源的顺序。同时在缩容过程中按照原调度顺序逆序缩容。本文介绍如何使用自定义弹性资源优先级调度功能。
前提条件
- Kubernetes集群为ACK Pro且版本为1.20.11及以上。关于如何升级,请参见升级ACK集群K8s版本。
- 对于不同ACK版本的集群,调度器版本需要满足以下要求。关于调度器各版本支持的功能,请参见kube-scheduler。
ACK版本 | 调度器版本 |
---|
1.20 | 1.20.4-ack-7.0及以上 |
1.22 | 1.22.15-ack-2.0及以上 |
1.24 | v1.24.3-ack-2.0及以上 |
- 需要使用ECI资源时,已部署ack-virtual-node。具体操作,请参见ACK使用ECI。
使用限制
- 本功能与pod-deletion-cost冲突,不能同时使用。关于pod-deletion-cost的更多信息,请参见pod-deletion-cost。
- 本功能暂不支持与使用ECI弹性调度混合使用。关于ECI弹性调度的更多信息,请参见使用ECI弹性调度。
- 本功能目前使用的是BestEffort策略,无法保证一定按照逆序缩容。
- 创建ResourcePolicy时请保证当前无已调度的Pod,否则已调度的Pod将会被最优先缩容。
- 修改ResourcePolicy的策略时,已调度的Pod将按照原ResourcePolicy的顺序进行缩容,新建的Pod将按照更新后ResourcePolicy的顺序进行缩容。
- 使用本功能时,ECI类型的Unit必须作为最后一个Unit使用。
- 本功能暂不支持在自定义优先级调度时触发弹性资源池生产资源。
使用方式
创建ResourcePolicy定义弹性资源优先级:
apiVersion: scheduling.alibabacloud.com/v1alpha1
kind: ResourcePolicy
metadata:
name: xxx
namespace: xxx
spec:
selector:
key1: value1
strategy: prefer
units:
- resource: ecs
nodeSelector:
key2: value2
- resource: ecs
nodeSelector:
key3: value3
- resource: eci
selector
:声明ResourcePolicy作用于同一命名空间下label
上打了key1=value1
的Pod。strategy
:调度策略选择,目前只支持prefer
。units
:用户自定义的调度单元。扩容时,将按照units
下资源的顺序进行扩容;缩容时,将按照逆序进行缩容。resource
:弹性资源的类型,目前支持eci
和ecs
两种类型。nodeSelector
:用node
的label
标识该调度单元下的节点,只对ecs
资源生效。
使用场景示例
场景一:基于节点池优先级调度当您需要部署一个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。