在這個領域,Kubernetes 用 Helm 的來管理和打包應用,可是 Helm 並非十全十美的,在使用過程當中咱們發現它並不能徹底知足咱們的需求,因此在 Helm 的基礎上,咱們本身研發了一套編排組件……node
什麼是編排?git
不知道你們有沒仔細思考過編排究竟是什麼意思? 我查閱了 Wiki 百科,瞭解到咱們常說的編排的英文單詞爲 「Orchestration」,它常被解釋爲:github
有趣的是 「Orchestration」 的標準翻譯應該爲「編配」,而「編排」則是另一個單詞 「Choreography」,爲了方便你們理解, 符合平時的習慣,咱們仍是使用編排 (Orchestration) 來描述下面的問題。至於「編配 (Orchestration)」 和 「編排(Choreography)」 之爭,這裏有一篇文章,有興趣能夠看一下 。數據庫
編配和編排的定義之爭當咱們在說容器編排的時候,咱們在說什麼?設計模式
在傳統的單體式架構的應用中,咱們開發、測試、交付、部署等都是針對單個組件,咱們不多聽到編排這個概念。而在雲的時代,微服務和容器大行其道,除了爲咱們顯示出了它們在敏捷性,可移植性等方面的巨大優點之外,也爲咱們的交付和運維帶來了新的挑戰:咱們將單體式的架構拆分紅愈來愈多細小的服務,運行在各自的容器中,那麼該如何解決它們之間的依賴管理,服務發現,資源管理,高可用等問題呢?安全
在容器環境中,編排一般涉及到三個方面:網絡
在 Kubernetes 中有 5 種咱們常常會用到的控制器來幫助咱們進行容器編排,它們分別是 Deployment, StatefulSet, DaemonSet, CronJob, Job。架構
在這 5 種常見資源中,Deployment 常常被做爲無狀態實例控制器使用; StatefulSet 是一個有狀態實例控制器; DaemonSet 能夠指定在選定的 Node 上跑,每一個 Node 上會跑一個副本,它有一個特色是它的 Pod 的調度不通過調度器,在 Pod 建立的時候就直接綁定 NodeName;最後一個是定時任務,它是一個上級控制器,和 Deployment 有些相似,當一個定時任務觸發的時候,它會去建立一個 Job ,具體的任務其實是由 Job 來負責執行的。他們之間的關係以下圖:運維
一個簡單的例子微服務
咱們來考慮這麼一個簡單的例子,一個須要使用到數據庫的 API 服務在 Kubernetes 中應該如何表示:
客戶端程序經過 Ingress 來訪問到內部的 API Service, API Service 將流量導流到 API Server Deployment 管理的其中一個 Pod 中,這個 Server 還須要訪問數據庫服務,它經過 DB Service 來訪問 DataBase StatefulSet 的有狀態副本。由定時任務 CronJob 來按期備份數據庫,經過 DaemonSet 的 Logging 來採集日誌,Monitoring 來負責收集監控指標。
Kubernetes 爲咱們帶來了什麼?
經過上面的例子,咱們發現 Kubernetes 已經爲咱們對大量經常使用的基礎資源進行了抽象和封裝,咱們能夠很是靈活地組合、使用這些資源來解決問題,同時它還提供了一系列自動化運維的機制:如 HPA, VPA, Rollback, Rolling Update 等幫助咱們進行彈性伸縮和滾動更新,並且上述全部的功能均可以用 YAML 聲明式進行部署。
困境
可是這些抽象仍是在容器層面的,對於一個大型的應用而言,須要組合大量的 Kubernetes 原生資源,須要很是多的 Services, Deployments, StatefulSets 等,這裏面用起來就會比較繁瑣,並且其中服務之間的依賴關係須要用戶本身解決,缺少統一的依賴管理機制。
什麼是應用?
一個對外提供服務的應用,首先它須要一個可以與外部通信的網絡,其次還須要能運行這個服務的載體 (Pods),若是這個應用須要存儲數據,這還須要配套的存儲,因此咱們能夠認爲:
應用單元 = 網絡 + 服務載體 +存儲
那麼咱們很容易地能夠將 Kubernetes 的資源聯繫起來,而後將他們劃分爲 4 種類型的應用:
咱們來從新審視一下以前的例子:
應用層面的四個問題
經過前面的探索,咱們能夠引出應用層面的四個問題:
在社區中,這四個方面的問題分別由三個組件或者項目來解決:
Helm Charts
Charts 在本質上是一個 tar 包,包含了一些 yaml 的 template 以及解析 template 須要的 values, 以下圖:templates 是 Golang 的 template 模板,values.yaml 裏面包含了這個 Charts 須要的值。
Helm Registry
用來負責存儲和管理用戶的 Charts, 並提供簡單的版本管理,與容器領域的鏡像倉庫相似這個項目是開源的。( https://github.com/caicloud/helm-registry)
Tiller
Tiller 的缺陷
Release Controller
爲了解決上述的問題,咱們基於 Kubernetes 的 Custom Resource Definition 設計並實現了咱們本身的運行時管理系統 – Release Controller, 爲此咱們設計了兩個新的 CRD – Release 和 Release History。
Release 建立
當 Release CRD 被建立出來,controller 爲它建立一個新的 Release History, 而後將 Release 中的 Chart 和 Configuration 解析成 Kubernetes 的資源,而後將這些資源在集羣中建立出來,同時會監聽這些資源的變化,將它們的狀態反映在 Release CRD 的 status 中。
Release 更新
當用戶更新 Release 的時候,controller 計算出更新後的資源與集羣中現有資源的 diff, 而後刪除一部分,更新一部分,建立一部分,來使得集羣中的資源與 Release 描述的一致,同時爲舊的 Release 建立一份 Release History。
Release 回滾和刪除
用戶但願回滾到某一個版本的 Release, controller 從 Release History 中找到對應的版本,而後將 Release 的 Spec 覆蓋,同時去更新集羣中對應的資源。當 Release 被刪除後,controller 將它關聯的 Release History 刪除,同時將集羣中的其餘資源一併刪除。
架構圖
這樣的設計有什麼好處?
總而言之,編排不只僅是一門技術也是一門藝術!謝謝!