前言
本文聚焦v11.0.0client-go controller框架Reflector对象,简单梳理Reflector函数执行流程。整个controller framework中,Reflector的角色是生产者,从k8s api-server中获取runtime.Object,并添加到DeltaFIFO中;indexer是消费者,从DeltaFIFO中获取并处理runtime.Object。
1 List&Watch介绍
Controller framework通过List&Watch机制完成k8s资源对象和Index缓存之间的同步。
// Lister is any object that knows howto perform an initial list.
List: controller启动时执行一次,k8s资源对象全量更新到Indexer。
// Watcher is any object that knows howto start a watch on a resource.
Watch: controller运行时持续监控,k8s资源对象增量更新到Indexer。
2 List&Watch的实现
从Informer框架中我们已经提到,func(*Controller)Run创建并运行Reflector。List&&Watch在Reflector.Run()执行,下图是该函数执行流程图。
1)Reflector.Run()调用ListAndWatch(), 启动一个子协程(goroutine)执行List,主协程阻塞等待List执行完成。
2)Meta.ExtractList(list)把List结果转化成runtime.Object数组。
3)r.syncWith(items, resourceVersion)写入DeltaFIFO,全量同步到Indexer。
4)r.resyncChan()也是在一个子协程里执行。
5)循环执行r.ListerWatcher.Watch(optiopns)。
6)r.WatchHandler增量同步runtime.Object到indexer。
List只做一次全量同步,watch持续做增量同步。下文会分析r.ListerWatcher.List(options),
r.syncWith(items, resourceVersion), r.ListerWatcher.Watch(options),
r.watchHandler实现细节,并简要分析r.syncChan()的作用。
2.1 r.ListerWatcher.List & r.ListerWatcher.Watch
ListerWatcher是接口类型,定义如下:
listwatch.go文件,NewListWatchFromClient创建了ListWatch对象,该对象实现了ListerWatcher interface。r.ListerWatcher.List(options)和r.ListerWatcher.Watch(options),是调用了某个实现了ListerWatcher接口的对象的List,Watch函数。当用户用NewListWatchFromClient创建一个ListWatch对象时,r.ListerWatcher.List(options)实际上调用了NewFilteredListWatchFromClient里的listFunc,而r.ListerWatcher.Watch(options)调用了watchFunc。
watchFunc的Watch()函数实现在client-go/rest/request.go:
2.2 r.syncWith(items, resourceVersion)
r.syncWith调用DeltaFIFO的Replace全量更新对象。
2.3 r.watchHandler
r.watchHandler从watch.Interface中获取event(Add,Modified,Deleted),并调用DeltaFIFO的Add,Modified,Deleted函数触发DeltaFIFO对象增量同步。
2.3 r.resyncChan()
Resync核心函数是r.store.Resync(),该函数实际上调用DeltaFIFO的Resync函数做对象周期性同步。
3 结语
本文仅简单梳理Reflector代码框架,不深入探究每个函数实现细节。
4 参考文档
https://blog.csdn.net/li_101357/article/details/89763992