kubernetes(20):k8s调度器,预选策略以及优选函数概述
K8s调度器,预选策略以及优选函数
https://www.cnblogs.com/kcxg/p/11119679.html
https://blog.csdn.net/dayi_123/article/details/90673991
https://www.cnblogs.com/linuxk/p/10535742.html
1 kubernetes调度器
调度是容器编排的重要环节,需要经过严格的监控和控制,现实生产通常对调度有各类限制,譬如某些服务必须在业务独享的机器上运行,或者从灾备的角度考虑尽量把服务调度到不同机器,这些需求在Kubernetes集群依靠调度组件kube-scheduler满足。
kube-scheduler是Kubernetes中的关键模块,扮演管家的角色遵从一套机制为Pod提供调度服务,例如基于资源的公平调度、调度Pod到指定节点、或者通信频繁的Pod调度到同一节点等。容器调度本身是一件比较复杂的事,因为要确保以下几个目标:
1、 公平性:在调度Pod时需要公平的进行决策,每个节点都有被分配资源的机会,调度器需要对不同节点的使用作出平衡决策。
2、 资源高效利用:最大化群集所有资源的利用率,使有限的CPU、内存等资源服务尽可能更多的Pod。
3、 效率问题:能快速的完成对大批量Pod的调度工作,在集群规模扩增的情况下,依然保证调度过程的性能。
4、 灵活性:在实际运作中,用户往往希望Pod的调度策略是可控的,从而处理大量复杂的实际问题。因此平台要允许多个调度器并行工作,同时支持自定义调度器。
为达到上述目标,kube-scheduler通过结合Node资源、负载情况、数据位置等各种因素进行调度判断,确保在满足场景需求的同时将Pod分配到最优节点。显然,kube-scheduler影响着Kubernetes集群的可用性与性能,Pod数量越多集群的调度能力越重要,尤其达到了数千级节点数时,优秀的调度能力将显著提升容器平台性能。
1.1 调度流程
API Server在接受客户端提交Pod对象创建请求后,然后是通过调度器(kube-schedule)从集群中选择一个可用的最佳节点来创建并运行Pod。而这一个创建Pod对象,在调度的过程当中有3个阶段:节点预选、节点优选、节点选定,从而筛选出最佳的节点。如图:
- 节点预选:基于一系列的预选规则对每个节点进行检查,将那些不符合条件的节点过滤,从而完成节点的预选
- 节点优选:对预选出的节点进行优先级排序,以便选出最合适运行Pod对象的节点
- 节点选定:从优先级排序结果中挑选出优先级最高的节点运行Pod,当这类节点多于1个时,则进行随机选择
当我们有需求要将某些Pod资源运行在特定的节点上时,我们可以通过组合节点标签,以及Pod标签或标签选择器来匹配特定的预选策略并完成调度,如MatchInterPodAfinity、MatchNodeSelector、PodToleratesNodeTaints等预选策略,这些策略常用于为用户提供自定义Pod亲和性或反亲和性、节点亲和性以及基于污点及容忍度的调度机制。
1.2 调度方式
1、 node(运行在那些node上)
2、 pod选择(当需要运行在某个pod在一个节点上(pod亲和性),或不要pod和某个pod运行在一起(pod反亲和性))
3、 污点 (pod是否能容忍污点,能则能调度到该节点,不能容忍则无法调度到该节点,如果存在则驱离pod),可以定义容忍时间
1.3 常用的预选机制
预选策略实际上就是节点过滤器,例如节点标签必须能够匹配到Pod资源的标签选择器(MatchNodeSelector实现的规则),以及Pod容器的资源请求量不能大于节点上剩余的可分配资源(PodFitsResource规则)等等。执行预选操作,调度器会逐一根据规则进行筛选,如果预选没能选定一个合适的节点,此时Pod会一直处于Pending状态,直到有一个可用节点完成调度。其常用的预选策略如下:
CheckNodeCondition:#检查节点是否正常(如ip,磁盘等)
GeneralPredicates
HostName:#检查Pod对象是否定义了pod.spec.hostname
PodFitsHostPorts:#pod要能适配node的端口 pods.spec.containers.ports.hostPort(指定绑定在节点的端口上)
MatchNodeSelector:#检查节点的NodeSelector的标签 pods.spec.nodeSelector
PodFitsResources:#检查Pod的资源需求是否能被节点所满足
NoDiskConflict: #检查Pod依赖的存储卷是否能满足需求(默认未使用)
PodToleratesNodeTaints:#检查Pod上的spec.tolerations可容忍的污点是否完全包含节点上的污点;
PodToleratesNodeNoExecuteTaints:#不能执行(NoExecute)的污点(默认未使用)
CheckNodeLabelPresence:#检查指定的标签再上节点是否存在
CheckServiceAffinity:#将相同services相同的pod尽量放在一起(默认未使用)
MaxEBSVolumeCount: #检查EBS(AWS存储)存储卷的最大数量
MaxGCEPDVolumeCount #GCE存储最大数
MaxAzureDiskVolumeCount: #AzureDisk 存储最大数
CheckVolumeBinding: #检查节点上已绑定或未绑定的pvc
NoVolumeZoneConflict: #检查存储卷对象与pod是否存在冲突
CheckNodeMemoryPressure:#检查节点内存是否存在压力过大
CheckNodePIDPressure: #检查节点上的PID数量是否过大
CheckNodeDiskPressure: #检查内存、磁盘IO是否过大
MatchInterPodAffinity: #检查节点是否能满足pod的亲和性或反亲和性
在上面的这些预选策略里面,CheckNodeLabelPressure和CheckServiceAffinity可以在预选过程中结合用户自定义调度逻辑,这些策略叫做可配置策略。其他不接受参数进行自定义配置的称为静态策略。
1.4 常用的优选函数
LeastRequested:#空闲量越高得分越高
(cpu((capacity-sum(requested))*10/capacity)+memory((capacity-sum(requested))*10/capacity))/2
BalancedResourceAllocation:#CPU和内存资源被占用率相近的胜出;
NodePreferAvoidPods: #节点注解信息“scheduler.alpha.kubernetes.io/preferAvoidPods”
TaintToleration:#将Pod对象的spec.tolerations列表项与节点的taints列表项进行匹配度检查,匹配条目越,得分越低;
SeletorSpreading:#标签选择器分散度,(与当前pod对象通选的标签,所选其它pod越多的得分越低)
InterPodAffinity:#遍历pod对象的亲和性匹配项目,项目越多得分越高
NodeAffinity: #节点亲和性 、
MostRequested: #空闲量越小得分越高,和LeastRequested相反 (默认未启用)
NodeLabel: #节点是否存在对应的标签 (默认未启用)
ImageLocality:#根据满足当前Pod对象需求的已有镜像的体积大小之和(默认未启用)