「控制器」模型

2022-09-21 07:03:11 字數 3795 閱讀 6655

pod 這個看似複雜的 api 物件,實際上就是對容器的進一步抽象和封裝而已。

說得更形象些,「容器」映象雖然好用,但是容器這樣乙個「沙盒」的概念,對於描述應用來說,還是太過簡單了。這就好比,貨櫃固然好用,但是如果它四面都光禿禿的,吊車還怎麼把這個貨櫃吊起來並擺放好呢?

所以,pod 物件,其實就是容器的公升級版。它對容器進行了組合,新增了更多的屬性和字段。這就好比給貨櫃四面安裝了吊環,使得 kubernetes 這架「吊車」,可以更輕鬆地操作它。

而 kubernetes 操作這些「貨櫃」的邏輯,都由控制器(controller)完成。我們曾經使用過 deployment 這個最基本的控制器物件。

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...