基于集群资源模型的调度
概览
在将应用程序调度到特定集群时,目标集群的资源状态是一个不容忽视的因素。 例如,当集群资源不足以运行给定的实例时,我们希望调度器尽可能避免这种调度行为。 本文将重点介绍 Karmada 如何基于集群资源模型进行实例的调度。
集群资源模型
在调度过程中,karmada-scheduler 现在根据一系列因素做出决策,其中一个因素是集群的资源状态。
现在 Karmada 有两种不同的基于集群资源的调度方式,其中一种是通用的集群模型,另一种是自定义的集群模型。
通用集群资源模型
使用通用集群资源模型
出于上述目的,Karmada在Cluster API 引入了ResourceSummary的概念。
以下给出了一个ResourceSummary的例子:
resourceSummary:
allocatable:
cpu: "4"
ephemeral-storage: 206291924Ki
hugepages-1Gi: "0"
hugepages-2Mi: "0"
memory: 16265856Ki
pods: "110"
allocated:
cpu: 950m
memory: 290Mi
pods: "11"
从上面的例子中,我们可以知道集群的可分配资源和已分配资源。
基于通用集群资源模型的调度
假设在Karmada控制面上注册了三个成员集群,这时过来一个Pod的调度请求。
Member1:
resourceSummary:
allocatable:
cpu: "4"
ephemeral-storage: 206291924Ki
hugepages-1Gi: "0"
hugepages-2Mi: "0"
memory: 16265856Ki
pods: "110"
allocated:
cpu: 950m
memory: 290Mi
pods: "11"
Member2:
resourceSummary:
allocatable:
cpu: "4"
ephemeral-storage: 206291924Ki
hugepages-1Gi: "0"
hugepages-2Mi: "0"
memory: 16265856Ki
pods: "110"
allocated:
cpu: "2"
memory: 290Mi
pods: "11"
Member3:
resourceSummary:
allocatable:
cpu: "4"
ephemeral-storage: 206291924Ki
hugepages-1Gi: "0"
hugepages-2Mi: "0"
memory: 16265856Ki
pods: "110"
allocated:
cpu: "2"
memory: 290Mi
pods: "110"
假设这个Pod的资源请求是500m CPU。 显然,Member1和Member2有足够的资源来运行这个副本,但Member3没有Pod的配额。 考虑到可用资源的数量,调度器更倾向于将Pod调度到member1。
| Cluster | member1 | member2 | member3 |
|---|---|---|---|
| AvailableReplicas | (4 - 0.95) / 0.5 = 6.1 | (4 - 2) / 0.5 = 4 | 0 |
自定义集群资源模型
背景
ResourceSummary 描述了集群的整体可用资源。
但是,ResourceSummary不够精确,它机械地统计所有节点上的资源,而忽略了节点上的碎片资源。例如,一个有 2000 个节点的集群,每个节点上只剩下1核CPU。
从 ResourceSummary 中我们获知集群还有 2000核CPU,但事实上,这个集群甚至无法运行任何需要1核CPU以上的Pod实例。
因此,我们为每个集群引入了“自定义资源模型”的概念,来记录每个节点的资源画像。 Karmada将收集每个集群的节点和pod信息,并经过计算将这个节点被划分为对应等级的合适的资源模型。
启用自定义资源模型
自定义集群资源模型特性开关从Karmada v1.4后处于Beta阶段,并且默认开启。如果你使用Karmada v1.3,你需要在 karmada-scheduler、karmada-aggregated-server 和 karmada-controller-manager 中开启 CustomizedClusterResourceModeling 特性开关。
例如,你可以使用以下命令打开 karmada-controller-manager 中的特性开关。
kubectl --kubeconfig ~/.kube/karmada.config --context karmada-host edit deploy/karmada-controller-manager -nkarmada-system
- command:
- /bin/karmada-controller-manager
- --kubeconfig=/etc/kubeconfig
- --bind-address=0.0.0.0
- --cluster-status-update-frequency=10s
- --secure-port=10357
- --feature-gates=CustomizedClusterResourceModeling=true
- --v=4
在开启特性开关后,当集群注册到 Karmada 控制面时,Karmada会自动为集群设置一个通用的资源模型。你可以在 cluster.spec 中看到它。
默认的资源模型如下:
resourceModels:
- grade: 0
ranges:
- max: "1"
min: "0"
name: cpu
- max: 4Gi
min: "0"
name: memory
- grade: 1
ranges:
- max: "2"
min: "1"
name: cpu
- max: 16Gi
min: 4Gi
name: memory
- grade: 2
ranges:
- max: "4"
min: "2"
name: cpu
- max: 32Gi
min: 16Gi
name: memory
- grade: 3
ranges:
- max: "8"
min: "4"
name: cpu
- max: 64Gi
min: 32Gi
name: memory
- grade: 4
ranges:
- max: "16"
min: "8"
name: cpu
- max: 128Gi
min: 64Gi
name: memory
- grade: 5
ranges:
- max: "32"
min: "16"
name: cpu
- max: 256Gi
min: 128Gi
name: memory
- grade: 6
ranges:
- max: "64"
min: "32"
name: cpu
- max: 512Gi
min: 256Gi
name: memory
- grade: 7
ranges:
- max: "128"
min: "64"
name: cpu
- max: 1Ti
min: 512Gi
name: memory
- grade: 8
ranges:
- max: "9223372036854775807"
min: "128"
name: cpu
- max: "9223372036854775807"
min: 1Ti
name: memory
自定义你的集群资源模型
在某些情况下,默认的集群资源模型可能与你的集群不相匹配。你可以调整集群资源模型的细粒度,以便更好地向集群下发资源。 例如,你可以使用以下命令编辑 member1 的集群资源模型。
kubectl --kubeconfig ~/.kube/karmada.config --context karmada-apiserver edit cluster/member1
自定义资源模型应满足以下要求:
- 每个模型的等级不应该是相同的。
- 每个模型中资源类型的数量应该相同。
- 目前只支持 cpu, memory, storage, ephemeral-storage四种资源类型。
- 每个资源的最大值必须大于最小值。
- 第一个模型中每个资源的最小值应为 0。
- 最后一个模型中每个资源的最大值应为 MaxInt64。
- 每个模型的资源类型应该相同。
- 从低等级到高等级的模型,资源的范围必须连续且不重叠。
例如:以下给出了一个自定义的集群资源模型:
resourceModels:
- grade: 0
ranges:
- max: "1"
min: "0"
name: cpu
- max: 4Gi
min: "0"
name: memory
- grade: 1
ranges:
- max: "2"
min: "1"
name: cpu
- max: 16Gi
min: 4Gi
name: memory
- grade: 2
ranges:
- max: "9223372036854775807"
min: "2"
name: cpu
- max: "9223372036854775807"
min: 16Gi
name: memory
上述是一个有三个等级的集群资源模型,每个等级分别定义了CPU和内存这两种资源的资源范围。这时如果一个节点的剩余可用资源为0.5核CPU和2Gi内存,则会被划分为0级的资源模型。如果这个节点的剩余可用资源为1.5核CPU和10Gi内存,则会被划分为1级。