以volume create 为例
volumen 资源创建后,volume Informer watch 到资源变化,volume controller 的worker 开始处理,因为longhorn-manager 实例有多个,也就意味着informer有多个,那么,究竟是哪个manager的informer才是处理某次资源变化的负责人呢?
代码探析:
==controller/volume_controller.go==
1 | // 当前的节点 manager 是否负责运行sync逻辑 |
我们查看下 isResponsibleFor 方法的逻辑,代码省略了判错及一些不影响主流程阅读的内容
==controller/volume_controller.go==
1 | // isResponsibleFor picks a running node that has the default engine image deployed. |
我们继续看下 isControllerResponsibleFor,这个函数是longhorn-manager 资源用来判断当前 manager是否负责处理 sync 逻辑的 通用函数
==controller/controller_manager.go==
1 | // 挑选指导原则:优先 Spec.NodeId,优先最优节点 |
总结:
通过以上代码,我们可以总结出:lognhorn-manager 实例主要是判断当前节点是否可负责处理sync逻辑,而判断能否使用当前节点:
最优先条件是当前节点是 perfer(最优节点,perfer的值一般是 xx.Spec.NodeID)
其次是当前节点就是owner节点
最次是最优节点及owner节点都不可用了,那么就使用当前节点
可以看出,节点的挑选最终的优化方向是往 “资源.Spec.NodeId 是哪个,那么就由这个期望的node上的manager来处理”
==注:voulume contoller 这一块加入了 节点engineImage 的判断,与其他资源(例:replica)有些不同,但核心的处理逻辑还是一致的==
(最优不可用,Owner不可用),两个或多个节点都获取到了负责权,这种情况下,是通过 更新 Status.OwnerID,通过 k8s 的版本冲突机制来保证只有最先更新的manager获得处理权,即这一段代码
1 | // 这里是 让哪个 vc instance 来处理 volume,如果是volume create,那就是第一个update 的 vc 获取处理权 |