资源调度
Kubernetes是如何进行资源调度的?
当APIServer接收来自客户端创建Pods资源的请求后,kubernetes中的kube-scheduler会实时监听到这个Pods还调度到node,于是会通过一系列的算法调度pod到节点上。
其中就包括主要的两个算法,预选策略和优选函数。
除了这预选和优选,还有一些倾向性和污点来控制预选优选的结果。
什么是预选策略(Predicate)?
所谓预选策略就是先找出能够满足Pods运行的基本需求的节点
例如数据库Pods运行需要8G内存,但是这么多节点中的剩余内存可能不足8G了,而有些节点是拥有8G空闲内存的。
但最终会使用那个节点运行数据库Pod,需要通过一系列优选函数
什么是优选函数(Priority)?
优选函数会获取每一个预选出来的节点属性,并根据这个节点属性计算优先级,计算完之后在进行逆序排序,得出最佳匹配的节点。
什么是选定(Select)?
优选结束后,如果最佳匹配的节点不止一个,此时会随即选择其中的节点运行Pods。这个过程叫做选定(Select)
什么是倾向性调度?
节点倾向性(NodeAffinity)
这是在Predicate阶段
- NodeName: 指明要运行在某个特定的节点
- NodeSelector: 根据标签选择特定的节点
Pods 倾向性(PodAffinity)
亲和性:多个Pods最好运行在一个节点 反亲和性:多个Pods最好不要运行在一个节点
什么是污点容忍调度(taint、toleration)?
节点可以定义污点,这样当进行调度时,如果Pods资源能够容忍节点的污点,就可以将资源调度到这个节点,如果无法容忍就不会调度到这个拥有污点的节点。
有哪些预选策略?
- CheckNodeConditionPredicate: 检查阶段是否处于可用状态
- PodFitsHost(HostNamePred): 检查被调度节点是否和
pod.spec.nodeName
相匹配 - PodFitsHostPorts: 如果
pod.spec.container.ports.hostPort
被定义,检查被调度节点端口是否被占用 - PodMatchNodeSelector: 如果
pod.spec.nodeSelector
被定义,检查匹配对应标签的节点 - PodFitsResources: 检查Pods需要的资源是否满足
- NoDiskConflict: 检查Pod依赖存储卷是否满足(默认未启用)
- PodToleratesNodeTaints : 检查pod.spec.tolerations能够容忍的污点是否包含节点上的污点
- PodToleratesNodeNoExecuteTaints: 默认已容忍的污点发生改变,即便不容人节点污点,此时已创建的Pod还会继续运行。 而想让Pod从节点驱离,就需要使用
PodToleratesNodeNoExecuteTaints
实现(默认未启用) - CheckNodeLabelPresence: 检查标签存在性(默认未启用)
- CheckServiceAffinity: 调度新创建的Pod至同Service下的其他运行Pod的节点上(默认未启用)
- 云存储检查:
- MaxEBSVolumeCountPred: 检查节点是否挂载是否启用了足够量的亚马逊EBS卷
- MaxGCEPDVolumeCountPred: 检查节点是否挂载启用了足够量的谷歌GCE卷
- MaxAzureDiskVolumeCountPred: 检查节点是否挂载启用了足够量的微软Azure卷
- CheckNodeMemoryPressurePredicate: 检查节点内存是否处于压力过大
- CheckNodePIDPressurePred : 检查节点PID压力是否过大
- CheckNodeDiskPressurePredicate: 检查节点磁盘IO压力是否过大
- MatchInterPodAffinity: 检查节点是否能够满足Pod亲和性或者反亲和性条件
- ...
预选策略的工作逻辑为一票否决,一项策略不通过则节点不匹配。
优选函数有哪些?
- LeastRequested:
(cpu((capacity-sum(requested))*10/capacity) + memory((capacity-sum(requested))*10/capacity))/2
,CPU内存空闲率越高的胜出 - BalancedResourceAllocation: CPU和内存资源占用率相近的胜出,为了平衡节点资源使用状况
- NodePreferAvoidPods: 根据节点是否拥有这个注解信息
"scheduler.alpha.kubernetes.io/preferAvoidPods"
,优先级权重非常高 - TaintToleration: 将Pod对象的spec.tolerations于节点的taint列表项进行匹配度检查,匹配条目越多,分数越低
- SelectorSpread : 通过标签选择器匹配到的对象,拥有此类对象越多的节点,它的分数也就越低,这个函数主要为了让对象均匀散开到各个节点。
- InterPodAffinity: 亲和性匹配性越多,得分越高,!!!每懂这个函数!!!
- NodeAffinity: 根据NodeSelector匹配,匹配度越高,得分越高
- MostRequested:
(cpu(10 * sum(requested) / capacity) + memory(10 * sum(requested) / capacity)) / 2
CPU内存空闲率越低的胜出,为了榨干机器性能,默认未启用 - NodeLabel: 节点有指定标签则加分,没有指定标签则不加分,
默认未启用 - ImageLocalityPriority: 节点有Pod所需的镜像的分最高,没有则分低,为了Pod快速创建启动。 但是,如果一个Pod有3个容器,第1个容器镜像大小为10M,第2个容器镜像体积为50M,第三个镜像为100M,node001有第1、2个镜像,node002有第3个镜像,此时分数最高的是node002,因为下载3个镜像需要耗费更多的带宽资源。
默认未启用 - ...
优选函数的工作逻辑,通过已启用所有函数,逐个计算分数,然后相加,得分最高的就是最佳的,分数相同随即选择。