1. Controller-runtime结构介绍
kubebuilder底层使用的就是Controller-runtime,Controller-runtime为 Controller 的开发提供了各种功能模块,每个模块中包括了一个 或多个实现,通过这些模块,开发者可以灵活地构建自己的 Controller,主要包括以下内容。
(1) Client:用于读写 Kubernetes 资源对象的客户端。
(2) Cache:本地缓存,用于保存需要监听的 Kubernetes 资源。缓存提供了只读客户端, 用于从缓存中读取对象。缓存还可以注册处理方法(EventHandler),以响应更新的事件。
(3) Manager:用于控制多个 Controller,提供 Controller 共用的依赖项,如 Client、 Cache、Schemes 等。通过调用 Manager.Start 方法,可以启动 Controller。
(4) Controller:控制器,响应事件(Kubernetes 资源对象的创建、更新、删除)并 确保对象规范(Spec 字段)中指定的状态与系统状态匹配,如果不匹配,则控制器需要根 据事件的对象,通过协调器(Reconciler)进行同步。在实现上,Controller 是用于处理 reconcile.Requests 的工作队列,reconcile.Requests 包含了需要匹配状态的资源对象。
① Controller 需要提供 Reconciler 来处理从工作队列中获取的请求。
② Controller 需要配置相应的资源监听,根据监听到的 Event 生成 reconcile.Requests 并加入队列。
(5) Reconciler:为 Controller 提供同步的功能,Controller 可以随时通过资源对象的 Name 和 Namespace 来调用 Reconciler,调用时,Reconciler 将确保系统状态与资源对象 所表示的状态相匹配。例如,当某个 ReplicaSet 的副本数为 5,但系统中只有 3 个 Pod 时, 同步 ReplicaSet 资源的 Reconciler 需要新建两个 Pod,并将它们的 OwnerReference 字段 指向对应的 ReplicaSet。
① Reconciler 包含了 Controller 所有的业务逻辑。
② Reconciler 通常只处理单个对象类型,例如只处理 ReplicaSets 的 Reconciler,不 处理其他的对象类型。如果需要处理多种对象类型,需要实现多个 Controller。如果你 希望通过其他类型来触发 Reconciler,例如,通过 Pod 对象的事件来触发 ReplicaSet 的 Recon- ciler,则可以提供一个映射,通过该映射将触发 Reconciler 的类型映射到需要匹 配的类型。
③ 提供给 Reconciler 的参数是需要匹配的资源对象的 Name 和 Namespace。
④ Reconciler 不关心触发它的事件的内容和类型。例如,对于同步 ReplicaSet 资源的 Reconciler 来说,触发它的是 ReplicaSet 的创建还是更新并不重要,Reconciler 总是会比 较系统中相应的 Pod 数量和 ReplicaSet 中指定的副本数量。
(6) WebHook:准 入 WebHook(Admission WebHook) 是 扩 展 Kubernetes API 的 一种机制,WebHook 可以根据事件类型进行配置,比如资源对象的创建、删除、更改等 事件,当配置的事件发生时,Kubernetes 的 APIServer 会向 WebHook 发送准入请求 (AdmissionRequests),WebHook 可以对请求中的资源对象进行更改或准入验证,然后将 处理结果响应给 APIServer。
(7) Source:resource.Source 是 Controller.Watch 的参数,提供事件,事件通常是来 自 Kubernetes 的 APIServer(如 Pod 创建、更新和删除)。例如,source.Kind 使用指定 对象(通过 GroupVersionKind 指定)的 Kubernetes API Watch 接口来提供此对象的创建、 更新、删除事件。
① Source 通过 Watch API 提供 Kubernetes 指定对象的事件流。
② 建议开发者使用 Controller-runtime 中已有的 Source 实现,而不是自己实现此接口。
(8) EventHandler:handler.EventHandler 是 Controller.Watch 的 参 数, 用 于 将 事 件对应的 reconcile.Requests 加入队列。例如,从 Source 中接收到一个 Pod 的创建事 件,eventhandler.EnqueueHandler 会 根 据 Pod 的 Name 与 Namespace 生 成 reconcile. Requests 后,加入队列。
① EventHandlers 处理事件的方式是将一个或多个 reconcile.Requests 加入队列。
② 在 EventHandler 的处理中,事件所属的对象的类型(比如 Pod 的创建事件属于 Pod 对象),可能与 reconcile.Requests 所加入的对象类型相同。
③ 事件所属的对象的类型也可能与 reconcile.Requests 所加入的对象类型不同。例如 将 Pod 的事件映射为所属的 ReplicaSet 的 reconcile.Requests。
④ EventHandler 可能会将一个事件映射为多个 reconcile.Requests 并加入队列,多个 reconcile.Requests 可能属于一个对象类型,也可能涉及多个对象类型。例如,由于集群扩 展导致的 Node 事件。
⑤ 在大多数情况下,建议开发者使用 Controller-runtime 中已有的 EventHandler 来 实现,而不是自己实现此接口。
(9) Predicate:predicate.Predicate 是 Controller.Watch 的参数,是用于过滤事件的 过滤器,过滤器可以复用或者组合。
① Predicate 接口以事件作为输入,以布尔值作为输出,当返回 True 时,表示需要将 事件加入队列。
② Predicate 是可选的。
③ 建议开发者使用 Controller-runtime 中已有的 Predicate 实现,但可以使用其他 Predicate 进行过滤。
Controller-runtime 核心流程如下:
-
Source 通过 Kubernetes APIServer 监听指定资源对象
-
EventHandler 根据资源对象变化事件,将 reconcile.Request 加入队列
-
从队列中获取 reconcile.Request,并调用 Reconciler 进行同步
2. Controller-runtime 底层原理
2.1 manager相关结构体介绍
Manager的方法
type Manager interface { cluster.Cluster //cluster.Cluster 提供了一系列方法,以获取与集群相关的对象。 Add(Runnable) error //添加controller Elected() <-chan struct{} // 选举相关, 返回一个 Channel 结构,用于判断选举状态。当未配 置选举或当选 Leader 时,Channel 将被关闭。 AddMetricsExtraHandler(path string, handler http.Handler) error // metrics相关 AddHealthzCheck(name string, check healthz.Checker) error // 健康检查相关 AddReadyzCheck(name string, check healthz.Checker) error // 是否就绪 Start(ctx context.Context) error // 启动所有的controller GetWebhookServer() *webhook.Server GetL