默认调度器的责任就只有一个,那就是为新创建出来的Pod选择一个最合适的节点。而这个过程分为两步:

  1. 调用调用一组叫作 Predicate 的调度算法,来检查每个 Node。筛选出符合符合条件的Node。
  2. 再调用一组叫作 Priority 的调度算法,来给上一步得到的结果里的每个 Node 打分。最终的调度结果,就是得分最高的那个 Node。

一个Pod被调度成功,就是将它的 spec.nodeName 字段填上调度结果的节点名字。

通过上图可以看出,调度器的核心是由两个控制循环组成的。

第一个控制循环Informer Path,监听Etcd中API对象的变化,当一个Pod被创建出来的时候,调度器就会将其加入带调度队列当中。

第二个控制循环Scheduling Path局就是负责调度的主循环,调用我们前面所说的两组算法获得最终要调度的Node,为了提高算法的效率,利用Scheduler Cache本地缓存节点信息,方便计算。

将Pod的nodeName字段变为上面选出的Node的过程被称为Bind,为了避免在关键的调度路径中进行远程访问apiserver,只会更新scheduler Cache中的Pod和Node,然后异步发起一个协程进行真正的Bind操作

正是由于上述 Kubernetes 调度器的“乐观”绑定的设计,当一个新的 Pod 完成调度需要在某个节点上运行起来之前,该节点上的 kubelet 还会通过一个叫作 Admit 的操作来再次验证该 Pod 是否确实能够运行在该节点上。