热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

13.调度器、预选策略及优选函数、高级调度方式

参见:调度器、预选策略与优选函数 https:www.cnblogs.comweiyiming007p10560518.html一、前言master上运行着三个最核心的组件,api

参见:调度器、预选策略与优选函数 https://www.cnblogs.com/weiyiming007/p/10560518.html


一、前言

master上运行着三个最核心的组件,apiserver、scheduler、controller manager。此外,master还依赖于ectd存储节点,最好ectd是有冗余能力的集群。


1、调度器(scheduler)

master上的scheduler控制着pod运行在哪个node上,默认用的default-scheduler(用describe时详情里可以看到用的哪个调度器);

调度器的调度信息存储在master上的etcd里面,apiserver负责和etcd通信;

kubelet运行在node节点上,监控着Node节点上的pod状态,并参与pod的创建等工作;

kube-proxy也运行在node节点上,它监控着service资源的变动, 然后将其在当前节点上创建为iptables或ipvs规则。Kube-proxy是管理service的组件;

kubelet和kube-proxy都要连接master上的apiserver去获取定义信息;


2、调度过程

预选策略(predicate):先排除那些完全不符合此pod运行法则的节点,有两个维度来排除,一个是最低资源需求(request),即节点必须满足此Pod的最低资源;第二个是资源限额(limit),即当前节点最多能给pod提供的资源;

优选(priority):在符合节点找到最佳匹配的节点;

选定(select):把pod绑定到优选的节点上,如果有多个最佳节点,就会随机选一个;


3、K8S的高级调度方式

nodeAffinity:表示node亲和性调度,表示这个pod对这个节点有一定的倾向性。我们通过nodeselector来完成这类调度;

podAffinity或podAntiAffinity:pod亲和性或者pod反亲和性调度,有时我们期望某些Pod运行在同一个节点上或者是相邻的节点上,或者我们期望某些Pod不要运行在某些节点上;

taints和tolerations:污点和污点容忍调度:可以在某些节点上打上污点,表示这些节点不让pod在其上面运行。容忍某节点上污点的子集,则可以该Pod可被调度到该节点上。taints是定义在节点之上的,tolerations是定义在pod之上的。

一般是基于最大资源的空闲率来调度。


二、预选策略

1.源码

https://github.com/kubernetes/kubernetes/blob/master/pkg/scheduler/algorithm/predicates/predicates.go   # 预选策略很多,参见源码。

定义的策略很多,但是很多策略默认是没有启用的,可以手动配置启用。


2.常用的预选策略

1、CheckNodeCondition:表示检查是否可以在节点磁盘、网络不可用,或未准备好的前提下,能够把pod调度到上去。

2、GeneralPredicates:通用预选策略,不是一个策略,包含好几个预选策略:

       HostName:表示如果pod定义了hostname属性(pod.spec.hostname),则检查节点的名字跟pod的hostname是否相匹配,但这里并不是定义这个pod必须运行在这些节点上;

       PodFitsHostPorts:如果节点定义了hostport属性(pod.spec.containers.ports.hostPort),表示指定在节点的哪个端口上。如果这个节点的端口被占用了,那么这个节点就不适合运行这个pod;

       MatchNodeSelector:检查pods.spec.nodeSelector这个字段你是否定义了,运行在携有这有这些标签选择器的节点上;没有对应的node,则pod无法运行。

       PodFitsResources:检查节点是否有足够的资源来支持这个pod运行;

3、NoDiskConfict:检查Pod所请求的存储卷类型在此节点上是否可用。比如需要glusterfs类型的资源,但该节点不能挂在该类型资源。NoDiskConfict调度策略默认没有启用。

4、PodToleratesNodeTaints:如果Pod定义了Tolerates(容忍度),即pods.spec.tolerations,那么就检查Pod上的spec.tolerations可容忍的污点是否完全包含节点上的污点,如果是,表示这个节点可以被选定;

5、PodToleratesNodeNoExecuteTaints:检查pod是否容忍节点上有NoExecute污点。NoExecute污点:如果一个pod上运行在一个没有污点的节点上,后来这个节点又给加上污点了,那么NoExecute表示这个新加污点的节点会去除其上正在运行的pod;此调度策略默认没有启用;

6、CheckNodeLabelPresence:检查节点上指定标签的存在性,如果节点有pod指定的标签,那么这个节点就被选中。 此调度策略默认没有启用;

7、CheckServiceAffinity:根据当前Pod对象所属的Service已有的其他Pod对象。一个service下可以有多个pod,比如这些pod都运行在1、2、3机器上,而没有运行在4、5、6机器上,那么CheckServceAffinity就表示新加入的pod都集中运行在1、2、3机器上,这样集中好处是一个service下pod之间内部通信的效率变高了。 这个策略默认是没有启用的。

8、CheckVolumeBinding:检查节点上的pvc是否被别的pod绑定了;

9、NoVolumeZoneConflict:区域限制的前提下,检查节点上的pod是否与pod的需求冲突;

