万级规模 K8s 如何管理?蚂蚁双11核心技术公开
阿里妹導(dǎo)讀:Kubernetes 大幅降低了容器化應(yīng)用部署的門檻,并以其超前的設(shè)計理念和優(yōu)秀的技術(shù)架構(gòu),在容器編排領(lǐng)域拔得頭籌。越來越多的公司開始在生產(chǎn)環(huán)境部署實(shí)踐。本文將分享螞蟻金服是如何有效可靠地管理大規(guī)模 Kubernetes 集群的,并會詳細(xì)介紹集群管理系統(tǒng)核心組件的設(shè)計。
系統(tǒng)概覽
Kubernetes 集群管理系統(tǒng)需要具備便捷的集群生命周期管理能力,完成集群的創(chuàng)建、升級和工作節(jié)點(diǎn)的管理。在大規(guī)模場景下,集群變更的可控性直接關(guān)系到集群的穩(wěn)定性,因此管理系統(tǒng)可監(jiān)控、可灰度、可回滾的能力是系統(tǒng)設(shè)計的重點(diǎn)之一。
除此之外,超大規(guī)模集群中,節(jié)點(diǎn)數(shù)量已經(jīng)達(dá)到 10K 量級,節(jié)點(diǎn)硬件故障、組件異常等問題會常態(tài)出現(xiàn)。面向大規(guī)模集群的管理系統(tǒng)在設(shè)計之初就需要充分考慮這些異常場景,并能夠從這些異常場景中自恢復(fù)。
設(shè)計模式
基于這些背景,我們設(shè)計了一個面向終態(tài)的集群管理系統(tǒng)。系統(tǒng)定時檢測集群當(dāng)前狀態(tài),判斷是否與目標(biāo)狀態(tài)一致,出現(xiàn)不一致時,Operators 會發(fā)起一系列操作,驅(qū)動集群達(dá)到目標(biāo)狀態(tài)。
這一設(shè)計參考控制理論中常見的負(fù)反饋閉環(huán)控制系統(tǒng),系統(tǒng)實(shí)現(xiàn)閉環(huán),可以有效抵御系統(tǒng)外部的干擾,在我們的場景下,干擾對應(yīng)于節(jié)點(diǎn)軟硬件故障。
架構(gòu)設(shè)計
如上圖,元集群是一個高可用的 Kubernetes 集群,用于管理 N 個業(yè)務(wù)集群的 Master 節(jié)點(diǎn)。業(yè)務(wù)集群是一個服務(wù)生產(chǎn)業(yè)務(wù)的 Kubernetes 集群。SigmaBoss 是集群管理入口,為用戶提供便捷的交互界面和可控的變更流程。
元集群中部署的 Cluster-Operator 提供了業(yè)務(wù)集群集群創(chuàng)建、刪除和升級能力,Cluster-Operator 面向終態(tài)設(shè)計,當(dāng)業(yè)務(wù)集群 Master 節(jié)點(diǎn)或組件異常時,會自動隔離并進(jìn)行修復(fù),以保證業(yè)務(wù)集群 Master 節(jié)點(diǎn)達(dá)到穩(wěn)定的終態(tài)。這種采用 Kubernetes 管理 Kubernetes 的方案,我們稱作 Kube on Kube 方案,簡稱 KOK 方案。
業(yè)務(wù)集群中部署有 Machine-Operator 和節(jié)點(diǎn)故障自愈組件用于管理業(yè)務(wù)集群的工作節(jié)點(diǎn),提供節(jié)點(diǎn)新增、刪除、升級和故障處理能力。在 Machine-Operator 提供的單節(jié)點(diǎn)終態(tài)保持的能力上,SigmaBoss 上構(gòu)建了集群維度灰度變更和回滾能力。
核心組件
集群終態(tài)保持器
基于 K8s CRD,在元集群中定義了 Cluster CRD 來描述業(yè)務(wù)集群終態(tài),每個業(yè)務(wù)集群對應(yīng)一個 Cluster 資源,創(chuàng)建、刪除、更新 Cluster 資源對應(yīng)于實(shí)現(xiàn)業(yè)務(wù)集群創(chuàng)建、刪除和升級。Cluster-Operator watch Cluster 資源,驅(qū)動業(yè)務(wù)集群 Master 組件達(dá)到 Cluster 資源描述的終態(tài)。
業(yè)務(wù)集群 Master 組件版本集中維護(hù)在 ClusterPackageVersion CRD 中,ClusterPackageVersion 資源記錄了 Master 組件(如:api-server、controller-manager、scheduler、operators 等)的鏡像、默認(rèn)啟動參數(shù)等信息。
Cluster 資源唯一關(guān)聯(lián)一個 ClusterPackageVersion,修改 Cluster CRD 中記錄的 ClusterPackageVersion 版本即可完成業(yè)務(wù)集群 Master 組件發(fā)布和回滾。
節(jié)點(diǎn)終態(tài)保持器
Kubernetes 集群工作節(jié)點(diǎn)的管理任務(wù)主要有:
- 節(jié)點(diǎn)系統(tǒng)配置、內(nèi)核補(bǔ)丁管理;
- docker / kubelet 等組件安裝、升級、卸載;
- 節(jié)點(diǎn)終態(tài)和可調(diào)度狀態(tài)管理(如關(guān)鍵 DaemonSet 部署完成后才允許開啟調(diào)度);
- 節(jié)點(diǎn)故障自愈。
為實(shí)現(xiàn)上述管理任務(wù),在業(yè)務(wù)集群中定義了 Machine CRD 來描述工作節(jié)點(diǎn)終態(tài),每一個工作節(jié)點(diǎn)對應(yīng)一個 Machine 資源,通過修改 Machine 資源來管理工作節(jié)點(diǎn)。
Machine CRD 定義如下圖所示,spec 中描述了節(jié)點(diǎn)需要安裝的組件名和版本,status 中記錄有當(dāng)前這個工作節(jié)點(diǎn)各組件安裝運(yùn)行狀態(tài)。除此之外,Machine CRD 還提供了插件式終態(tài)管理能力,用于與其它節(jié)點(diǎn)管理 Operators 協(xié)作,這部分會在后文詳細(xì)介紹。
工作節(jié)點(diǎn)上的組件版本管理由 MachinePackageVersion CRD 完成。MachinePackageVersion 維護(hù)了每個組件的 rpm 版本、配置和安裝方法等信息。一個 Machine 資源會關(guān)聯(lián) N 個不同的 MachinePackageVersion,用來實(shí)現(xiàn)安裝多個組件。
在 Machine、MachinePackageVersion CRD 基礎(chǔ)上,設(shè)計實(shí)現(xiàn)了節(jié)點(diǎn)終態(tài)控制器 Machine-Operator。Machine-Operator watch Machine 資源,解析 MachinePackageVersion,在節(jié)點(diǎn)上執(zhí)行運(yùn)維操作來驅(qū)動節(jié)點(diǎn)達(dá)到終態(tài),并持續(xù)守護(hù)終態(tài)。
節(jié)點(diǎn)終態(tài)管理
隨著業(yè)務(wù)訴求的變化,節(jié)點(diǎn)管理已不再局限于安裝 docker / kubelet 等組件,我們需要實(shí)現(xiàn)如等待日志采集 DaemonSet 部署完成才可以開啟調(diào)度的需求,而且這類需求變得越來越多。
如果將終態(tài)統(tǒng)一交由 Machine-Operator 管理,勢必會增加 Machine-Operator 與其它組件的耦合性,而且系統(tǒng)的擴(kuò)展性會受到影響。因此,我們設(shè)計了一套節(jié)點(diǎn)終態(tài)管理的機(jī)制,來協(xié)調(diào) Machine-Operator 和其它節(jié)點(diǎn)運(yùn)維 Operators。
設(shè)計如下圖所示:
- 全量 ReadinessGates: 記錄節(jié)點(diǎn)可調(diào)度需要檢查的 Condition 列表;
- Condition ConfigMap: 各節(jié)點(diǎn)運(yùn)維 Operators 終態(tài)狀態(tài)上報 ConfigMap;
協(xié)作關(guān)系:
節(jié)點(diǎn)故障自愈
我們都知道物理機(jī)硬件存在一定的故障概率,隨著集群節(jié)點(diǎn)規(guī)模的增加,集群中會常態(tài)出現(xiàn)故障節(jié)點(diǎn),如果不及時修復(fù)上線,這部分物理機(jī)的資源將會被閑置。
為解決這一問題,我們設(shè)計了一套故障發(fā)現(xiàn)、隔離、修復(fù)的閉環(huán)自愈系統(tǒng)。
如下圖所示,故障發(fā)現(xiàn)方面,采取 Agent 上報和監(jiān)控系統(tǒng)主動探測相結(jié)合的方式,保證了故障發(fā)現(xiàn)的實(shí)時性和可靠性(Agent 上報實(shí)時性比較好,監(jiān)控系統(tǒng)主動探測可以覆蓋 Agent 異常未上報場景)。故障信息統(tǒng)一存儲于事件中心,關(guān)注集群故障的組件或系統(tǒng)都可以訂閱事件中心事件拿到這些故障信息。
節(jié)點(diǎn)故障自愈系統(tǒng)會根據(jù)故障類型創(chuàng)建不同的維修流程,例如:硬件維系流程、系統(tǒng)重裝流程等。
維修流程中優(yōu)先會隔離故障節(jié)點(diǎn)(暫停節(jié)點(diǎn)調(diào)度),然后將節(jié)點(diǎn)上 Pod 打上待遷移標(biāo)簽來通知 PaaS 或 MigrateController 進(jìn)行 Pod 遷移,完成這些前置操作后,會嘗試恢復(fù)節(jié)點(diǎn)(硬件維修、重裝操作系統(tǒng)等),修復(fù)成功的節(jié)點(diǎn)會重新開啟調(diào)度,長期未自動修復(fù)的節(jié)點(diǎn)由人工介入排查處理。
風(fēng)險防范
在 Machine-Operator 提供的原子能力基礎(chǔ)上,系統(tǒng)中設(shè)計實(shí)現(xiàn)了集群維度的灰度變更和回滾能力。此外,為了進(jìn)一步降低變更風(fēng)險,Operators 在發(fā)起真實(shí)變更時都會進(jìn)行風(fēng)險評估,架構(gòu)示意圖如下。
高風(fēng)險變更操作(如:刪除節(jié)點(diǎn)、重裝系統(tǒng))接入統(tǒng)一限流中心,限流中心維護(hù)了不同類型操作的限流策略,若觸發(fā)限流,則熔斷變更。
為了評估變更過程是否正常,我們會在變更前后,對各組件進(jìn)行健康檢查,組件的健康檢查雖然能夠發(fā)現(xiàn)大部分異常,但不能覆蓋所有異常場景。所以,風(fēng)險評估過程中,系統(tǒng)會從事件中心、監(jiān)控系統(tǒng)中獲取集群業(yè)務(wù)指標(biāo)(如:Pod 創(chuàng)建成功率),如果出現(xiàn)異常指標(biāo),則自動熔斷變更。
結(jié)束語
本文主要和大家分享了現(xiàn)階段螞蟻金服 Kubernetes 集群管理系統(tǒng)的核心設(shè)計,核心組件大量使用 Operator 面向終態(tài)設(shè)計模式。這套面向終態(tài)的集群管理系統(tǒng)在今年備戰(zhàn)雙 11 過程中,經(jīng)受了性能和穩(wěn)定性考驗(yàn)。
一個完備的集群管理系統(tǒng)除了保證集群穩(wěn)定性和運(yùn)維效率外,還應(yīng)該提升集群整體資源利用率。接下來,我們會從提升節(jié)點(diǎn)在線率、降低節(jié)點(diǎn)閑置率等方面出發(fā),來提升螞蟻金服生產(chǎn)集群的資源利用率。
Q & A
Q1:目前公司絕大多數(shù)應(yīng)用已部署在 Docker 中 ,如何向 K8s 轉(zhuǎn)型?是否有案例可以借鑒?
A1:我在螞蟻工作了將近 5 年,螞蟻的業(yè)務(wù)由最早跑在 xen 虛擬機(jī)中,到現(xiàn)在跑在 Docker 里由 K8s 調(diào)度,基本上每年都在迭代。K8s 是一個非常開放的 “PaaS” 框架,如果已經(jīng)部署在 Docker 中,符合“云原生”應(yīng)用特性,遷移 K8s 理論上會比較平滑。螞蟻由于歷史包袱比較重,在實(shí)踐過程中,為了兼容業(yè)務(wù)需求,對 K8s 做了一些增強(qiáng),保證業(yè)務(wù)能平滑遷移過來。
Q2:應(yīng)用部署在 K8s 及 Docker 中會影響性能嗎?例如大數(shù)據(jù)處理相關(guān)的任務(wù)是否建議部署到 K8s 中?
A2:我理解 Docker 是容器,不是虛擬機(jī),對性能的影響是有限的。螞蟻大數(shù)據(jù)、AI 等業(yè)務(wù)都已經(jīng)在遷移 K8s 與在線應(yīng)用混部。大數(shù)據(jù)類對時間不敏感業(yè)務(wù),可以很好地利用集群空閑資源,混部后可大幅降低數(shù)據(jù)中心成本。
Q3:K8s 集群和傳統(tǒng)的運(yùn)維環(huán)境怎么更好的結(jié)合?現(xiàn)在公司肯定不會全部上 K8s。
A3:基礎(chǔ)設(shè)施不統(tǒng)一會導(dǎo)致資源沒有辦法統(tǒng)一進(jìn)行調(diào)度,另外維護(hù)兩套相對獨(dú)立的運(yùn)維系統(tǒng),代價是非常大的。螞蟻在遷移過程中實(shí)現(xiàn)了一個“Adapter”,將傳統(tǒng)創(chuàng)建容器或發(fā)布的指令轉(zhuǎn)換成 K8s 資源修改來做“橋接”。
Q4:Node 監(jiān)控是怎么做的,Node 掛掉會遷移 Pod 嗎?業(yè)務(wù)不允許自動遷移呢?
A4:Node 監(jiān)控分為硬件、系統(tǒng)級、組件級,硬件監(jiān)控數(shù)據(jù)來自 IDC,系統(tǒng)級監(jiān)控使用內(nèi)部自研監(jiān)控平臺,組件(kubelet/pouch 等)監(jiān)控我們擴(kuò)展 NPD,提供 exporter 暴露接口給監(jiān)控系統(tǒng)采集。Node 出現(xiàn)異常,會自動遷移 Pod。有些帶狀態(tài)的業(yè)務(wù),業(yè)務(wù)方自己定制 operator 來實(shí)現(xiàn) Pod 自動遷移。不具備自動遷移能力的 Pod, 超期后會自動銷毀。
Q5:整個 K8s 集群未來是否會對開發(fā)透明,使用代碼面向集群編程或編寫部署文件,不再需要按容器去寫應(yīng)用及部署,是否有這種規(guī)劃?
A5:K8s 提供了非常多構(gòu)建 PaaS 平臺的擴(kuò)展能力,但現(xiàn)在直接面向 K8s 去部署應(yīng)用的確非常困難。我覺得采用某種 DSL 去部署應(yīng)用是未來的趨勢,K8s 會成為這些基礎(chǔ)設(shè)施的核心。
Q6:我們目前采用 kube-to-kube 的方式管理集群,kube-on-kube 相比 kube-to-kube 的優(yōu)勢在哪?在大規(guī)模場景下,K8s 集群的節(jié)點(diǎn)伸縮過程中,性能瓶頸在哪?是如何解決的?
A6:目前已經(jīng)有非常多的 CI/CD 流程跑在 K8s 之上。采用 kube-on-kube 方案,我們可以像管理普通業(yè)務(wù) App 那樣管理業(yè)務(wù)集群的管控。節(jié)點(diǎn)上除運(yùn)行 kubelet pouch 外,還會額外運(yùn)行很多 daemonset pod,大規(guī)模新增節(jié)點(diǎn)時,節(jié)點(diǎn)組件會對 apiserver 發(fā)起大量 list/watch 操作,我們的優(yōu)化主要集中在 apiserver 性能提升,和配合 apiserver 降低節(jié)點(diǎn)全量 list/watch。
Q7:因?yàn)槲覀児具€沒有上 K8s,所有我想請教以下幾個問題:K8s 對我們有什么好處?能夠解決當(dāng)前的什么問題?優(yōu)先在哪些業(yè)務(wù)場景、流程環(huán)節(jié)使用?現(xiàn)有基礎(chǔ)設(shè)施能否平滑切換到 Kubernetes?
A7:我覺得 K8s 最大的不同在于面向終態(tài)的設(shè)計理念,不再是一個一個運(yùn)維動作。這對于復(fù)雜的運(yùn)維場景來說,非常有益。從螞蟻的升級實(shí)踐看,平滑是可以做到的。
Q8:cluster operator 是 Pod 運(yùn)行,用 Pod 啟動業(yè)務(wù)集群 master,然后 machine operator 是物理機(jī)運(yùn)行?
A8:operator 都運(yùn)行在 Pod 里面的,cluster operator 將業(yè)務(wù)集群的 machine operator 拉起來。
Q9:為應(yīng)對像雙十一這樣的高并發(fā)場景,多少量級的元集群的規(guī)模對應(yīng)管理多少量級的業(yè)務(wù)集群合適?就我的理解,cluster operator 應(yīng)該是對資源的 list watch,面對大規(guī)模的并發(fā)場景,你們做了哪些方面的優(yōu)化?
A9:一個集群可以管理萬級節(jié)點(diǎn),所以元集群理論上可以管理 3K+ 業(yè)務(wù)集群。
Q10:節(jié)點(diǎn)如果遇到系統(tǒng)內(nèi)核、Docker、K8s 異常,如何從軟件層面最大化保證系統(tǒng)正常?
A10:具備健康檢查能力,主動退出,由 K8s 發(fā)現(xiàn),并重新在其它節(jié)點(diǎn)拉起。
原文鏈接
本文為云棲社區(qū)原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。
總結(jié)
以上是生活随笔為你收集整理的万级规模 K8s 如何管理?蚂蚁双11核心技术公开的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 看!闲鱼在ServiceMesh的探索和
- 下一篇: 左手代码右手滑板 支付宝这个程序员有些酷