一、概述
调度器是kubernetes中独特而又重要的一个模块,独特是因为scheduler是唯一一个以plugin形式存在的组件,重要是因为kubernetes中最重要的基础单元pod的部署是通过scheduler完成的。
正常情况下,scheduler为pod通过算法筛选合适的node,然后绑定pod与node关系,而相应的node上的kubelet在完成绑定之后才会启动pod,此过程中,scheduler的功能很明确,就是筛选出合适的node,如果找到了就绑定node信息,如果没有找到,pod则会一直处于pending状态,一旦一个合适的Node接入到kubernetes cluster,调度器会将pod调度到该Node上。
我们知道在k8s中有个非常主要的对象叫做Replication Controller,简称RC.在部署pod时候,通常是通过RC指定pod类型以及副本数量来实现,而并非是部署单pod。为什么需要借助RC来部署呢?首先就是快速方便,只需指定副本数量即可,RC可以部署指定数量的副本pod,另外就是一旦某个pod fail掉,RC可以通过调度器再次拉起与失败个数相同的副本以确保running的副本个数与指定的个数一致。
这里我们可能有个疑问,既然调度器的目的是为pod筛选合适的node,那么在pod中能否指定node呢? 答案是可以的,如果在pod中指定node,则不会经过调度器,node上的kubelet会拉起pod。这时候问题又来了,没有经过调度器的算法筛选,这个由用户指定的node如果不满足Pod的要求,比如资源要求,那又会出现什么样的情况呢? 答案其实很简单,这个pod会被kubelet设置成fail状态,那么这么说来,kubelet会像scheduler一样对node做一些判断,以确保pod适合当前的node。下面我们会分析这个判断的过程。
二、scheduler模块分析
调度的过程分两步,首先是做筛选(predict),其次是排序(priorities)。筛选的过程是决定是否,排序的过程是区分优劣。算法是调度的依据,这个算法其中的一部分-GeneralPredicates也会被kubelet用到,这个在第二节中提到过。算法加载的过程比较巧妙,是通过包的引用来作为算法加载的入口的: