pod 這個看似複雜的 api 物件,實際上就是對容器的進一步抽象和封裝而已。而 kubernetes 操作這些「貨櫃」的邏輯,都由控制器(controller)完成。我們曾經使用過 deployment 這個最基本的控制器物件。說得更形象些,「容器」映象雖然好用,但是容器這樣乙個「沙盒」的概念,對於描述應用來說,還是太過簡單了。這就好比,貨櫃固然好用,但是如果它四面都光禿禿的,吊車還怎麼把這個貨櫃吊起來並擺放好呢?
所以,pod 物件,其實就是容器的公升級版。它對容器進行了組合,新增了更多的屬性和字段。這就好比給貨櫃四面安裝了吊環,使得 kubernetes 這架「吊車」,可以更輕鬆地操作它。
nginx-deployment 的例子:
kind: deployment
metadata:
name: nginx-deployment
spec:
selector:
matchlabels:
replicas: 2
template:
metadata:
labels:
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerport: 80
問題:究竟是 kubernetes 專案中的哪個元件,在執行這些操作呢?
答案:我在前面介紹 kubernetes 架構的時候,曾經提到過乙個叫作 kube-controller-manager 的元件。
實際上,這個元件,就是一系列控制器的集合。我們可以檢視一下 kubernetes 專案的 pkg/controller 目錄:
cd kubernetes/pkg/controller/
ls -d */
deployment/ job/ podautoscaler/
cloud/ disruption/ namespace/
replicaset/ serviceaccount/ volume/
cronjob/ garbagecollector/ nodelifecycle/ replication/ statefulset/ daemon/
...
這個目錄下面的每乙個控制器,都以獨有的方式負責某種編排功能。而我們的 deployment,正是這些控制器中的一種。
實際上,這些控制器之所以被統一放在 pkg/controller 目錄下,就是因為它們都遵循 kubernetes 專案中的乙個通用編排模式,即:控制迴圈(control loop)。
比如,現在有一種待編排的物件 x,它有乙個對應的控制器。那麼,我就可以用一段 go 語言風格的偽**,為你描述這個控制迴圈:
for else
}
在具體實現中,實際狀態往往來自於 kubernetes 集群本身。kubelet 通過心跳匯報的容器狀態和節點狀態,或者監控系統中儲存的應用監控資料,或者控制器主動收集的它自己感興趣的資訊,這些都是常見的實際狀態的**。
而期望狀態,一般來自於使用者提交的 yaml 檔案。
deployment 物件中 replicas 欄位的值。很明顯,這些資訊往往都儲存在 etcd 中。
接下來,以 deployment 為例,我和你簡單描述一下它對控制器模型的實現:
deployment 物件的 replicas 欄位的值就是期望狀態;
乙個 kubernetes 物件的主要編排邏輯,實際上是在第三步的「對比」階段完成的。
這個操作,通常被叫作調諧(reconcile)。這個調諧的過程,則被稱作「reconcile loop」(調諧迴圈)或者「sync loop」(同步迴圈)。
所以,如果你以後在文件或者社群中碰到這些詞,都不要擔心,它們其實指的都是同乙個東西:控制迴圈。
而調諧的最終結果,往往都是對被控制物件的某種寫操作。
比如,增加 pod,刪除已有的 pod,或者更新 pod 的某個字段。這也是 kubernetes 專案「面向 api 物件程式設計」的乙個直觀體現。
其實,像 deployment 這種控制器的設計原理,就是我們前面提到過的,「用一種物件管理另一種物件」的「藝術」。
其中,這個控制器物件本身,負責定義被管理物件的期望狀態。比如,deployment 裡的 replicas=2 這個字段。
而被控制物件的定義,則來自於乙個「模板」。比如,deployment 裡的 template 字段。
可以看到,deployment 這個 template 欄位裡的內容,跟乙個標準的 pod 物件的 api 定義,絲毫不差。而所有被這個 deployment 管理的 pod 例項,其實都是根據這個 template 欄位的內容建立出來的。
像 deployment 定義的 template 字段,在 kubernetes 專案中有乙個專有的名字,叫作 podtemplate(pod 模板)。
這個概念非常重要,因為後面我要講解到的大多數控制器,都會使用 podtemplate 來統一定義它所要管理的 pod。更有意思的是,我們還會看到其他型別的物件模板,比如 volume 的模板。
至此,我們就可以對 deployment 以及其他類似的控制器,做乙個簡單總結了:
類似 deployment 這樣的乙個控制器,實際上都是由上半部分的控制器定義(包括期望狀態),加上下半部分的被控制物件的模板組成的。
這就是為什麼,在所有 api 物件的 metadata 裡,都有乙個字段叫作 ownerreference,用於儲存當前這個 api 物件的擁有者(owner)的資訊。
那麼,對於我們這個 nginx-deployment 來說,它建立出來的 pod 的 ownerreference 就是 nginx-deployment 嗎?或者說,nginx-deployment 所直接控制的,就是 pod 物件麼?
在今天這篇文章中,我以 deployment 為例,和你詳細分享了 kubernetes 專案如何通過乙個稱作「控制器模式」(controller pattern)的設計方法,來統一地實現對各種不同的物件或者資源進行的編排操作。
在後面的講解中,我還會講到很多不同型別的容器編排功能,比如 statefulset、daemonset 等等,它們無一例外地都有這樣乙個甚至多個控制器的存在,並遵循控制迴圈(control loop)的流程,完成各自的編排邏輯。
實際上,跟 deployment 相似,這些控制迴圈最後的執行結果,要麼就是建立、更新一些 pod(或者其他的 api 物件、資源),要麼就是刪除一些已經存在的 pod(或者其他的 api 物件、資源)。
但也正是在這個統一的編排框架下,不同的控制器可以在具體執行過程中,設計不同的業務邏輯,從而達到不同的編排效果。
這個實現思路,正是 kubernetes 專案進行容器編排的核心原理。在此後講解 kubernetes 編排功能的文章中,我都會遵循這個邏輯展開,並且帶你逐步領悟控制器模式在不同的容器化作業中的實現方式。
控制器與模型
先走通乙個案例 控制器 測試function testcontroller scope controller.js 模組 module 方法的第乙個引數為模組的名稱,第二個引數為它的依賴模組列表。我們建立了乙個獨立的模組,不依賴於其它模組。所以第二個引數為空陣列 注意 即使它為空,我們也必須填寫這個...
jmeter控制器 交替控制器
1.簡單使用 如下圖,設定1個執行緒,執行3次 執行結果如下圖 2.巢狀乙個控制器,不勾選忽略子控制器 測試計畫如下圖 巢狀乙個迴圈控制器,迴圈次數設定3次 執行緒組設定1個執行緒,執行5次 執行結果如下圖 總結 交替執行到迴圈控制器時,迴圈執行結束後,在進行下一次的交替。3.巢狀乙個控制器,勾選忽...
子控制器 和 父控制器
1 新增子控制器很簡單 分兩步 乙個是 view 乙個是 controller 1 self addchildviewcontroller tablectr 2 self.view addsubview tablectr.view 最後不要忘了加一行 tablectr didmovetoparent...