天天看點

靈活、高效的雲原生叢集管理經驗:用 K8s 管理 K8s

靈活、高效的雲原生叢集管理經驗:用 K8s 管理 K8s

背景

多叢集主要應用在如下場景:

1.産品本身需要多叢集能力。産品的管控需要部署在 K8s 叢集内,同時,該産品還需要提供 K8s 叢集給使用者使用,從故障隔離、穩定性、安全多重角度考慮,容器服務的管控和業務應該分别部署在不同的叢集内;

2.使用者在使用 K8s 的時候,也希望具備生産多套叢集供不同業務使用,進而進行資源隔離、故障隔離;

3.同一使用者可能需要多種類型叢集的能力,以邊緣計算 IOT 為例,它需要一個定制的邊緣 K8s 叢集,如果按照普通的獨立 K8s 叢集來建立,一方面會存在資源浪費,另一方面獨立的叢集為使用者增加了運維的成本。

我們總結了運維 K8s 叢集的難點,可以分為兩部分:

難點 1:運維 K8s 叢集的管控面

如何支援使用者一鍵彈出新的 Kubernetes 叢集?

如何更新多個 K8s 叢集的版本,當社群重大 CVE 發現時,是否要一個個更新叢集?

如何自動修複多個 K8s 叢集運作時發生的故障?

如何對叢集的 etcd 進行維護,包括更新、備份、恢複、節點遷移?

難點 2:運維 Worker 節點

如何快速擴縮容 Worker 節點?同時需要確定每個節點的 on-host 軟體(例如 docker、kubelet 等無法被 K8s 托管的元件)版本、配置和其他節點拉齊。

如何更新若幹 Worker 節點上的 on-host 軟體?如何灰階釋出 Worker 節點上的軟體包?

如何自動修複若幹 Worker 節點可能出現的 on-host 軟體故障?比如要是 docker/kubelet 發生 panic,我們是否能自動化的處理?

K8s 作為一個複雜的自動化運維系統,支撐了上層業務的釋出、更新、生命周期管理,但 K8s 本身的運維在業内卻往往還是由一個工作流(ansible、argo 等)來執行。這個過程的自動化程度不高,需要運維人員具備比較專業的 K8s 知識。而當需要運維多套 K8s 叢集後,運維成本在理想情況下也會線性上升,在專有雲場景下成本還會被再次放大。

阿裡内部很早就遇到了運維大量 K8s 叢集的難題,我們摒棄了傳統工作流的模式,探索另外一條路徑:使用 K8s 管理 K8s,CNCF 的文章《Demystifying Kubernetes as a Service – How Alibaba Cloud Manages 10,000s of Kubernetes Clusters》介紹了阿裡巴巴在大規模 K8s 叢集管理上的探索與經驗。

當然,專有雲場景和阿裡巴巴内部場景還是有較大不同,阿裡集團内使用 Kube-On-Kube 技術主要看重它的規模效應,可以使用一個元 K8s 叢集來管理成百上千的業務 K8s 叢集,而專有雲場景的規模效應小,專有雲主要看重的是Kube-On-Kube 技術自動化運維 K8s 叢集和相容多種 K8s 叢集的能力,在提高穩定性的同時豐富了使用者的使用場景。

K8s 聲明式運維哲學:用 K8s 管理 K8s

K8s 的聲明式 API 颠覆了傳統的過程式運維模式,聲明式 API 對應的是面向終态的運維模式:使用者将在 Spec 裡定義自己所期望的狀态,K8s 的 Controller 會進行一系列操作幫助使用者達到期望狀态,隻要不滿足要求,Controller 會一直嘗試。

靈活、高效的雲原生叢集管理經驗:用 K8s 管理 K8s

對于 Deployment 等 K8s 原生資源,由 K8s 的 Controller 負責終态維護,而對于使用者自定義的資源,例如一個 Cluster,K8s 提供了強大易用的 CRD+Operator 機制,隻需要簡單幾步就可以實作自定義的面向終态運維:

1.定義自己的資源類型(CRD),實作自己的 Operator,Operator 中包含了自定義 Controller;

2.使用者隻需要送出自己的 CR,表現形式為一個 yaml 或者 json;

3.Operator 監聽到 CR 的變化,Controller 開始執行對應的運維邏輯;

4.在運作過程中,當終态不滿足要求時,Operator 也能夠監聽到變化,并做出相應的恢複操作。

Operator 是用代碼運維應用最好的實踐之一。當然,這隻是一個架構,它節省了使用者的一些重複性勞動,如事件監聽機制、RESTful API 監聽,但核心的運維邏輯,還是需要 case by case 由使用者編寫。

雲原生的 KOK 架構

Kube-On-Kube 不是新概念,業内已有很多優秀的解決方案:

螞蟻

社群項目

但是以上方案對公有雲基礎設施有較強依賴,專有雲的特殊性讓我們要考慮:

足夠輕量化使用者才會買單,客戶通常很排斥獨占的管理節點開銷;

不依賴公有雲和阿裡集團内部的差異性基礎設施;

采用雲原生架構。

在考慮到這 3 個因素後,我們設計出更為通用的 KOK 方案:

靈活、高效的雲原生叢集管理經驗:用 K8s 管理 K8s

名詞解釋:

Meta Cluster:元叢集,即 Kube-On-Kube 的下層 Kube;

Production Cluster:業務叢集,即 Kube-On-Kube 的上層 Kube;

etcd cluster:由運作在元叢集中的 etcd operator 建立和維護的 etcd 叢集,可以每個業務叢集獨占一個 etcd,或者多個業務叢集共享;

PC-master-pod:業務叢集管控 pod,實際上是 apiserver/scheduler/controller-manager 這 3 種 pod,由運作在元叢集的 Cluster Operator 維護;

