您的位置:首页 > 运维架构 > Docker

Kubernetes Scheduler 调度详解-基于Kubernetes 1.61版本

2017-05-30 21:53 387 查看
源码为k8s v1.6.1版本,github上对应的commit id为b0b7a323cc5a4a2019b2e9520c21c7830b7f708e
本文将对Scheduler的调度算法原理和执行过程进行分析,重点介绍Scheduler算法中预选和优选的相关内容。

1、Kubernetes Scheduler的基本功能
Kubernetes Scheduler的作用就是根据特定的调度算法将pod调度到指定的工作节点(Node)上,这一过程也叫绑定(bind)。Scheduler的输入为需要调度的Pod和可以被调度的节点(Node)的信息,输出为调度算法选择的Node,并将该pod bind到这个Node。



Kubernetes Scheduler中调度算法分为两个阶段:

预选:根据配置的Predicates Policies(默认为DefaultProvider中定义的default predicates policies集合)过滤掉那些不满足这些Policies的的Nodes,剩下的Nodes就作为优选的输入。

优选:根据配置的Priorities Policies(默认为DefaultProvider中定义的default priorities policies集合)给预选后的Nodes进行打分排名,得分最高的Node即作为最适合的Node,该Pod就Bind到这个Node。



2、预选规则详细说明
预先规则主要用于过滤出不符合规则的Node节点,剩下的节点作为优选的输入。在1.6.1版本中预选规则包括:



详细的规则说明:
(1) NoDiskConflict:检查在此主机上是否存在卷冲突。如果这个主机已经挂载了卷,其它同样使用这个卷的Pod不能调度到这个主机上。GCE,Amazon EBS, and Ceph RBD使用的规则如下:GCE允许同时挂载多个卷,只要这些卷都是只读的。Amazon
EBS不允许不同的Pod挂载同一个卷。Ceph RBD不允许任何两个pods分享相同的monitor,match pool和 image。ISCSI与GCE一样,在卷都是只读的情况下,允许挂载两个IQN相同的卷。
(2) NoVolumeZoneConflict:检查给定的zone限制前提下,检查如果在此主机上部署Pod是否存在卷冲突,目前指对PV资源进行检查(NewVolumeZonePredicate对象predicate函数)
(3) MaxEBSVolumeCount:确保已挂载的EBS存储卷不超过设置的最大值。默认值是39。它会检查直接使用的存储卷,和间接使用这种类型存储的PVC。计算不同卷的总目,如果新的Pod部署上去后卷的数目会超过设置的最大值,那么Pod不能调度到这个主机上。
(4) MaxGCEPDVolumeCount:确保已挂载的GCE存储卷不超过设置的最大值。默认值是16。规则同MaxEBSVolumeCount。
(5) MaxAzureDiskVolumeCount:确保已挂载的Azure存储卷不超过设置的最大值。默认值是16。规则同MaxEBSVolumeCount。
(6) CheckNodeMemoryPressure:节点是否已经进入到内存压力状态,如果是则只允许调度内存为0标记的Pod
(7) CheckNodeDiskPressure: 节点是否已经进入到磁盘压力状态,如果是则不调度新的Pod
(8) PodToleratesNodeTaints: Pod是否满足节点容忍的一些条件
(9) MatchInterPodAffinity: 节点亲和性筛选
(10) GeneralPredicates: 包含一些基本的筛选规则,PodFitsResources,PodFitsHostPorts, HostName,MatchNodeSelector

(11) PodFitsResources:检查节点上的空闲资源(CPU,Memory,GPU资源)是否满足Pod的需求
(12) PodFitsHostPorts: 检查Pod内每一个容器所需的HostPort是否已被其它容器占用。如果有所需的HostPort不满足需求,那么Pod不能调度到这个主机上。
(13) 检查主机名称是不是Pod指定的HostName。
(14) 检查主机的标签是否满足Pod的*nodeSelector*属性需求。

3、优选规则详细说明

优选规则对符合需求的主机列表进行打分,最终选择一个分值最高的主机部署Pod。kubernetes用一组优先级函数处理每一个待选的主机。每一个优先级函数会返回一个0-10的分数,分数越高表示主机越“好”,同时每一个函数也会对应一个表示权重的值。最终主机的得分用以下公式计算得出:

