做者 | 阿里雲售後技術專家 聲東數據庫
導讀:當咱們嘗試去理解 K8s 集羣工做原理的時候,控制器(Controller)確定是一個難點。這是由於控制器有不少,具體實現截然不同;且控制器的實現用到了一些較爲晦澀的機制,不易理解。可是,咱們又不能繞過控制器,由於它是集羣的「大腦」。今天這篇文章,做者經過分析一個簡易冰箱的設計過程,來幫助讀者深刻理解集羣控制器的產生,功能以及實現方法。後端
下圖是 K8s 集羣的核心組件,包括數據庫 etcd,調度器 Scheduler,集羣入口 API Server,控制器 Controller,服務代理 kube-proxy 以及直接管理具體業務容器的 kubelet。api
這些組件邏輯上能夠被分爲三個部分:網絡
今天咱們要講的就是集羣控制器原理。優化
雖然控制器是 K8s 集羣中比較複雜的組件,但控制器自己對咱們來講並不陌生的。咱們天天使用的洗衣機、冰箱、空調等,都是依靠控制器才能正常工做。在控制器原理這一節,咱們經過思考一個簡易冰箱的設計過程,來理解 K8s 集羣控制器的原理。阿里雲
這個冰箱包括五個組件:箱體、製冷系統、照明系統、溫控器以及門。編碼
冰箱只有兩個功能:設計
對於上邊的冰箱,咱們能夠簡單抽象成兩個部分:統一的操做入口和冰箱的全部組件。3d
在這裏,用戶只有經過入口,才能操做冰箱。這個入口提供給用戶兩個接口:開關門和調節溫控器。用戶執行這兩個接口的時候,入口會分別調整冰箱門和溫控器的狀態。代理
可是這裏有一個問題,就是用戶經過這兩個接口,既不能讓冰箱內部的燈打開,也不能調節冰箱的溫度。
控制器就是爲了解決上邊的問題產生的。控制器就是用戶的操做,和冰箱各個組件的正確狀態之間的一座橋樑:
冰箱有照明系統和製冷系統,顯然相比一個控制器管理着兩個組件,咱們替每一個組件分別實現一個控制器是更爲合理的選擇。同時咱們實現一個控制器管理器來統一維護全部這些控制器,來保證這些控制器在正常工做。
上邊的控制器和控制器管理器,看起來已經至關不錯了。可是當冰箱功能增長,勢必有不少新的控制器加進來。這些控制器都須要經過冰箱入口,時刻監控本身關心的組件的狀態變化。好比照明系統控制器就須要時刻監控冰箱門的狀態。當大量控制器不斷的和入口通訊的時候,就會增長入口的壓力。
這個時候,咱們把監控冰箱組件狀態變化這件事情,交給一個新的模塊 SharedInformer 來實現。
SharedInformer 做爲控制器的代理,替控制器監控冰箱組件的狀態變化,並根據控制器的喜愛,把不一樣組件狀態的變化,通知給對應的控制器。經過優化,這樣的 SharedInformer 能夠極大的緩解冰箱入口的壓力。
SharedInformer 方便了控制器對冰箱組件的監控,而這個機制最核心的功能,固然是主動獲取組件狀態和被動接收組件狀態變化的通知。這兩個功能加起來,就是 ListWatcher。
假設 SharedInformer 和冰箱入口經過 http 協議通訊的話,那麼 http 分塊編碼(chunked transfer encoding)就是實現 ListWatcher 的一個好的選擇。控制器經過 ListWatcher 給冰箱入口發送一個查詢而後等待,當冰箱組件有變化的時候,入口經過分塊的 http 響應通知控制器。控制器看到 chunked 響應,會認爲響應數據尚未發送完成,因此會持續等待。
以上咱們從一個簡易冰箱的進化過程當中,瞭解了控制器產生的意義,扮演的角色,以及實現的方式。如今咱們回到K8s 集羣。K8s 集羣實現了大量的控制器,並且在能夠預見的將來,新的功能的控制器會不斷出現,而一些舊的控制器也會被逐漸淘汰。
目前來講,咱們比較經常使用的控制器,如 Pod 控制器、Deployment 控制器、Service 控制器、Replicaset 控制器等。這些控制器一部分是由 kube controller manager 這個管理器實現和管理,而像 route 控制器和 service 控制器,則由 cloud controller manager 實現。
之因此會出現 cloud controller manager,是由於在不一樣的雲環境中,一部分控制器的實現,會由於雲廠商、雲環境的不一樣,出現很大的差異。這類控制器被劃分出來,由雲廠商各自基於 cloud controller manager 分別實現。
這裏咱們以阿里雲 K8s 集羣 cloud controller manager 實現的 route 控制器和 service 控制器爲例,簡單說明 K8s 控制器的工做原理。
首先,用戶請求 API Server 建立一個 LoadBalancer 類型的服務,API Server 收到請求並把這個服務的詳細信息寫入 etcd 數據庫。而這個變化,被服務控制器觀察到了。服務控制器理解 LoadBalancer 類型的服務,除了包括存放在 etcd 內部的服務記錄以外,還須要一個 SLB 做爲服務入口,以及若干 endpoints 做爲服務後端。因此服務控制器分別請求 SLB 的雲 openapi 和 API Server,來建立雲上 SLB 資源,和集羣內 endpoints 資源。
在集羣網絡一章中,咱們提到過,當一個節點加入一個 K8s 集羣的時候,集羣須要在 VPC 路由表裏增長一條路由,來搭建這個新加入節點到 Pod 網絡的主幹道。而這件事情,就是路由控制器來作的。路由控制器完成這件事情的流程,與上邊服務控制器的處理流程很是相似,這裏再也不贅述。
基本上來講,K8s 集羣的控制器,其實扮演着集羣大腦的角色。有了控制器,K8s 集羣纔有機會擺脫機械和被動,變成一個自動、智能、有大用的系統。