扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
本篇文章为大家展示了如何进行Kubernetes Scheduler原理解析,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。
10年建站经验, 成都做网站、成都网站设计客户的见证与正确选择。创新互联提供完善的营销型网页建站明细报价表。后期开发更加便捷高效,我们致力于追求更美、更快、更规范。
本文是对Kubernetes Scheduler的算法解读和原理解析,重点介绍了预选(Predicates)和优选(Priorities)步骤的原理,并介绍了默认配置的Default Policies。接下来,我会分析Kubernetes Scheduler的源码,窥探其具体的实现细节以及如何开发一个Policy,见我下片博文吧。
Kubernetes Scheduler是Kubernetes Master的一个组件,通常与API Server和Controller Manager组件部署在一个节点,共同组成Master的三剑客。
一句话概括Scheduler的功能:将PodSpec.NodeName为空的Pods逐个地,经过预选(Predicates)和优选(Priorities)两个步骤,挑选最合适的Node作为该Pod的Destination。
展开这两个步骤,就是Scheduler的算法描述:
预选:根据配置的Predicates Policies(默认为DefaultProvider中定义的default predicates policies集合)过滤掉那些不满足这些Policies的的Nodes,剩下的Nodes就作为优选的输入。
优选:根据配置的Priorities Policies(默认为DefaultProvider中定义的default priorities policies集合)给预选后的Nodes进行打分排名,得分最高的Node即作为最适合的Node,该Pod就Bind到这个Node。
如果经过优选将Nodes打分排名后,有多个Nodes并列得分最高,那么scheduler将随机从中选择一个Node作为目标Node。
因此整个schedule过程,算法本身的逻辑是非常简单的,关键在这些Policies的逻辑,下面我们就来看看Kubernetes的Predicates and Priorities Policies。
Predicates Policies就是提供给Scheduler用来过滤出满足所定义条件的Nodes,并发的(最多16个goroutine)对每个Node启动所有Predicates Policies的遍历Filter,看其是否都满足配置的Predicates Policies,若有一个Policy不满足,则直接被淘汰。
注意:这里的并发goroutine number为All Nodes number,但最多不能超过16个,由一个queue控制。
Kubernetes提供了以下Predicates Policies的定义,你可以在kube-scheduler启动参数中添加--policy-config-file
来指定要运用的Policies集合,比如:
{ "kind" : "Policy", "apiVersion" : "v1", "predicates" : [ {"name" : "PodFitsPorts"}, {"name" : "PodFitsResources"}, {"name" : "NoDiskConflict"}, {"name" : "NoVolumeZoneConflict"}, {"name" : "MatchNodeSelector"}, {"name" : "HostName"} ], "priorities" : [ ... ] }
NodeiskConflict:评估一个pod是否能够容纳它请求的卷以及已经装载的卷。当前支持的卷有:AWS EBS、GCE PD、ISCSI和Ceph RBD。仅检查这些受支持类型的持久卷声明。直接添加到POD的持久卷不进行评估,也不受此策略的约束。
NoVolumeZoneConflict:在给定区域限制的情况下,评估节点上是否存在pod请求的卷。
PodFitsResources:检查可用资源(CPU和内存)是否满足Pod的要求。可用资源由容量减去节点上所有POD的请求之和来衡量。要了解更多关于Kubernetes中资源QoS的信息,请查看QoS建议。
PODFITSHOSPORTS:检查Pod所需的任何主机端口是否已在节点上被占用。
HostName:过滤掉除PodSpec的NodeName字段中指定的节点之外的所有节点。
MatchNodeSelector:检查节点的标签是否与Pod的nodeSelector字段中指定的标签匹配,并且从Kubernetes v1.2开始,还与scheduler.alpha.Kubernetes.io/affinity Pod注释(如果存在)匹配。有关这两方面的更多详细信息,请参见此处。
MaxEBSVolumeCount:确保连接的ElasticBlockStore卷的数量不超过最大值(默认情况下为39,因为Amazon建议最大值为40,其中一个保留给根卷——请参阅Amazon的文档)。可通过设置KUBE_MAX_PD_VOLS环境变量来控制最大值。
MaxGCEPDVolumeCount:确保连接的GCE PersistentDisk卷数不超过最大值(默认情况下为16,这是GCE允许的最大值)。可通过设置KUBE_MAX_PD_VOLS环境变量来控制最大值。
CheckNodeMemoryPressure:检查是否可以在报告内存压力条件的节点上调度pod。目前,在内存紧张的节点上不应放置BestEffort,因为它会被kubelet自动逐出。
CheckNodeDiskPressure:检查是否可以在报告磁盘压力状况的节点上调度pod。目前,在磁盘压力下,不应在节点上放置吊舱,因为它会被kubelet自动逐出。
默认的默认提供者中选了以下谓词策略:
NoVolumeZoneConflict
MaxEBSVolumeCount
MaxGCEPDVolumeCount
匹配有限性
说明:Fit由pod间亲和性确定。AffinityAnotationKey表示pod注释中亲和性数据(json序列化)的键。
AffinityAnnotationKey string = "scheduler.alpha.kubernetes.io/affinity"
节点冲突
一般预测
pod,在数量上
cpu,在内核中
内存,以字节为单位
alpha.kubernetes.io/nvidia-gpu,在设备中截止V1.4每个节点最多只支持1.个gpu
Podcast resources
Podfest Hotel
Pod
Podcast selector match
podesnodetaints
CheckNodeMemoryPressure
Checknodedisk pressure
优先事项和政策
经过预选策略甩选后得到的Nodes,会来到优选步骤。在这个过程中,会并发的根据每个Priorities Policy分别启动一个goroutine,在每个goroutine中会根据对应的policy实现,遍历所有的预选Nodes,分别进行打分,每个Node每一个Policy的打分为0-10分,0分最低,10分最高。待所有policy对应的goroutine都完成后,根据设置的各个priorities policies的权重weight,对每个node的各个policy的得分进行加权求和作为最终的node的得分。
finalScoreNodeA = (weight1 * priorityFunc1) + (weight2 * priorityFunc2)
注意:这里的并发goroutine number为Priorities Policies number,无队列控制,数量不封顶。当然,正常情况,也不会配置超过十几二十个Policies。
思考:如果经过预选后,没有一个Node满足条件,则直接返回FailedPredicates报错,不会再触发Prioritizing阶段,这是合理的。但是,如果经过预选后,只有一个Node满足条件,同样会触发Prioritizing,并且所走的流程和多个Nodes一样。实际上,如果只有一个Node满足条件,在优选阶段,可以直接返回该Node作为最终scheduled结果,无需跑完整个打分流程。
如果经过优选将Nodes打分排名后,有多个Nodes并列得分最高,那么scheduler将随机从中选择一个Node作为目标Node。
Kubernetes提供了以下Priorities Policies的定义,你可以在kube-scheduler启动参数中添加--policy-config-file
来指定要运用的Policies集合,比如:
{ "kind" : "Policy", "apiVersion" : "v1", "predicates" : [ ... ], "priorities" : [ {"name" : "LeastRequestedPriority", "weight" : 1}, {"name" : "BalancedResourceAllocation", "weight" : 1}, {"name" : "ServiceSpreadingPriority", "weight" : 1}, {"name" : "EqualPriority", "weight" : 1} ] }
LeastRequestedPriority: The node is prioritized based on the fraction of the node that would be free if the new Pod were scheduled onto the node. (In other words, (capacity - sum of requests of all Pods already on the node - request of Pod that is being scheduled) / capacity). CPU and memory are equally weighted. The node with the highest free fraction is the most preferred. Note that this priority function has the effect of spreading Pods across the nodes with respect to resource consumption.
BalancedResourceAllocation: This priority function tries to put the Pod on a node such that the CPU and Memory utilization rate is balanced after the Pod is deployed.
SelectorSpreadPriority: Spread Pods by minimizing the number of Pods belonging to the same service, replication controller, or replica set on the same node. If zone information is present on the nodes, the priority will be adjusted so that pods are spread across zones and nodes.
CalculateAntiAffinityPriority: Spread Pods by minimizing the number of Pods belonging to the same service on nodes with the same value for a particular label.
ImageLocalityPriority: Nodes are prioritized based on locality of images requested by a pod. Nodes with larger size of already-installed packages required by the pod will be preferred over nodes with no already-installed packages required by the pod or a small total size of already-installed packages required by the pod.
NodeAffinityPriority: (Kubernetes v1.2) Implements preferredDuringSchedulingIgnoredDuringExecution node affinity; see here for more details.
默认的DefaultProvider中选了以下Priorities Policies
SelectorSpreadPriority, 默认权重为1
InterPodAffinityPriority, 默认权重为1
pods should be placed in the same topological domain (e.g. same node, same rack, same zone, same power domain, etc.)
as some other pods, or, conversely, should not be placed in the same topological domain as some other pods.
AffinityAnnotationKey represents the key of affinity data (json serialized) in the Annotations of a Pod.
scheduler.alpha.kubernetes.io/affinity="..."
LeastRequestedPriority, 默认权重为1
BalancedResourceAllocation, 默认权重为1
NodePreferAvoidPodsPriority, 默认权重为10000
说明:这里权重设置足够大(10000),如果得分不为0,那么加权后最终得分将很高,如果得分为0,那么意味着相对其他得搞很高的,注定被淘汰,分析如下:
如果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分,那么该node对该policy的得分相对没有设置该Anotation的Node得分低的离谱了。也就是说这个Node一定会被淘汰!
NodeAffinityPriority, 默认权重为1
TaintTolerationPriority, 默认权重为1
##scheduler算法流程图
##总结
kubernetes scheduler的任务就是将pod调度到最合适的Node。
整个调度过程分两步:预选(Predicates)和优选(Policies)
默认配置的调度策略为DefaultProvider,具体包含的策略见上。
可以通过kube-scheduler的启动参数--policy-config-file指定一个自定义的Json内容的文件,按照格式组装自己Predicates and Priorities policies。
上述内容就是如何进行Kubernetes Scheduler原理解析,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注创新互联行业资讯频道。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流