K8S上的分散式系統應用編排
隨著容器技術的發展,容器的優勢:易打包、可複製、隔離性、低開銷,使得不斷的有應用開始從傳統的物理機、虛擬機器,逐漸的搬遷到容器上。而 Kubernetes 的誕生和發展壯大,又降低了應用的標準化部署管理的難度,大大加速了應用搬遷到容器的程序。將一個存在前臺、後臺、資料庫的分散式系統一鍵式部署到 K8S 上時,可以有哪些方法和途徑呢?
K8S上的應用模型
Kubernetes 對容器應用的編排,是將應用的執行時、配置、服務提供、儲存、映象等都定義成了多種資源物件,每種資源物件都可以按照一定的格式進行描述定義。比如環境變數可以定義到 configmap 物件,也可以定義在容器的配置中;而應用的執行時,則是多種工作負載:Deployment、StatefulSet、DaemonSet 等。

資源型別 | 功能 |
---|---|
Deployment | 定義應用的容器映象、資源要求、執行時環境等工作負載相關,無狀態記錄,可任意擴縮容 |
StatefulSet | 定義應用的容器映象、資源要求、執行時環境等工作負載相關,存在狀態資訊記錄,按序啟動與伸縮 |
DaemonSet | 定義應用的容器映象、資源要求、執行時環境等工作負載相關,一般是代理類應用,會在每個節點上執行例項 |
Job | 定義應用的容器映象、資源要求、執行時環境等工作負載相關,短時任務類,執行完成即退出 |
ConfigMap | 定義配置,可用於掛載到容器的環境變數或者檔案中 |
Secret | 定義敏感配置資訊,可用於掛載到容器的環境變數或者檔案中 |
Service | 定義應用的訪問入口 |
Ingress | 定義應用的http訪問入口 |
... ... |
一個應用就會至少有一個工作負載,以及一些配置,訪問入口等資源物件。通過控制這些資源物件,就可以完成一個應用,或者多個應用的統籌管理,這就是k8s上的應用編排。最原始的方式當然是直接操控每一個的資源物件,但是,多個分散的檔案,又沒有變數替換功能,就意味著這些檔案只能在一套環境上執行,一旦環境有變化,還需要手動修改檔案的內容;這些物件之間還必須以一定的先後順序執行,否則會失敗。當應用更多時,執行的流程就會更加的複雜。
分散式系統的編排要求
下面是一個典型的分散式系統,包括前端程式、後臺程式、後臺資料庫,負載均衡器等。在應用系統發展到一定程度,自然而然的就會對系統的各部件角色進行拆分,對於每種角色,都可以進行一定的水平或者垂直的擴充套件,保證應用的擴充套件性,解除系統的單點問題。

這樣的一個系統,對應用編排有這些要求:
-
系統中可以定義多種應用
-
每個應用的多個資源物件之間,可以定義控制依賴關係
-
不同應用之間存在配置上的傳遞
-
不同應用之間存在啟動順序上的先後依賴關係
Helm:社群原生的包管理工具
由於 K8S 的資源物件都具備著一定的格式化規範,社群提供了 Helm 用於處理 k8s 應用的打包,這個包叫做一個 chart。Chart 的包格式如下:一個 Chart.yaml
檔案,使用者定義包的名稱、版本等資訊,一個 templates
目錄,裡面定義了這個應用所有相關的資源描述的 go-template 語法的模板,而模板使用到的變數,則在 values.yaml
檔案中進行宣告定義。

Helm 的實現原理很簡單,在客戶端實現變數的渲染替換,再將完整的內容傳遞到服務端(tiller),由 tiller 將生成的 k8s 物件按照一定的順序呼叫 k8s 介面,完成應用的編排建立。

helm 還支援了 dependency 的依賴關係,用於 chart 包之間的引用。而應用之間的引數傳遞,也可以通過共享相同的變數輸入來完成。這樣,分散式系統要求的1,2,3,4看起來也都滿足了。
但是,在helm的實際應用中,存在著下面的幾個問題。
-
應用中的任務下發,只控制了請求的傳送順序,並不能保證建立完成的先後順序。這就導致了有時候 secret 之類的物件尚未處理完成,deployment 就去引用而失敗的情況。
-
對於 Deployment 之類的工作負載,helm 沒有去真正的判斷例項是否啟動就緒完成了,即使應用例項因為某些原因失敗了,helm也感知不到。
-
Helm 的 dependency 依賴,只控制了 chart 包的引用,實際上的多個應用一起建立時,還是全部展開按照型別順序統一執行的。
-
Chart 包的模板編寫,一方面需要使用者對k8s的資源物件結構有一定的理解基礎,另一方面go-template的引入使得模板變成了非格式化的結構,無法正常的進行校驗處理,導致容易出錯。
對於 Helm 在處理分散式系統中遇到的問題,並非難解。 核心在於一套完善的DAG框架,能夠精確控制所有的步驟流程,以及每個步驟的結果管理和傳遞。 而這套框架最好是格式化的簡單的結構,不需要那麼複雜,要精通 K8S、go-templat e等等,最好有圖形化的介面,可以輔助編寫。
應用編排服務:解決依賴和配置傳遞
華為雲上的應用編排服務(以下簡稱 AOS),就是這樣一個能夠滿足複雜分散式應用在 K8S 上的各種要求的系統。AOS 服務對接了華為雲的雲容器引擎(CCE服務),提供了一套規範化的模型結構,可定義 K8S 上的各種資源物件。通過模型設計的模板,可以實現複雜分散式系統的一鍵式編排建立在 K8S 叢集上。
-
優秀的圖形化設計器,通過圖形化拖拽即可設計應用結構,將應用所需的各種資源,精確控制所有物件的執行順序關係,實現最大化的並行。
-
通過編排語法可以將應用之間的共享引數、應用的輸出訪問地址等資訊進行傳遞輸出。
-
良好的變數輸入輸出機制,將應用在不同環境中的部署所需配置提煉,實現一套模板,多處複用。
前面的分散式系統,在 AOS 編排設計後,就可以成為下面的這個圖。這樣的一個分散式系統,將依次建立 DB 資料庫,執行建立資料庫表結構的job,而資料庫的訪問資訊將記錄到secret中,由兩個後端程式 app1-back2,app-backend1
掛載使用。兩個後端程式還同時引用了共同的配置 appconfig。前臺應用通過 ingress 和 service 去訪問後端程式,並提供了 ingress 用於外部訪問。這個圖中沒有體現負載均衡器,因為這裡的 ingress 配置了連線華為雲的 ELB 服務。

應用編排系統還支援編排管理雲上的各種服務,比如 RDS 資料庫,ELB 負載均衡器等,利用這些服務,將簡化分散式系統的雲上架構,幫助使用者聚焦在自身的業務,不再需要花大力氣在業務的交付和部署運維上。