k8s的调度机制
scheduler组件
k8s调度器会将pod调度到资源满足要求并且评分最高的node上。
我们可以使用多种规则比如:
1.设置cpu、内存的使用要求;
2.增加node的label,并通过pod.Spec.NodeSelector进行强匹配;
3.直接设置pod的nodeName,跳过调度直接下发。
k8s 1.2加入了一个实验性的功能:affinity。意为亲和性。这个特性的设计初衷是为了替代nodeSelector,并扩展更强大的调度策略。
调度器的工作机制是这样的:
一、预备工作
1、缓存所有的node节点,记录他们的规格:cpu、内存、磁盘空间、gpu显卡数等;
2、缓存所有运行中的pod,按照pod所在的node进行区分,统计每个node上的pod request了多少资源。request是pod的QoS配置,可以参考之前的文章。
3、list & watch pod资源,当检查到有新的Pending状态的pod出现,就将它加入到调度队列中。
4、调度器的worker组件从队列中取出pod进行调度。
二、调度过程
1、先将当前所有的node放入队列;
2、执行predicates算法,对队列中的node进行筛选。这里算法检查了一些pod运行的必要条件,包括port不冲突、cpu和内存资源QoS(如果有的话)必须满足、挂载volume(如果有的话)类型必须匹配、nodeSelector规则必须匹配、硬性的affinity规则(下文会提到)必须匹配、node的状态(condition)必须正常,taint_toleration硬规则(下文会提到)等等。
3、执行priorities算法,对队列中剩余的node进行评分,这里有许多评分项,各个项目有各自的权重:整体cpu,内存资源的平衡性、node上是否有存在要求的镜像、同rs的pod是否有调度、node affinity的软规则、taint_toleration软规则(下文会提到)等等。
4、最终评分最高的node会被选出。即代码中suggestedHost, err := sched.schedule(pod)一句(plugin/pkg/scheduler/scheduler.go)的返回值。
5、调度器执行assume方法,该方法在pod调度到node之前,就以“该pod运行在目标node上” 为场景更新调度器缓存中的node 信息,也即预备工作中的1、2两点。这么做是为了让pod在真正调度到node上时,调度器也可以同时做后续其他pod的调度工作。
6、调度器执行bind方法&#