PC-nodes:業務叢集的 Node 節點,由 Machine Operator 負責初始化并加入到業務叢集,由 Machine Operator 維護;

etcd Operator

etcd Operator 負責 etcd 叢集的建立、銷毀、更新、故障恢複等,還提供了 etcd 叢集的狀态監控,包括叢集健康狀态、member 健康狀态、存儲資料量等。

阿裡雲-雲原生應用平台-SRE 團隊對開源版 etcd Operator 進行了改進,增強了運維功能和穩定性,該 Operator 負責阿裡内部大量 etcd 叢集的運維管理,運作穩定,久經考驗。

Cluster Operator

Cluster Operator 負責業務叢集 K8s 管控元件(Apiserver、Controller Manager、Scheduler)的建立、維護,以及相應的證書生成、kubeconfig 生成。

我們和螞蟻集團-PaaS 引擎與專有雲産品團隊共建了 Cluster Operator,具備自定義渲染、版本溯源、動态增加可支援版本等能力。

業務叢集的 K8s 管控元件部署在元叢集,從元叢集的視角看就是一堆普通的 Resource,包括 Deployment、Secret、Pod、PVC 等,是以,業務叢集不具備 Master 節點的概念:

kube-apiserver:由 1 個 Deployment +1 個 Service 組成。kube-apiserver 本身無狀态,Deployment 可以滿足要求,同時,Apiserver 需要對接 etcd Operator 拉起的 etcd cluster;Service 用于對業務叢集其他元件以及對外暴露 Apiserver 的服務,此處我們考慮了,如果使用者環境具備 LoadBalancer Service 的能力,建議優先使用 LoadBalancer 暴露 Apiserver,如果沒有此能力,我們也提供了 NodePort 的暴露形态;

kube-controller-manager:1 個 Deployment,無狀态應用;

kube-scheduler:1 個 Deployment 即可,無狀态應用;

但是,隻部署以上 3 個元件還不能提供一個可用 K8s,我們還需要滿足以下場景:

1.一個可用的業務 K8s 除了 etcd、3 大件之外,還需要部署 coredns、kube-proxy 或者其他任意元件;

2.部分元件需要和 etcd、3 大件一樣的部署在元叢集,例如 Machine Operator 是拉起節點的元件,它必須在業務叢集有節點之前就能運作,是以它不能部署在業務叢集;

3.元件版本的更新。

是以,為了應對擴充性要求,我們設計了 addons 熱插拔能力,隻需一條指令即可導入所有 Addon 元件;同時 addons 支援動态渲染能力,可自定義 addons 的配置項,細節不再贅述。

Machine Operator

Machine Operator 負責對節點做必要的初始化操作,然後建立節點的 docker、k8s、NVIDIA 等元件并維護其終态;最後,将節點加入業務叢集。

我們采用了阿裡雲-雲原生應用平台-Serverless 節點管理團隊維護的 KubeNode 元件,該 Operator 負責集團内節點的上下線,實作了一個面向終态的運維架構,可以針對不同 Arch 或者不同 OS 定制運維 CRD,比較适合在環境多變的專有雲環境使用。

KubeNode 簡而言之實作了一個面向終态的運維架構,它主要包含 Component+Machine 兩個概念。

1.使用者按模闆提供運維腳本,生成 Component CR;

2.如果要上線節點,就生成一個 Machine CR,Machine CR 裡會指定需要部署哪些 Component;

3.KubeNode 監聽到 Machine CR,會到對應節點進行運維操作。

這種設計理論上可以針對不同 Arch 或者不同 OS 可以在不改動 Operator 源碼的前提下進行擴充,靈活度很高。同時,我們也在探索如何結合 IaaS provider,最終實作 RunAnyWhere 的目标。

多叢集方案成本對比

在使用自動化工具(也是一個雲原生的 Operator,後續會有文章介紹)串接上述流程後,我們可以将一個叢集的生産時間壓縮到分鐘級。

下圖列舉了平鋪式多叢集解決方案(直接部署多套)和 KOK 多叢集解決方案的成本分析:

平鋪式多叢集解決方案 KOK多叢集解決方案
傳遞成本 TKG TG+tG*(K-1)
更新成本 UGP*K UGP+uGP*(K-1)
使用者使用成本 T*K t*K
其中,T 為單個 K8s 叢集部署時間,t 為單個業務叢集的部署時間,K 為叢集數,G 為局點數,U 為更新元叢集時間,u 為更新業務叢集時間,P 為更新次數。

從我們的實踐經驗得到,正常情況下,T、U 為約為 1 小時,t、u 約為 10 分鐘,我們預計:

傳遞多叢集(叢集數為 3)時間将由 > 3小時降為 <1 小時;

更新 1 套叢集的時間将由 >1 小時降為 10 分鐘;

使用者自建 1 套新叢集的時間開銷将由 >2 小時降為 10 分鐘。

總結

平鋪式多叢集勢必帶來運維複雜度的線性上升,難以維護;而 KOK 多叢集将 K8s 叢集本身視為一個 K8s 資源,利用 K8s 強大的 CRD+Operator 能力,将 K8s 的運維本身也從傳統的過程式更新為聲明式,對 K8s 叢集的運維複雜度實行了降維打擊。

與此同時,本文介紹的多叢集設計方案,在借鑒阿裡巴巴集團内多年運維經驗的基礎上,采用雲原生的架構,擺脫了對差異性基礎設施的依賴,實作了 RunAnyWhere。使用者隻需要提供普通的 IaaS 設施,就可以享受到易用、穩定、輕量的 K8s 多叢集能力。

本文轉自<阿裡巴巴雲原生技術圈>——阿裡巴巴雲原生小助手

繼續閱讀