scheduler模块在k8s系统中的作用是分配pod,它会watch未分配的pod,然后把pod分配到合适的节点上。scheduler模块代码在目录pkg/scheduler中,其中scheduler.go文件中有一个Scheduler结构体,它主要由下面几个数据结构组成:
1)Algorithm:算法接口,提供schedule时候的算法。
2)SchedulingQueue:等待schedule的pod队列。
3)NextPod():每次取从队列中取一个pod进行schedule,这个方法是非阻塞的。
Scheduler结构体的Run方法内容如下:
Scheduler首先同步需要分配的pod到队列中,然后运行一个无限循环,每次循环做一次分配。
scheduleOne方法里面是一次分配的逻辑,首先会从优先级队列里面取下一个Pod,然后用Algorithm去schedule一次pod,如果schedule失败则记录一次失败。
Algorithm是一个interface,只有三个方法,用户可以实现这三个方法来实现自己的Algorithm。
其中preempt方法在一个pod分配失败之后,通过抢占一些低优先级pod资源的方式来尝试重新分配。Extenders则是对schedule的扩展,比如运行一些pre-scheduler和after-scheduler的流程等等。k8s提供了一个内置的schedule算法,我们来看看它是怎么运行的。
内置schedule的算法是这样的:首先获得一个node列表,然后filter掉那些不合适的node,用这些node和pod信息去排一个优先级队列(heap实现的优先级队列),然后从队列中选择评分最高的一个,开发者可以用插件的方式去定制化评分算法。
scheduler内部还有一个插件加载的机制,在framework文件夹里面。它实际上用一个框架规定了schedule的几个阶段,PreFilter, Filter, QueueSort等等,用户可以把自己的逻辑用plugin的方式插入各个阶段,从而定制化schedule的整个流程。