編排的藝術|K8S中的容器編排和應用編排
眾所周知,Kubernetes 是一個容器編排平臺,它有非常豐富的原始的 API 來支援容器編排,但是對於使用者來說更加關心的是一個應用的編排,包含多容器和服務的組合,管理它們之間的依賴關係,以及如何管理儲存。
在這個領域,Kubernetes 用 Helm 的來管理和打包應用,但是 Helm 並不是十全十美的,在使用過程中我們發現它並不能完全滿足我們的需求,所以在 Helm 的基礎上,我們自己研發了一套編排元件……
什麼是編排?
不知道大家有沒仔細思考過編排到底是什麼意思? 我查閱了 Wiki 百科,瞭解到我們常說的編排的英文單詞為 “Orchestration”,它常被解釋為:
- 本意:為管絃樂中的配器法,主要是研究各種管絃樂器的運用和配合方法, 通過各種樂器的不同音色,以便充分表現樂曲的內容和風格。
- 計算機領域:引申為描述複雜計算機系統、中介軟體 (middleware) 和業務的自動化的安排、協調和管理。
有趣的是 “Orchestration” 的標準翻譯應該為“編配”,而“編排”則是 另外一個單詞 “Choreography”,為了方便大家理解, 符合平時的習慣,我們還是使用編排 (Orchestration) 來描述下面的問題。至於“編配 (Orchestration)” 和 “編排(Choreography)” 之爭,這裡有一篇文章,有興趣可以看一下 。
Kubernetes 容器編排技術
當我們在說容器編排的時候,我們在說什麼?
在傳統的單體式架構的應用中,我們開發、測試、交付、部署等都是針對單個元件,我們很少聽到編排這個概念。而在雲的時代,微服務和容器大行其道,除了為我們顯示出了它們在敏捷性,可移植性等方面的巨大優勢以外,也為我們的交付和運維帶來了新的挑戰:我們將單體式的架構拆分成越來越多細小的服務,執行在各自的容器中,那麼該如何解決它們之間的依賴管理,服務發現,資源管理,高可用等問題呢?
在容器環境中,編排通常涉及到三個方面:
- 資源編排 – 負責資源的分配,如限制 namespace 的可用資源,scheduler 針對資源的不同排程策略;
- 工作負載編排 – 負責在資源之間共享工作負載,如 Kubernetes 通過不同的 controller 將 Pod 排程到合適的 node 上,並且負責管理它們的生命週期;
- 服務編排 – 負責服務發現和高可用等,如 Kubernetes 中可用通過 Service 來對內暴露服務,通過 Ingress 來對外暴露服務。
在 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 種型別的應用:
- 無狀態應用 = Services + Volumes + Deployment
- 有狀態應用 = Services + Volumes + StatefulSet
- 守護型應用 = Services + Volumes + DaemonSet
- 批處理應用 = Services + Volumes + CronJob/Job
我們來重新審視一下之前的例子:
應用層面的四個問題
通過前面的探索,我們可以引出應用層面的四個問題:
- 應用包的定義
- 應用依賴管理
- 包儲存
- 執行時管理
在社群中,這四個方面的問題分別由三個元件或者專案來解決:
- Helm Charts: 定義了應用包的結構以及依賴關係;
- Helm Registry: 解決了包儲存;
- HelmTiller: 負責將包執行在 Kubernetes 叢集中。
Helm Charts
Charts 在本質上是一個 tar 包,包含了一些 yaml 的 template 以及解析 template 需要的 values, 如下圖:templates 是 Golang 的 template 模板,values.yaml 裡面包含了這個 Charts 需要的值。
Helm Registry
用來負責儲存和管理使用者的 Charts, 並提供簡單的版本管理,與容器領域的映象倉庫類似這個專案是開源的。( github.com/caicloud/he…)
Tiller
- 負責將 Chart 部署到指定的叢集當中,並管理生成的 Release (應用);
- 支援對 Release 的更新,刪除,回滾操作;
- 支援對 Release 的資源進行增量更新;
- Release 的狀態管理;
- Kubernetes下屬子專案(github.com/kubernetes/…) 。
Tiller 的缺陷
- 沒有內建的認知授權機制,Tiller 跑在 kube-system 分割槽下,擁有整個叢集的許可權;
- Tiller 將 Release 安裝到 Kubernetes 叢集中後並不會繼續追蹤他們的狀態;
- Helm+Tiller的架構並不符合 Kubernetes 的設計模式,這就導致它的擴充性比較差;
- Tiller 建立的 Release 是全域性的並不是在某一個分割槽下,這就導致多使用者/租戶下,不能進行隔離;
- 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 刪除,同時將叢集中的其他資源一併刪除。
架構圖
這樣的設計有什麼好處?
- 隔離性:資源使用 Namespace 隔離,適應多使用者/租戶;
- 可讀性:Release Controller 會追蹤每個 Release 的子資源的狀態;
- 版本控制:你可以很容易地會退到某一個版本;
- 擴充性:整個架構是遵循 Kubernetes 的 controller pattern,具有良好的可擴充套件性,可以在上面進行二次開發;
- 安全性:因為所有的操作都是基於 Kubernetes 的 Resource,可以充分利用 Kubernetes 內建的認證鑑權模組,如 ABAC, RBAC 。
本文轉自掘金-編排的藝術| K8S 中的容器編排和應用編排
相關文章
- Docker批量容器編排Docker
- 42_Docker容器編排Docker
- Docker 多容器編排Swarm(六)DockerSwarm
- 1.07 容器編排docker SwarmDockerSwarm
- Docker容器編排技術解析與實踐Docker
- kubernetes (k8s)容器編排系統K8S
- 容器編排系統K8s之Dashboard部署K8S
- DCOS雲平臺之Marathon應用容器編排元件元件
- Docker 釋出新的跨容器的分散式應用編排服務Docker分散式
- Docker 容器編排利器 Docker ComposeDocker
- Kubernetes – 容器編排簡介
- Docker批次容器編排的實現介紹Docker
- 容器編排系統k8s之Service資源K8S
- 容器編排系統K8s之crd資源K8S
- 容器編排系統K8s之APIService資源K8SAPI
- 容器編排系統K8s之HPA資源K8S
- Docker知識進階與容器編排技術Docker
- 如何視覺化編寫和編排你的 K8s 任務視覺化K8S
- 容器編排系統K8s之StatefulSet控制器K8S
- 容器編排系統K8s之flannel網路模型K8S模型
- 容器編排系統K8s之NetworkPolicy資源K8S
- 滬江基於容器編排的Dev/Ops流程dev
- 容器編排系統K8s之Volume的基礎使用K8S
- 流程編排、如此簡單-通用流程編排元件JDEasyFlow介紹元件
- Docker Machine, Swarm,和Compose編排分散式應用DockerMacSwarm分散式
- PraisonAI :簡化各種大模型應用的建立和編排AI大模型
- 容器編排系統之ReplicaSet和Deployment控制器
- 容器編排系統K8s之PV、PVC、SC資源K8S
- 容器編排系統K8s之訪問控制--准入控制K8S
- docker容器編排原來這麼絲滑~Docker
- 容器編排系統之Kubectl工具的基礎使用
- 容器引擎Docker和容器編排kubernetes如何優雅的收集容器日誌Docker
- Docker編排利器DockerComposeDocker
- Docker compose 編排LNPDocker
- docker-compose 編排Docker
- 容器編排系統之DaemonSet、Job和CronJob控制器
- 容器編排系統K8s之訪問控制--RBAC授權K8S
- 容器編排系統K8s之ConfigMap、Secret資源K8S