昨天介紹了Kubernetes的運作與設計原理,了解到最主要的運作模式就是靠etcd、APIServer、Controller的合作完成了K8s上面所有任務。
今天我們就來介紹這個Controller裡面是長什麼樣子吧
每一個K8s裡面的Controller一定都會搭配一個Resource,也就是API Server裡面REST API的那個Object。
而每一個Controller也就只負則管理相對應Object的生命週期。
在K8s 1.10版本以後
使用者正式可以在K8s透過創建一個Custom Resource Definition (CRD) 來自定義自己的Resource並註冊在API Server中。
接著也可以基於Controller的設計原理開發自己的Custom Controller。
而搭配了 CRD 與 Custom Controller 的客製化運作模式就叫做Operator Pattern,由CoreOS發起與推廣。
而Controller到底內部有什麼?
下圖就是一個Controller的組成
Informers: Informer的任務就是訂閱Resource的Add/Update/Delete事件,並接收事件的主要元件。透過HTTP Watch/List方法,取得事件與物件後,放進一個Delta Queue裡
Workqueue: 前面提到的callback function當然可以獨立寫成三個相對應的function去執行動作。但是也提供另一種方法是,三個callback function皆是將物件放進Workqueue中,另外撰寫一個Controller Infinite Loop不斷從Queue中取得物件來進行 Real World = Desired World
的維護狀態邏輯
Real World = Desired World
的維護狀態邏輯。可以平行開好幾個Goroutines增加效能。而除了Informer K8s的client-go library已經幫你維護好了以外,Workqueue與Controller皆是開發者可以自行設計的部分。
以下用程式碼描述Controller從Workqueue到Control Loop的邏輯。
一個Controller會有
這邊撰寫時,針對三個Callback Functions皆直接將物件放進Queue中。
啟動Controller,可以自定義threadiness
來平行啟動好幾個Goroutines來處理Queue中的物件。
而每一個Goroutine皆執行runWorker
這個函式,其實動作就從Queue中取出物件執行 Real World = Desired World
的邏輯。
裡面可以看到很多對應前面Queue API的流程圖,表示從Queue中取出物件處理。
而最重要的就是syncHandler,就是比對現實系統中這個物件的狀態與他的Spec,並呼叫K8s API來完成狀態的維護。
比方說
kubectl describe deployment/XXXXX
會發現他的Status出現 pod id5 has been created
這個就是在這個邏輯中完成加上去的。以上就是K8s Controller的設計與實作,更詳細的實作可以直接參考K8s官方的像是Job Controller/Deployment Controller
。
或是參考一些Custom Controller像是etcd Operator
、rook Operator
都是很好的參考對象。
透過CRD+Custom Controller,開發者可以把一整個分散式系統應用當作一個Resource Unit像是Pod那樣來做部署與維護。是一個很強大的設計。