10、CheckNodeMemoryPressure:检查节点内存是否存在压力;

11、CheckNodePIDPressure:检查节点pid数量是否压力过大,但一般pid是可以重复使用的;

12、CheckNodeDiskPressure:检查内存/磁盘 IO是否压力过大;

13、MatchInterPodAffinity:检查Pod是否满足亲和性或者反亲和性;

14、MaxCSIVolumeCountPred:检查节点上挂载的附加存储的数量是否超出了最大的设定值。

 

pod在调度的时候,启用的所有预选策略要逐一评估。(都要满足,一票否决)


三、优选函数

1.源码

https://github.com/kubernetes/kubernetes/tree/master/pkg/scheduler/algorithm/priorities

https://github.com/kubernetes/kubernetes/blob/master/pkg/scheduler/algorithm/priorities/priorities.go


2.常用的优选函数

每一个优选函数的最大得分是10分。(得分范围是0-10)

1、LeastRequest:最少请求,空闲比例。对cpu来说,用cpu((capacity-sum(requested))*10/capacity)方式进行评估,得分最高的胜出;内存同样。(cpu得分+mem得分)/2=优选函数得分

2、BalanceResourceAllocation:均衡资源的使用方式,表示以cpu和内存占用率的相近程度(均衡)作为评估标准,二者占用越接近,得分就越高,得分高的胜出。

3、NodePreferAvoidPods:看节点是否有注解信息"scheduler.alpha.kubernetes.io/preferAvoidPods"。没有这个注解信息,说明这个节点是适合运行这个pod的,得分为10。优先级很高。

4、TaintToleration:将pod对象的spec.toleration与节点的taint列表项进行匹配度检查,匹配的条目越多,得分越低;

5、SelectorSpreading:查找当前pod对象对应的service,statefulset,replicatset等所匹配的标签选择器,在节点上运行的带有这样标签的pod越少得分越高。 这就是说我们要把同一个标签选择器下运行的pod散开(spreading)到多个节点上;

6、InterPodAffinity:遍历Pod对象亲和性的条目,并将那些能够匹配到节点权重相加,值越大的得分越高,得分高的胜出;

7、NodeAffinity:根据pod对象中的nodeselector,对节点进行匹配度检查,能够成功匹配的数量越多,得分就越高;

8、MostRequest:表示尽可能的把一个节点的资源先用完,这个和least_requested相反,二者不能同时使用;默认未启用;

9、NodeLabel:根据节点是否拥有标签,不关注标签值,来评估分数;默认未启用;

10、ImageLocality:表示根据满足当前pod运行需要的已有镜像体积大小之和来选择节点的;默认未启用。

 

启用的优选函数会逐一评估,最后得分相加,根据最终得分来优!!


四、高级调度设置方式

两类调度方式

节点选择器:nodeSelector,nodeName

节点亲和调度:nodeAffinity


(一)、节点选择器nodeSelector(强约束)


[root@master ~]# kubectl explain pod.spec.nodeSelector

 技术分享图片

技术分享图片

Pod处于Pending状态,因为调度失败,没有节点拥有disk:ssh标签。


[root@master ~]# kubectl label node node2 disk=ssd # 给node2打上需要的标签。

技术分享图片

可以看到刚才Pending的pod运行到了节点2上。


(二)、节点亲和性调度nodeAffinity


[root@master ~]# kubectl explain pod.spec.affinity.nodeAffinity
requiredDuringSchedulingIgnoredDuringExecution:硬亲和性,必须满足
preferredDuringSchedulingIgnoredDuringExecution:软亲和性,不是必须,尽量满足,优先运行在满足条件的节点上。

软亲和性和硬亲和性资源清单定义不相同,不能单独改个单词就是。


1、硬亲和性


[root@master ~]# kubectl explain pod.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms

 技术分享图片

目前没有节点拥有zOne=foo或者zOne=bar。


[root@master ~]# kubectl label node node1 zOne=foo #给node1打个标签

技术分享图片

Pod状态变为Running。


2、软亲和性


[root@master ~]# kubectl label node node1 zone- # 先删除node1上的zone标签

技术分享图片

目前是没有节点有拥有pod所需要的标签的,但是Pod一经创建马上运行,因为软亲和性,满足最好,不能满足也能将就。


三、Pod亲和性调度podAffinity,podAntiAffinity

比如在机房中,我们可以将一个机柜中的机器都打上标签,让pod调度的时候,对此机柜有亲和性;或者将机柜中某几台机器打上标签,让pod调度的时候,对这几个机器有亲和性;

通过节点亲和性,也能让一组pod运行在一起,但需要对节点进行精心编排,节点拥有的标签,想在一起pod使用相同的标签选择器,不想在一起的pod使用不同的标签选择器,比较麻烦。

Pod亲和性,第一个Pod随机调度,后面的Pod都以此为标准,运行在相近节点上,不需要考虑节点标签配置。但仍需要有一个逻辑条件预先设置好哪些节点是属于相近节点,同一位置,让pod去判断。


