controller-runtime是在client-go/tools/cache和client-go/util/workqueue的基础上实现的, 了解
client-go/tools/cache
和client-go/util/workqueue
对理解controller-runtime
很有帮助
informer 的工作机制是什么
Reflector
从kube-apiserver
中获取资源对象, 更新到DeltaFIFO
中- Informer 从 DeltaFIFO 中获取资源对象, 更新到
local cache
中, 然后执行注册的 EventHandler
自定义控制器会注册 AddFunc
, UpdateFunc
, DeleteFunc
等事件处理器, 这些事件会添加对象到 WorkQueue 中, 然后从 WorkQueue 中获取对象, 触发 reconcile
同一个 crd object 会不会同时被 reconcile
这个全靠Queue数据结构设计的精妙, 保证了正在执行的reconcile不会处理相同的object
向queue中增加object之前会检查是否有次object存在于queue中,如果不存在则加入dirty set,如果也不存在于processing set才会加入queue中,当processing中的处理完成之后(调用Done),会将object从processing set种移除,如果次object在处理过程中加入到了dirty set,则将object再次加入到queue中 https://www.cnblogs.com/daniel-hutao/p/18010835/k8s_clientgo_workqueue
有几种队列,Queue,DelayingQueue,RateLimitingQueue
reconcile
时会读到旧数据吗,如何解决
因为读写分离,更新是直接更新 kube-apiserver
,读是从 indexer(local cache)
中,所以读到的有可能是陈旧的数据。
My cache might be stale if I read from a cache! How should I deal with that?
在更新或patch status之后,通过wait.Pool(100ms, 2s, func()(bool, error))校验cache中的本object数据直至更新