kube-scheduler的2个独立控制循环
k8s 1.19.0
调度周期:从NextPod到RunPermitPlugins
绑定周期:从RunPrebindPlugins到RunPostbindPlugins
调度的本质就是将Pod为空的NodeName写上相应的Node的值
第1个控制循环:Informer Path
通过Informer来List Watch API对象,把待调度Pod(nodeName字段是空的)添加进调度队列。只有对调度队列(避免并发操作)和Scheduler Cache(informer本身缓存是只读,额外node和pod缓存随资源状态变化而变化)操作时,才需要加锁。
第2个控制循环:Scheduling Path
不断地从调度队列里出队一个Pod。
Predicates:预选出符合条件的所有节点
Priorities:优选出最优节点
因通过kube-apiserver设置pod nodeName耗时而异步更新,不在关键调度路径里执行。
Assume:不加锁更新Scheduler Cache里的Pod和Node信息(增加资源占用)。
Bind:通过协程异步向kube-apiserver更新Pod。如果更新失败,那么加锁恢复之前node减少的资源。
Admit:kubelet二次确认
Pod完成调度后,节点上的kubelet通过GeneralPredicates的预选调度算法再次验证该Pod是否可以运行在该节点上。不通过时,kubelet向kube-apiserver发送该pod删除请求。
pkg/kubelet/kubelet.go
syncLoopIteration函数
HandlePodAdditions函数
canAdmitPod函数
pkg/kubelet/lifecycle/interfaces.go
Admit函数