K8s scheduler 调度:预选和优选策略

3b2bdf106f525de047628a76960986e6.gif

1

环境准备

kube-scheduler是k8s的核心组件之一,主要负责Pod的调度。scheduler通过监听kube-apiserver,查询未分配 Node的Pod,根据配置的调度策略,将Pod调度到最优的工作节点上,从而高效、合理地利用k8s集群资源。

在master节点通过ps命令可以查看scheduler的启动参数

root       2035   1930  0 10:17 ?        00:00:11 kube-scheduler --authentication-kubeconfig=/etc/kubernetes/scheduler.conf --authorization-kubeconfig=/etc/kubernetes/scheduler.conf --bind-address=127.0.0.1 --kubeconfig=/etc/kubernetes/scheduler.conf --leader-elect=true

可以为scheduler设置额外配置策略文件,例如

-–policy-config-file=/etc/kubernetes/scheduler-policy.config

如果没有配置则使用的是默认调度算法,默认调度算法分为预选和优选两个阶段:

  • 预选调度:遍历所有目标 Node, 筛选出符合要求的节点。

  • 优选调度:确定最优节点,在第一步的基础上,采用优选策略计算出每个候选节点的积分。评分时会根据评分算法为通过预选的节点进行打分,选择得分最高的节点。例如,资源越充足、负载越小的节点可能具有越高的排名。

2

预选策略


Scheduler默认加载的预选策略有5个,PodFitsPorts、PodFitsResources、PodSelectorMatches(MatchNodeSelector)、PodFitHost(HostName)、NoDiskConflict。


  1. PodFitsPorts:判断 Pod 所用的端口,在备选节点中是否被占用。如果占用返回false ,否则返回true。

  2. PodFitsResources:判断备选节点资源是否满足 Pod 需求。计算备选 Pod 和节点中已存在的 Pod 的所有容器的资源需求(cpu 内存)的总和,获得备选节点的节点资源信息。判定资源不满足则返回false, 如果满足返回true。

  3. PodSelectorMatches:判断备选节点是否包含备选 Pod 的标签选择器指定的标签。如果pod 没有指定 spec.nodeSelector ,则返回true。如果pod 有指定 spec.nodeSelector, 则判断节点是否包含 pod 指定的标签, 如果有就返回true 否则返回 false。

  4. PodFitHost:判断备选 Pod 的 spec.nodeName 所指定的节点名称和备选节点的名称是否一致,一致返回true 否则返回 false。

  5. NoDiskConflict:判断备选 pod 的GcePersistentDisk 或 AwsElasticBlockStore 和备选的节点中已存在的pod 是否存在冲突。读取备选pod的所有volume值(pod.spec.volumes), 对每个Volume执行以下冲突检测,将Volume 和备选节点上的所有 Pod 的每个Volume 进行比较, 如果发现相同的GcePersistentDisk或AwsElasticBlockStore, 则返回false,如果均未发现冲突,返回true。


还可以指定使用 CheckNodeLabelPresence、CheckServiceAffinity等预选策略。


3

优选策略


经过预选策略筛选后得到的Nodes,会来到优选步骤。在这个过程中,会并发的根据每个Priorities Policy分别启动一个goroutine,在每个goroutine中会根据对应的policy实现,遍历所有的预选Nodes,分别进行打分,每个Node每一个Policy的打分为0-10分,0分最低,10分最高。待所有policy对应的goroutine都完成后,根据设置的各个priorities policies的权重weight,对每个node的各个policy的得分进行加权求和作为最终的node的得分。

  1. leastRequestedPriority:计算Pods需要的CPU和内存在当前节点可用资源的百分比,具有最小百分比的节点就是最优,得分计算公式 (cpu(capacity-sum(requested))*10/capacity)+(memory(capacity-sum(requested))*10/capacity)/2

  2. CalculateNodeLabelPriority:判断策略列出的标签在备选节点中存在时,是否选择该节点,如果备选节点上标签在优选策略标签列表中存在,且Presence 为true, 或者备选节点上标签不再优选策略标签列表中且Presence为false, 则备选节点score=10 否则 score=0。

  3. BalanceResourceAllocation:选出资源使用率最均匀的节点,计算备选节点上pod+待分配pod 所占资源(CPU, MEMORY)的总量,计算得分,公式为score=int(10-math.Abs(totalMilliCPU/nodeCpuCapacity-totalMemory/nodeMemoryCapacity)*10)

  4. TaintToleration:将Pod对象的spec.tolerations与节点的taints列表项进行匹配度检查,匹配的条目越多得分越低。

  5. ImageLocalityPriority:根据Node上是否存在一个pod的容器运行所需镜像大小对优先级打分,分值为0-10。遍历全部Node,如果某个Node上pod容器所需的镜像一个都不存在,分值为0;如果Node上存在Pod容器部分所需镜像,则根据这些镜像的大小来决定分值,镜像越大,分值就越高;如果Node上存在pod所需全部镜像,分值为10。

  6. NodePreferAvoidPodsPriority(权重1W):如果节点的 Anotation 没有设置 scheduler.alpha.kubernetes.io/preferAvoidPods,则节点对该 pod 的得分就是10分,加上权重10000,那么该node对该policy的得分至少10W分。设置该anotation的 node 对该 policy 的得分就是0分。

  7. InterPodAffinityPriority:基于亲和性(affinity)和反亲和性(anti-affinity)计算分数。

  8. NodeAffinityPriority:基于节点亲和性计算分数。

4

尾巴

有些k8s集群会配置自定义调度器,以实现默认调度器无法实现的调度能力。如果集群中有自定义调度器和默认调度器,可以通过查看具体pod的yaml文件,查看这个pod使用哪个调度器进行调度。default-scheduler就是使用k8s默认调度器。

8bb63f10709b32f4617fd8c351f1aec1.png

其实大部分情况使用k8s默认调度器已经足够了,上述预选优选策略中有多种可配置的调度策略,例如nodeSelector、nodeAffinity、podAffinity、podAntiAffinity、taint污点、Topology拓扑分布等等,后续文章会一一讲解,欢迎关注~

点个赞

b979b5010a618dfea3be393ae157fba4.gif

再走吧

你可能感兴趣的:(kubernetes,java,docker,运维,容器)