摘錄自羅建龍等著的《雲原生作業系統Kubernetes》,詳細瞭解請檢視原著。
雖然控制器是Kubernetes比較複雜的元件,但是控制器這個概念本身,對我們來說並不陌生。我們生活中使用的洗衣機、冰箱、空調等,都要有控制器才能正常工作。
以下我們透過思考一個簡易冰箱的設計過程,來理解Kubernetes叢集控制器的原理和實現。
設計一臺冰箱
如下圖所示是一臺簡易冰箱。
冰箱包括五個元件,分別是箱體、製冷系統、照明系統、溫控器和門。
冰箱有兩個典型使用場景:
- 當有人開啟冰箱門的時候,冰箱內的燈會自動開啟;
- 當有人調節溫控器的時候,製冷系統會根據溫度設定調節冰箱內的溫度。
統一操作入口
實際上,我們可以把冰箱簡單抽象成下圖圖中的兩個部分:統一的操作入口和其他元件。使用者只有透過操作入口才能操作冰箱,這個入口為使用者提供了開關門和調節溫控器這兩個介面。使用者呼叫這兩個介面的時候,入口邏輯會調整冰箱門或溫控器的狀態。
但是這裡有一個問題,就是使用者透過這兩個介面,既不能讓冰箱內部的燈開啟,也不能調節冰箱內的溫度,因為這兩個介面和照明或者製冷系統沒有任何必然的聯絡。
引入控制器
如下圖所示,控制器就是為了解決上面的問題而產生的。控制器是使用者操作和冰箱各個元件狀態之間的一座橋樑。當使用者開啟門的時候,控制器“觀察”到了門的變化,幫助使用者開啟冰箱內的燈;當使用者調節溫控器的時候,控制器“觀察”到了使用者設定的溫度,替使用者管理製冷系統以便調整冰箱內溫度。
統一管理控制器
因為冰箱有照明系統和製冷系統,所以與一個控制器管理著兩個元件相比,為每個元件分別設定一個控制器是更為合理的選擇。同時為了方便管理,可以設定一個控制器管理器來統一維護所有這些控制器,以確保這些控制器在正常工作。
Shared Informer
有了控制器和控制器管理器之後,冰箱的設計看起來已經相當不錯了。但是隨著冰箱功能的增加,必然會有新的控制器不斷地加進來。這些控制器都需要透過冰箱入口,時刻監控自己“關心”的元件的狀態變化,就如同照明系統控制器在時刻監控冰箱門狀態一樣。當大量控制器不斷地和操作入口通訊的時候,就會增加操作入口的壓力。
如下圖所示,這時我們可以把監控冰箱元件狀態變化這件事情,交給一個新的模組Shared Informer來做。Shared Informer作為控制器的代理,替控制器監控冰箱元件的狀態變化,並根據控制器的“喜好”,把不同元件狀態的變化通知對應的控制器。
Shared Informer模組的增加,實際上可以極大地緩解冰箱操作入口的壓力。
List Watcher
Shared Informer方便了控制器對冰箱元件的監控,而這個機制最核心的功能,當然是主動獲取元件狀態和被動接收元件狀態變化的通知。這兩個功能加起來,就是List Watcher機制。
假設Shared Informer和冰箱入口透過HTTP協議通訊的,那麼HTTP分塊編碼(chunked transfer encoding)就是實現List Watcher的一個好的選擇。
控制器透過List Watcher給冰箱入口傳送一個查詢請求然後等待,當冰箱元件有變化的時候,入口透過分塊的HTTP響應通知控制器。控制器“看到”Chunked響應,會認為響應資料還沒有傳送完成,所以會持續等待。