天天看點

帶你讀《雲原生應用開發 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()。重新加入的次數無限制。