kubebuilder流程
1、创建manager,ctrl.NewManager,包括设置 shemme和端口、选主信息等配置、NewCluster(用来访问k8s,主要包括newCache和New读写client)、newEventRecorder。
1.1、newCache包括创建informerMap,分为structured、unstructured与metadata,其实最终都是调用newSpecificInformersMap,在newSpecificInformersMap中通过createListWatcher来NewListWatch对象,通过informersByGVK来记录schema中每个GVK对象与informer的对应关系,使用时可根据GVK得到informer再去得到litser和watcher对象。
1.2、newClient包括newApiReader和newWriteObj,apiReader直接从apiserver读写对象,writeObj实现了读写分离的Client,写直接写apiserver,读先读cache读不到则通过clientset。
2、创建builder(controller),controller.SetupWithManager主要包括 设置配置、doController来创建controller、doWatch来设置需要监听的资源,对于监听资源会在informer上添加回调函数进行filter。
2.1、doController调用controller.New来创建controller并添加到manager;
2.2、doWatch主要watch当前资源,包括forInput,ownsInput(owner为当前资源),以及watchsInput,最后调用ctrl.Watch来注册,且watch的是localStore,并且watch是加锁的,防止并发问题。
3、启动manager,启动监控服务、启动健康检查服务、启动非选主服务、启动选主服务
3.1、对于非选主服务webhook主要包括 等待cache同步,启动n个worker,每个Worker不断从workerQueue的req数据,之后调用c.Do.Reconcile来调谐处理取到的req对象。
3.2、对于选主服务controller,最前边加了一步 加入到选主服务队列,其他的和webhook完全相同。(若开启多节点竞争选主服务则只有主节点会启动控制器执行reconcile,而从节点只是用于实现高可用,并会不断竞争选主,关闭选主服务则谁先启动谁一直占据主节点)
controller配置选项:
Owns:监听dengployment且该deployment的Owner是当前资源,deployment发生变化则将当前资源owner重新入队workqueue。使用全局的eventfilter+own的predicates;
For:监听owner当前资源,使用全局eventfilter;
Watches:监听dengployment,使用全局的eventfilter+watches自己实现的入队器EventHandler,
设置该资源的独有的事件监听规则,并能够自定义入队的资源类型;
EventFilter:变更过滤器,是添加在informer的回调函数,可以针对watch的所有资源统一地设置事件监听规则;
Options:worker数量、ratelamiter等参数设置;
最佳实践:
1、不应该在一个reconciler逻辑中进行两次资源的update(update status除外),否则会引发版本不一致的报错。