1、Pod亲和性podAffinity


[root@master ~]# kubectl explain pod.spec.affinity.podAffinity
preferredDuringSchedulingIgnoredDuringExecution:软亲和性
requiredDuringSchedulingIgnoredDuringExecution:硬亲和性


硬亲和性


[root@master ~]# kubectl explain pod.spec.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution

技术分享图片

第二个Pod定义的podAffinity意思为:当前这个pod要跟一个有着标签app=myapp(要和上面pod-first的metadata里面的标签一致)的pod在一起。

topologyKey: kubernetes.io/hostname意思为:节点标签kubernetes.io/hostname相同的为相近节点。

由于定义的是硬亲和性,如果调度器找不到运行着app=myapp标签资源的节点,则Pod状态应该是Pending。

注意:要考虑到所有存在此标签的Pod,预期结果不同可能是因为当前名称空间已经存在app=myapp标签的Pod。


软亲和性

类似,不多介绍。


2、Pod反亲和性podAntiAffinity


[root@master ~]# kubectl explain pod.spec.affinity.podAntiAffinity
preferredDuringSchedulingIgnoredDuringExecution:软亲和性
requiredDuringSchedulingIgnoredDuringExecution:硬亲和性

资源清单定义类似于podAffinity。


硬亲和性

 技术分享图片

这样展现出来的效果不明显,如果只有一个节点可用的话,应该是第二个Pod会Pending。

再次实验:


[root@master ~]# kubectl label nodes node1 zOne=foo
[root@master
~]# kubectl label nodes node2 zOne=foo
# 给node1,node2打标签,这样node1,node2以此为标签属于一组相近节点,创建Pod时以zone为topologyKey。

技术分享图片

技术分享图片

与预期结果相符,调度失败提示也很明显。


软亲和性

类似,不过多实验。


四、污点调度

给节点选择了让哪些Pod运行的权利。

污点(taint)定义在节点上。

Tolerations:定义在pod上,定义容忍度。


[root@master ~]# kubectl get node node1 -o yaml
[root@master
~]# kubectl explain node.spec.taints

在Pod上定义容忍度有两种方式


[root@master schedule]# kubectl explain deployment.spec.template.spec.tolerations.operator
等值比较Equal: key,value,effect完全匹配
存在性判断Exists:key,effect完全匹配,value可以为空,不关注。

逐一匹配节点上的污点是否被容忍,只要有一个污点没有被容忍,并且effect为NoSchedule,则一定不能被调度过来。


[root@master ~]# kubectl describe node master #一般pod不被调度到master的原因是Master上存在污点。

技术分享图片


1、node.spec.taints.effect

taints上的effect定义对Pod的排斥效果:

NoSchedule:仅影响调度过程,对现存pod不产生影响,不能容忍就不能调度过来。

PreferNoSchedule:仅影响调度过程,不能容忍就不能调度过来,但是实在没办法也是能调度过来的。对节点新加了污点,那么对节点上现存的pod没有影响。

NoExecute:既影响调度过程,也影响现存的Pod对象。不容忍污点的Pod对象将被驱逐。


2、定义污点及容忍度


定义污点:


[root@master ~]# kubectl taint --help
[root@master schedule]# kubectl taint node node1 node
-type=production:NoSchedule #给node1打上污点

技术分享图片

所有的pod都被调度到了node2,因为pod不能容忍污点。在node2上也打上污点,并且effect为NoExecute,则已调度的Pod会被驱逐,然后因为所有节点上都有pod容忍不了的污点,pod就pending了。效果如下:

[root@master schedule]# kubectl taint node node2 node-type=dev:NoExecute

 技术分享图片


定义容忍度:


[root@master schedule]# kubectl explain pod.spec.tolerations
[root@master schedule]# kubectl explain deployment.spec.template.spec.tolerations

技术分享图片

在Pod上定义容忍度(容忍node-type=production:NoSchedule)后,之前Pending的pod被调度到了node1上,符合预期。

技术分享图片

修改资源清单,定义容忍node-type的所有effect,则pod能容忍node1,node2上的node-type污点,不管effect是什么。

注意:

       容忍度定义,等值比较(Equal)必须key,value,effect三者完全相匹配;如果effect,key定义为空,代表匹配所有的effect和key

       修改了资源清单的容忍度,Pod会被重新调度。


[root@master ~]# kubectl describe nodes node1 |grep -E (Roles|Taints) #查看节点上的污点
[root@master
~]# kubectl taint node node1 node-type- #删除节点上的污点
[root@master
~]# kubectl taint node node2 node-type-


五、Tips:

Protocol Buffer:组件之间内部对象序列化格式。

Json:资源对象序列化格式。

键值数据对:

       Labels:标签

       Annotations:注解

       Taints:污点,用在节点上的。


推荐阅读
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 在project.properties添加#Projecttarget.targetandroid-19android.library.reference.1..Sliding ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
author-avatar
蒲小平2502897955
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有