带你读《云原生应用开发 Operator原理与实践》第三章 Kubebuilder 原理3.3 Controller-runtime 模块分析(五)

3.3.3        Controller

Controller是 Controller-runtime的核心结构, 其实现了 Controller的基本逻辑:Controller管理一个工作队列,并从 source.Sources中获取 reconcile.Requests加入队列,通过执行 reconcile.Reconciler来处理队列中的每项 reconcile.Requests,而 reconcile.

Reconciler可以通过读写 Kubernetes 资源来确保集群状态与期望状态一致。

接口:

Controller接口定义在 pkg/controller/controller.go下,包括如下内容。

(1)         reconcile.Reconciler:匿名接口,定义了 Reconcile(context.Context,Request)

(Result,error

(2)      Watch(srcsource.Source,eventhandlerhandler.EventHandler,predicates

...predicate.Predicate)error:定义入队 reconcile.Requests,Watch() 方法会从 sour-ce.Source中获取Event, 并根据参数 Eventhandler来决定如何入队, 根据参数Predicates进行 Event过滤,Preficates可能有多个, 只有所有的 Preficates都返回True 时,才会将 Event 发送给 Eventhandler 处理。

(3)      Start(ctxcontext.Context)error:Controller的启动方法,实现了 Controller接口的对象,也实现了Runnable,因此,该方法可以被Manager管理。

(4)       GetLogger()logr.Logger:获取 Controller内的 Logger,用于日志输出。

实现:

Controller的实现在 pkg/internal/controller/controller.go下,为结构体 Controller,Controller结构体中包括的主要成员如下。

(1)   Namestring:必须设置, 用于标识 Controller,会在 Controller的日志输出中进行关联。

(2)  MaxConcurrentReconcilesint:定义允许 reconcile.Reconciler 同时运行的最多个数,默认为 1。

(3)  Doreconcile.Reconciler:定义了 Reconcile() 方法,包含了 Controller同步的业务逻辑。Reconcile()能在任意时刻被调用,接收一个对象的 Name与 Namespace,并同步集群当前实际状态至该对象被设置的期望状态。

(4)  MakeQueue    func()    workqueue.RateLimitingInterface:用 于在    Controller启动时,创建工作队列。由于标准的Kubernetes工作队列创建后会立即启动,因此,如果在 Controller启动前就创建队列,在重复调用 controller.New() 方法创建 Con-troller 的情况下,就会导致 Goroutine 泄露。

(5)  Queueworkqueue.RateLimitingInterface:使用上面方法创建的工作队列。

(6)  SetFieldsfunc(iinterface{})error:用 于 从 Manager中 获 取 Controller赖的方法, 依赖包括 Sourcess、EventHandlers和 Predicates等。 此方法存储的是controllerManager.SetFields()方法。

(7)  StartedBool:用于表示Controller 是否已经启动。

(8)  CacheSyncTimeouttime.Duration:定义了 Cache 完成同步的等待时长,超过时长会被认为是同步失败。默认时长为 2分钟。

(9)  startWatches[ ]watchDescription:定 义 了 一 组Watch操 作 的 属 性, 会在Controller启动时, 根据属性进行 Watch操作。watchDescription的定义见代码 清单3-30,watchDescription包括 Event的源 source.Source、Event的入队方法handler.EventHandler以及 Event的过滤方法 predicate.Predicate。

typewatchDescriptionstruct{srcsource.Source

handlerhandler.EventHandlerpredicates[]predicate.Predicate


}

 

(10)  LogLogr.Logger:用于记录日志的日志对象。

Controller的主要逻辑在Controller.Start()方法内,流程如图 3-4所示。

带你读《云原生应用开发 Operator原理与实践》第三章 Kubebuilder 原理3.3 Controller-runtime 模块分析(五)

 

                                 图 3—4Controiier 逻辑

 

(1) Manager调用 Start()方法后,进入 Controller 的启动流程,经过选举等预处理后,Controller进入Start()方法。

(2)  Controller根据 MakeQueue() 创建工作队列,并启动工作队列。

(3) Controller根据 startWatches参数启动各个 Watch 流程,并将工作队列注入各个Watcher中。 

(4) Controller根据 MaxConcurrentReconciles启动多个 Worker程序,用于处理队列中的对象。

(5) Work程序先从工作队列中获取需要处理的对象,然后调用 Controller成员 Do的 Reconcile()方法进行处理。

(6)  根据 Reconcile() 方法返回的结果, 将对象重新入队列或从队列中删除。重新入队列的方法可以是带有一定延迟的Queue.AddAfter(), 也可以是有限速的 Queue.AddRateLimited()。重新加入的次数无限制。

上一篇:带你读《云原生应用开发 Operator原理与实践》第三章 Kubebuilder 原理3.3 Controller-runtime 模块分析(三)


下一篇:web安全防御与优化