注:本文已发布超过一年,请注意您所使用工具的相关版本是否适用
在前面的文章当中我们已经完整的完成了一个 Operator 的开发,涉及到了 CURD、预删除、Status、Event、OwnerReference、WebHook,也算是将一个 Operator 开发中会涉及到的点大部分都了解了一下。kubebuilder 帮我们做了很多事情,让我们的开发基本上只需要关注一个 Reconcile 函数就可以了,但是从另外一个方面来讲,kubebuilder 目前对我们来说它还是一个黑盒,会产生很多的疑问:
我们先来看一下来自官方文档的这个架构图[1]
main.go启动,一般来说一个 Controller 只有一个进程,如果做了高可用的话,会有多个了解了基本的架构之后,我们就从入口 main.go 开始,看一看 kubebuilder 究竟在后面偷偷的做了哪些事情吧。
1 | |
可以看到 main.go 主要是做了一些启动的工作包括:
下面我们就顺着 main 函数里面的逻辑一步步的往下看看
1 | |
1 | |
这里主要是调用 NewInformersMap方法创建 Informer 的映射
1 | |
NewInformersMap会去分别创建,结构化、非结构化以及 metadata 的 InformerMap 而这些方法最后都会去调用 newSpecificInformersMap方法,区别就是不同的方法传入的 createListWatcherFunc 参数不同
1 | |
newSpecificInformersMap 和常规的 InformersMap 类似,区别是没实现 WaitForCacheSync方法
以结构化的传入的 createStructuredListWatch 为例,主要是返回一个用于创建 SharedIndexInformer 的 ListWatch 对象
1 | |
小结: cache 主要是创建了一些 InformerMap,完成了 GVK 到 Informer 的映射,每个 Informer 会根据 ListWatch 函数对对应的 GVK 进行 List 和 Watch。
1 | |
client 创建了两个一个用于读,一个用于写,用于读的会直接使用上面的 cache,用于写的才会直接和 APIServer 进行交互
下面我们看一下核心的 Controller 是怎么初始化和工作的
1 | |
main.go 的方法里面主要是初始化了 Controller 的结构体,然后调用了 SetupWithManager方法
1 | |
SetupWithManager之前有讲到过,主要是使用了建造者模式,去构建了我们需要监听的对象,只有这些对象的相关事件才会触发我们的 Reconcile 逻辑。这里面的 Complete 最后其实是调用了 Build 方法
1 | |
Build主要调用 doController 、doWatch两个方法
1 | |
doController主要是初始化了一个 Controller,这里面传入了我们实现 的Reconciler以及获取到我们的 GVK 的名称
1 | |
Watch 主要是监听我们想要的资源变化,blder.ctrl.Watch(src, hdler, allPredicates...)通过过滤源事件的变化,allPredicates是过滤器,只有所有的过滤器都返回 true 时,才会将事件传递给 EventHandler hdler,这里会将 Handler 注册到 Informer 上
1 | |
无论是不是 leader 最后都会使用 startRunnable 启动 Controller
1 | |
实际上是调用了 Controller 的 Start方法
1 | |
Reconcile 方法的触发是通过 Cache 中的 Informer 获取到资源的变更事件,然后再通过生产者消费者的模式触发我们自己实现的 Reconcile 方法的。
Kubebuilder 是一个非常好用的 Operator 开发框架,不仅极大的简化了 Operator 的开发过程,并且充分的利用了 go interface 的特性留下了足够的扩展性,这个我们可以学习,如果我们的业务代码开发框架能够做到这个地步,我觉得也就不错了
注:本文已发布超过一年,请注意您所使用工具的相关版本是否适用
在前面的文章当中我们已经完整的完成了一个 Operator 的开发,涉及到了 CURD、预删除、Status、Event、OwnerReference、WebHook,也算是将一个 Operator 开发中会涉及到的点大部分都了解了一下。kubebuilder 帮我们做了很多事情,让我们的开发基本上只需要关注一个 Reconcile 函数就可以了,但是从另外一个方面来讲,kubebuilder 目前对我们来说它还是一个黑盒,会产生很多的疑问:
我们先来看一下来自官方文档的这个架构图[1]
main.go启动,一般来说一个 Controller 只有一个进程,如果做了高可用的话,会有多个了解了基本的架构之后,我们就从入口 main.go 开始,看一看 kubebuilder 究竟在后面偷偷的做了哪些事情吧。
1 | |
可以看到 main.go 主要是做了一些启动的工作包括:
下面我们就顺着 main 函数里面的逻辑一步步的往下看看
1 | |
1 | |
这里主要是调用 NewInformersMap方法创建 Informer 的映射
1 | |
NewInformersMap会去分别创建,结构化、非结构化以及 metadata 的 InformerMap 而这些方法最后都会去调用 newSpecificInformersMap方法,区别就是不同的方法传入的 createListWatcherFunc 参数不同
1 | |
newSpecificInformersMap 和常规的 InformersMap 类似,区别是没实现 WaitForCacheSync方法
以结构化的传入的 createStructuredListWatch 为例,主要是返回一个用于创建 SharedIndexInformer 的 ListWatch 对象
1 | |
小结: cache 主要是创建了一些 InformerMap,完成了 GVK 到 Informer 的映射,每个 Informer 会根据 ListWatch 函数对对应的 GVK 进行 List 和 Watch。
1 | |
client 创建了两个一个用于读,一个用于写,用于读的会直接使用上面的 cache,用于写的才会直接和 APIServer 进行交互
下面我们看一下核心的 Controller 是怎么初始化和工作的
1 | |
main.go 的方法里面主要是初始化了 Controller 的结构体,然后调用了 SetupWithManager方法
1 | |
SetupWithManager之前有讲到过,主要是使用了建造者模式,去构建了我们需要监听的对象,只有这些对象的相关事件才会触发我们的 Reconcile 逻辑。这里面的 Complete 最后其实是调用了 Build 方法
1 | |
Build主要调用 doController 、doWatch两个方法
1 | |
doController主要是初始化了一个 Controller,这里面传入了我们实现 的Reconciler以及获取到我们的 GVK 的名称
1 | |
Watch 主要是监听我们想要的资源变化,blder.ctrl.Watch(src, hdler, allPredicates...)通过过滤源事件的变化,allPredicates是过滤器,只有所有的过滤器都返回 true 时,才会将事件传递给 EventHandler hdler,这里会将 Handler 注册到 Informer 上
1 | |
无论是不是 leader 最后都会使用 startRunnable 启动 Controller
1 | |
实际上是调用了 Controller 的 Start方法
1 | |
Reconcile 方法的触发是通过 Cache 中的 Informer 获取到资源的变更事件,然后再通过生产者消费者的模式触发我们自己实现的 Reconcile 方法的。
Kubebuilder 是一个非常好用的 Operator 开发框架,不仅极大的简化了 Operator 的开发过程,并且充分的利用了 go interface 的特性留下了足够的扩展性,这个我们可以学习,如果我们的业务代码开发框架能够做到这个地步,我觉得也就不错了