finalScoreNode = (weight1 * priorityFunc1) + (weight2 * priorityFunc2) + … + (weightn * priorityFuncn)



详细的规则说明:

(1) SelectorSpreadPriority:对于属于同一个service、replication controller的Pod,尽量分散在不同的主机上。如果指定了区域,则会尽量把Pod分散在不同区域的不同主机上。调度一个Pod的时候,先查找Pod对于的service或者replication
controller,然后查找service或replication controller中已存在的Pod,主机上运行的已存在的Pod越少,主机的打分越高。
(2) LeastRequestedPriority:如果新的pod要分配给一个节点,这个节点的优先级就由节点空闲的那部分与总容量的比值(即(总容量-节点上pod的容量总和-新pod的容量)/总容量)来决定。CPU和memory权重相当,比值最大的节点的得分最高。需要注意的是,这个优先级函数起到了按照资源消耗来跨节点分配pods的作用。计算公式如下:

cpu((capacity – sum(requested)) * 10 / capacity) + memory((capacity – sum(requested)) * 10 / capacity) / 2

(3) BalancedResourceAllocation:尽量选择在部署Pod后各项资源更均衡的机器。*BalancedResourceAllocation*不能单独使用,而且必须和*LeastRequestedPriority*同时使用,它分别计算主机上的cpu和memory的比重,主机的分值由cpu比重和memory比重的“距离”决定。计算公式如下:score
= 10 – abs(cpuFraction-memoryFraction)*10
(4) NodeAffinityPriority:Kubernetes调度中的亲和性机制。Node Selectors(调度时将pod限定在指定节点上),支持多种操作符(In, NotIn, Exists, DoesNotExist, Gt, Lt),而不限于对节点labels的精确匹配。另外,Kubernetes支持两种类型的选择器,一种是“hard(requiredDuringSchedulingIgnoredDuringExecution)”选择器,它保证所选的主机必须满足所有Pod对主机的规则要求。这种选择器更像是之前的nodeselector,在nodeselector的基础上增加了更合适的表现语法。另一种是“soft(preferresDuringSchedulingIgnoredDuringExecution)”选择器,它作为对调度器的提示,调度器会尽量但不保证满足NodeSelector的所有要求。

(5) InterPodAffinityPriority:通过迭代weightedPodAffinityTerm的元素计算和,并且如果对该节点满足相应的PodAffinityTerm,则将“weight”加到和中; 具有最高和的节点是最优选的。
(6) NodePreferAvoidPodsPriority(权重1W):如果Node的Anotation没有设置key-value:scheduler.alpha.kubernetes.io/ preferAvoidPods="...",则该node对该policy的得分就是10分,加上权重10000,那么该node对该policy的得分至少10W分。如果Node的Anotation设置了,scheduler.alpha.kubernetes.io/preferAvoidPods="...",如果该pod对应的Controller是ReplicationController或ReplicaSet,则该node对该policy的得分就是0分。
(7) TaintTolerationPriority:使用Pod中tolerationList与Node节点Taint进行匹配,配对成功的项越多,则得分越低。

另外在优选的调度规则中,有几个未被默认使用的规则:
(1) ImageLocalityPriority:据主机上是否已具备Pod运行的环境来打分。ImageLocalityPriority会判断主机上是否已存在Pod运行所需的镜像,根据已有镜像的大小返回一个0-10的打分。如果主机上不存在Pod所需的镜像,返回0;如果主机上存在部分所需镜像,则根据这些镜像的大小来决定分值,镜像越大,打分就越高。
(2) EqualPriority:EqualPriority是一个优先级函数,它给予所有节点一个相等的权重。
(3) ServiceSpreadingPriority:作用于SelectorSpreadPriority相同,已经被SelectorSpreadPriority替换。
(4) MostRequestedPriority:在ClusterAutoscalerProvider中,替换LeastRequestedPriority,给使用多资源的节点,更高的优先级。

计算公式为:(cpu(10 * sum(requested) / capacity) + memory(10 * sum(requested) / capacity)) / 2
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息