kube-scheduler的2个独立控制循环

发布时间 2023-05-02 10:54:54作者: 王景迁

k8s 1.15.0

调度周期:从NextPod到RunPermitPlugins
绑定周期:从RunPrebindPlugins到RunPostbindPlugins
调度的本质就是将Pod为空的NodeName写上相应的Node的值

第1个控制循环:Informer Path

通过Informer来List Watch API对象,把待调度Pod(nodeName字段是空的)添加进调度队列。只有对调度队列和 Scheduler Cache 操作时,才需要加锁。

第2个控制循环:Scheduling Path

不断地从调度队列里出队一个Pod。
Predicates:过滤出符合条件的所有节点
Priorities:找到最终调度的节点
设置Pod对象的nodeName。
Assume:不在关键调度路径里访问kube-apiserver,只会更新Scheduler Cache里的Pod和Node信息。
Bind:通过协程异步地向kube-apiserver更新Pod。如果这次异步过程失败了,等Scheduler Cache同步之后一切就会恢复正常。

pkg/scheduler/scheduler.go
scheduleOne函数

Admit:kubelet二次确认

Pod完成调度后,在某个节点上运行起来之前,该节点上的kubelet通过GeneralPredicates的预选调度算法来再次验证该Pod是否确实能够运行在该节点上。当kubelet二次确认时发现Pod不能在当前节点上创建时,该Pod会被kubelet向kube-apiserver发送删除请求。

pkg/kubelet/kubelet.go
syncLoopIteration函数

HandlePodAdditions函数

canAdmitPod函数

pkg/kubelet/lifecycle/interfaces.go
Admit函数

Scheduler Framework:可扩展性设计

基于Go plugin机制(在编译时选择把哪些插件编译进去,每一个绿色的箭头都是插件),在调度器生命周期的各个关键点上,暴露出扩展接口,实现用户自定义调度器的能力。

参考资料

41 | 十字路口上的Kubernetes默认调度器