作者:vivo 互聯(lián)網(wǎng)容器團隊 - Zhang Rong
本文主要講述了一些對于K8s多集群管理的思考,包括為什么需要多集群、多集群的優(yōu)勢以及現(xiàn)有的一些基于Kubernetes衍生出的多集群管理架構(gòu)實踐。
一、為什么需要多集群
隨著K8s和云原生技術(shù)的快速發(fā)展,以及各大廠商在自己的數(shù)據(jù)中心使用K8s的API進行容器化應(yīng)用編排和管理,讓應(yīng)用交付本身變得越來越標準化和統(tǒng)一化,并且實現(xiàn)了與底層基礎(chǔ)設(shè)施的完全解耦,為多集群和混合云提供了一個堅實技術(shù)基礎(chǔ)。談到多集群多云的數(shù)據(jù)中心基礎(chǔ)架構(gòu),會想到為什么企業(yè)需要多集群?
1.單集群容量限制:
集群上限5000個節(jié)點和15萬個Pod。同時單集群的最大節(jié)點數(shù)不是一個確定值,其受到集群部署方式和業(yè)務(wù)使用集群資源的方式的影響。
2.多云混合使用:
避免被單家供應(yīng)商鎖定,不同集群的最新技術(shù)規(guī)劃,或是出于成本等考慮,企業(yè)選擇了多云架構(gòu)。
3.業(yè)務(wù)流量突發(fā):
正常情況下用戶使用自己的 IDC 集群提供服務(wù),當應(yīng)對突發(fā)大流量時,迅速將應(yīng)用擴容到云上集群共同提供服務(wù),需具備公有云 IaaS接入,可以自動擴縮容計算節(jié)點,將公有云作為備用資源池。該模式一般針對無狀態(tài)的服務(wù),可以快速彈性擴展,主要針對使用 CPU、內(nèi)存較為密集的服務(wù),如搜索、查詢、計算等類型的服務(wù)。
4.業(yè)務(wù)高可用:
單集群無法應(yīng)對網(wǎng)絡(luò)故障或者數(shù)據(jù)中心故障導(dǎo)致的服務(wù)的不可用。通常主要服務(wù)的集群為一個,另一個集群周期性備份?;蛘咭粋€集群主要負責讀寫,其他備份集群只讀,在主集群所在的云出現(xiàn)問題時可以快速切換到備份集群。該模式可用于數(shù)據(jù)量較大的存儲服務(wù),如部署一個高可用的mysql集群,一個集群負責讀寫,其他2個集群備份只讀,可以自動切換主備。
5.異地多活:
數(shù)據(jù)是實時同步的,多集群都可以同時讀寫,這種模式通常針對極其重要的數(shù)據(jù),如全局統(tǒng)一的用戶賬號信息等。
6.地域親和性:
盡管國內(nèi)互聯(lián)網(wǎng)一直在提速,但是處于帶寬成本的考量,同一調(diào)用鏈的服務(wù)網(wǎng)絡(luò)距離越近越好。服務(wù)的主調(diào)和被調(diào)部署在同一個地域內(nèi)能夠有效減少帶寬成本;并且分而治之的方式讓應(yīng)用服務(wù)本區(qū)域的業(yè)務(wù),也能有效緩解應(yīng)用服務(wù)的壓力。
二、多集群探索
2.1 社區(qū)在多集群上的探索
當前基于 K8s 多集群項目如下:
1.Federation v1:
已經(jīng)被社區(qū)廢棄,主要原因在于 v1 的設(shè)計試圖在 K8s 之上又構(gòu)建一層 Federation API,直接屏蔽掉了已經(jīng)取得廣泛共識的 K8s API ,這與云原生社區(qū)的發(fā)展理念是相悖。
2.Federation v2:
已經(jīng)被社區(qū)廢棄,提供了一個可以將任何 K8s API type 轉(zhuǎn)換成有多集群概念的 federated type 的方法,以及一個對應(yīng)的控制器以便推送這些 federated 對象 (Object)。而它并不像 V1 一樣關(guān)心復(fù)雜的推送策略(V1 的 Federation Scheduler),只負責把這些 Object 分發(fā)到用戶事先定義的集群去。這也就意味著 Federation v2 的主要設(shè)計目標,其實是向多集群推送 RBAC,policy 等集群配置信息。
參考Kubernetes Federation v2 核心實踐,并融入了眾多新技術(shù),包括 Kubernetes 原生 API 支持、多層級高可用部署、多集群自動故障遷移、多集群應(yīng)用自動伸縮、多集群服務(wù)發(fā)現(xiàn)等,并且提供原生 Kubernetes 平滑演進路徑。
4.Clusternet:
是一個兼具多集群管理和跨集群應(yīng)用編排的開源云原生管控平臺,解決了跨云、跨地域、跨可用區(qū)的集群管理問題。在項目規(guī)劃階段,就是面向未來混合云、分布式云和邊緣計算等場景來設(shè)計的,支持海量集群的接入和管理、應(yīng)用分發(fā)、流量治理等。
5.OCM:
OCM 是一款 Kubernetes 多集群平臺開源項目,它可以幫助你大大簡化跨云/多云場景下的集群管理,無論這些集群是在云上托管,還是部署在自建數(shù)據(jù)中心,再或者是在邊緣數(shù)據(jù)中心中。OCM 提供的基礎(chǔ)模型可以幫助我們同時理解單集群內(nèi)部的容量情況,也可以橫跨多集群進行資源/工作負載的編排調(diào)度。與此同時,OCM 還提供了一系列強大的擴展性或者叫做插件框架(addon-framework)來幫助我們集成 CNCF 生態(tài)中的其他項目,這些擴展性也可以幫助我們無侵入地針對你的特定使用場景手工擴展特性。
以上多集群項目主要功能為資源分發(fā)和調(diào)度,還有如多云基礎(chǔ)設(shè)施管理cluster-api,多集群檢索Clusterpedia,多集群pod互通submariner,multicluster-ingress解決多集群的ingress,服務(wù)治理和流量調(diào)度 Service Mesh,如istio、cilium等網(wǎng)絡(luò)組件實現(xiàn)的multi cluster mesh解決跨集群的mesh網(wǎng)絡(luò)管理,以及結(jié)合存儲相關(guān)項目實現(xiàn)跨集群存儲管理和遷移等。
2.2 vivo 在多集群上的探索
2.2.1 非聯(lián)邦集群管理
非聯(lián)邦多集群管理系統(tǒng)主要是進行資源管理、運維管理和用戶管理,提供導(dǎo)入K8s集群權(quán)限功能,并通過統(tǒng)一 Web 界面進行查看和管理。這類工具不引入額外集群聯(lián)邦的復(fù)雜,保持每個集群的獨立性,同時通過統(tǒng)一的 Web 界面來查看多個集群的資源使用情況,支持通過 Web 界面創(chuàng)建 Deployment、Service 和負載均衡等,并且會集成持續(xù)集成、持續(xù)交付和監(jiān)控告警等功能。由于集群聯(lián)邦技術(shù)還在發(fā)展,大多數(shù)企業(yè)傾向于使用這種方式來運維和管理多集群 Kubernetes 環(huán)境。當前vivo主要是通過這種方式管理多集群。
2.2.2 聯(lián)邦集群管理
聯(lián)邦集群主要將資源聯(lián)邦化,實現(xiàn)資源的統(tǒng)一管理和調(diào)度。隨著K8s在數(shù)據(jù)中心大量使用,K8s已成為基礎(chǔ)設(shè)施管理的標準,不同區(qū)域部署已非常普遍。如K8s運行在云上來托管集群、企業(yè)自建數(shù)據(jù)中心的私有云、邊緣計算等。越來越多的企業(yè)投入到多集群管理項目,當然聯(lián)邦集群肯定會增加整體架構(gòu)的復(fù)雜度,集群之間的狀態(tài)同步也會增加控制面的額外開銷。盡管增加了所有的復(fù)雜性,但普遍存在的多集群拓撲引入了新的令人興奮的潛力。這種潛力超越了目前所探索的通過多個集群進行的簡單靜態(tài)應(yīng)用程序編排。事實上,多集群拓撲對于跨不同位置編排應(yīng)用程序和統(tǒng)一對基礎(chǔ)設(shè)施的訪問非常有用。其中,這引入了一種令人興奮的可能性,可以透明而快速地將應(yīng)用程序從一個集群遷移到另一個集群。在處理集群災(zāi)難或關(guān)鍵基礎(chǔ)設(shè)施干預(yù)、擴展或布局優(yōu)化時,移動工作負載是可行的。
vivo在聯(lián)邦集群的探索方向主要有以下四個方面:
資源分發(fā)和編排
彈性突發(fā)
多集群調(diào)度
服務(wù)治理和流量調(diào)度
本次主要分享資源分發(fā)和編排、彈性突發(fā)和多集群調(diào)度以K8s為核心的聯(lián)邦多集群探索。網(wǎng)絡(luò)為核心的能力建設(shè),主要為不同集群的網(wǎng)絡(luò)可以通過如 Service Mesh或者 Mesh Federation打通,就可以實現(xiàn)網(wǎng)絡(luò)流量的靈活調(diào)度和故障轉(zhuǎn)移。實際上,也有很多應(yīng)用通過隧道或者專線打通多個集群,進一步保證了多集群之間網(wǎng)絡(luò)通信的可靠性。vivo網(wǎng)絡(luò)和服務(wù)發(fā)現(xiàn)主要是開源的基礎(chǔ)上自研,可以持續(xù)關(guān)注后面分享。
三、面向應(yīng)用的多集群實踐
云原生技術(shù)的發(fā)展是持續(xù)輸出“事實標準的軟件”,而這些事實標準中,應(yīng)用的彈性、易用性和可移植性是其所解決的三大本質(zhì)問題。
應(yīng)用的彈性:對于云產(chǎn)品的客戶來說等價于業(yè)務(wù)可靠性和業(yè)務(wù)探索與創(chuàng)新的敏捷性,體現(xiàn)的是云計算所創(chuàng)造的客戶價值,應(yīng)用彈性的另一個關(guān)注點在于快速部署、交付、以及在云上的擴縮容能力。這就需要完善的應(yīng)用交付鏈路以及應(yīng)用的云原生開發(fā)框架支撐;
易用性:能更好地發(fā)揮應(yīng)用的彈性,在微服務(wù)軟件架構(gòu)成為主流的情形下,易用性需要考慮通過技術(shù)手段實現(xiàn)對應(yīng)用整體做全局性的治理,實現(xiàn)全局最優(yōu)。這凸顯了 Service Mesh 的服務(wù)能力;
可移植性:實現(xiàn)多集群和混合云無障礙遷移等。
那么一個以應(yīng)用為中心,圍繞應(yīng)用交付的多集群多集群管理具備統(tǒng)一的云原生應(yīng)用標準定義和規(guī)范,通用的應(yīng)用托管和分發(fā)中心,基于 Service Mesh 的跨云的應(yīng)用治理能力,以及 K8s 原生的、面向多集群的應(yīng)用交付和管理體系,將會持續(xù)不斷的產(chǎn)生巨大的價值。vivo當前主要結(jié)合Karmada和CNCF周邊項目來探索以上挑戰(zhàn)。
3.1 面向應(yīng)用的多集群持續(xù)發(fā)布
3.1.1 應(yīng)用發(fā)布
上圖是面向應(yīng)用的多集群持續(xù)發(fā)布架構(gòu),我們主要的工作如下:
管理注冊多個Kubernetes集群并接入Karmada,Karmada負責多個集群的資源調(diào)度編排和故障轉(zhuǎn)移。
容器平臺統(tǒng)一管理K8s資源、Karmada策略和配置。
CICD平臺對應(yīng)用進行單元測試、安全測試、編譯鏡像等操作,配置應(yīng)用的存儲、密鑰、環(huán)境變量、網(wǎng)絡(luò)和資源等,最終對接容器平臺的API生成K8s對象,統(tǒng)一交付。
一個應(yīng)用真正的能管理起來其實很復(fù)雜,如特定的場景需要原地升級和灰度發(fā)布等。為了可以提供更加靈活、高級和易用的應(yīng)用發(fā)布能力,更好地滿足應(yīng)用發(fā)布的需求,最終選擇使用Openkruise。比如上圖有個游戲的應(yīng)用game-2408。它涉及到K8s資源有configmap、secret、pv、pvc、service,openkruise的cloneset、自研的服務(wù)發(fā)現(xiàn)和訪問資源、以及Karmada的PropagationPolicy和OverridePolicy等資源,都能達到12個資源配置。比如存儲等資源都是按需申請和分配的,為了有效管理這些資源和關(guān)系,當前主要通過關(guān)聯(lián)數(shù)據(jù)庫進行管理,并打通cicd和容器平臺的交互,記錄應(yīng)用發(fā)布的狀態(tài)轉(zhuǎn)換,實現(xiàn)應(yīng)用的滾動、灰度等發(fā)布能力,達到可持續(xù)發(fā)布的能力。
為了方便問題定位、K8s資源和Karmada資源的策略關(guān)系,當前Karmada 策略命名規(guī)范如下:
可以識別策略屬于那個workload
避免策略重復(fù),需要加入workload類型
策略名超過63個字符,需要hash處理
xxx為非workload的資源名
遇到的問題總結(jié):
一個資源無法被多個策略匹配,導(dǎo)致如configmap、secret等公用資源無法再次下發(fā)到其它集群。
多個集群之間串行發(fā)布,如發(fā)布完A集群才能發(fā)布B集群的控制。
3.1.2 Openkruise資源解析
當前vivo的應(yīng)用主要通過OpenKruise的Cloneset(無狀態(tài))和AdvancedStatefulset(有狀態(tài))控制器進行發(fā)布。Kamrada目前只能識別K8s默認的資源,其它的資源都需要開發(fā)資源解析。為了解決上面提到的問題,Karmada 引入了 Resource Interpreter Webhook,通過干預(yù)從 ResourceTemplate-> ResourceBinding ->Work ->Resource 的這幾個階段來實現(xiàn)完整的自定義資源分發(fā)能力。
(1)InterpretReplica:
該 hook 點發(fā)生在從 ResourceTemplate 到 ResourceBinding 這個過程中,針對有 replica 功能的資源對象,比如類似 Deployment 的自定義資源,實現(xiàn)該接口來告訴 Karmada 對應(yīng)資源的副本數(shù)。
(2)ReviseReplica:
該 hook 點發(fā)生在從 ResourceBinding 到 Work 這個過程中,針對有 replica 功能的資源對象,需要按照 Karmada 發(fā)送的 request 來修改對象的副本數(shù)。Karmada ?會通過調(diào)度策略把每個集群需要的副本數(shù)計算好,你需要做的只是把最后計算好的值賦給你的 CR 對象。
(3)Retain:
該 hook 點發(fā)生在從 Work 到 Resource 這個過程中,針對 spec 內(nèi)容會在 member 集群單獨更新的情況,可以通過該 hook 告知 Karmada 保留某些字段的內(nèi)容。
(4)AggregateStatus:
該 hook 點發(fā)生在從 ResourceBinding 到 ResourceTemplate 這個過程中,針對需要將 status 信息聚合到 Resource Template 的資源類型,可通過實現(xiàn)該接口來更新 Resource Template 的 status 信息。
3.2 面向應(yīng)用的多集群彈性伸縮
3.2.1 彈性伸縮
跨集群HPA這里定義為FedHPA,使用了K8s原生的HPA,在Karmada控制平面通過FedHpaController實現(xiàn)跨集群的彈性調(diào)度擴縮容。
FedHPA流程:
用戶創(chuàng)建HPA資源,如指定workload、cpu上限、min和max值。
FedController開始計算clusterA和clusterB資源,在clusterA和clusterB創(chuàng)建HPA,并按比例分配集群的min和max。
當集群clusterA和clusterB觸發(fā)定義的cpu資源上限,clusterA和clusterB開始擴容。
Karmada控制平面的clusterA和clusterB的HPA work對象的status里有記錄集群擴容副本情況。
FedHPAController感知到work的變化,并獲取到每個集群真實的副本數(shù),開始更新調(diào)度資源RB和控制平面的workload副本數(shù)。保證了控制平面和member集群的調(diào)度和副本數(shù)一致,不會出現(xiàn)重復(fù)調(diào)度和副本不一致。反之cpu流量下去開始縮容,計算過程一樣。
同時添加了資源再度均衡的能力,當集群資源變化時,F(xiàn)edHPAController會計算集群總資源、節(jié)點碎片、是否可調(diào)度等情況,重新分配每個集群HPA的min和max值,確保在擴容時候有充足的資源。
3.2.2 定時伸縮
定時擴縮容是指應(yīng)在固定時間點執(zhí)行應(yīng)用擴容來應(yīng)對流量的高峰期。K8s本身沒有這個概念,這里在Karmada控制平面定義了CronHpa資源,并通過Karmada-scheduler對多集群統(tǒng)一調(diào)度。避免非聯(lián)邦化集群在多個member集群創(chuàng)建多個cronhpa。定時功能通過go-cron庫實現(xiàn)。
CronHpa流程:
用戶根據(jù)業(yè)務(wù)需求,創(chuàng)建CronHPA。定義擴容時間和縮容時間。
到擴容時間點,CronHPAController開始擴容workload。
Karmada-scheduler開始調(diào)度,根據(jù)每個集群的資源開始合理分配每個集群的副本數(shù)。
到縮容時間點,CronHPAController開始縮容workload。
3.2.3 手動和指定擴縮容
手動擴縮容流程:
用戶指定workload,進行擴容或者縮容。
Kamrada-scheduler開始調(diào)度,合理分配擴容或者縮容值到每個集群。
指定縮容,這里用到了openkruise能力。如訓(xùn)練模型需要將一批性能差的pod進行縮容。
指定縮容流程:
用戶在clusterA 指定workload下面一個pod進行縮容,需要在
ScaleStrategy.PodsToDelete指定pod。
需要在Karmada實現(xiàn)openkurise實現(xiàn)該字段的資源解析,不讓它被控制平面覆蓋。
并在控制平面更新workload的副本和pp資源,保證副本數(shù)和調(diào)度結(jié)果一致。
member集群的openkruise開始刪除指定的pod。
也可以嘗試從Karmada控制平面指定刪除pod和更改調(diào)度的結(jié)果,這樣更加合理些,也不用添加Karmada資源解析。
3.3 統(tǒng)一調(diào)度
3.3.1 多集群調(diào)度
Karmada多集群調(diào)度主要實現(xiàn)跨集群資源的合理分配和集群故障快速遷移業(yè)務(wù)。如上圖所示主要通過Karmada scheudler和emulator配合實現(xiàn),其中emulator主要負責每個集群的資源的估算。
workload調(diào)度流程:
用戶定義workload和策略匹配,生成RB資源。
doSchedulerBinding開始對RB進行調(diào)度,通過預(yù)選和優(yōu)選調(diào)度算法選擇合適的集群,當前不會進行資源計算,和K8s調(diào)度預(yù)選和優(yōu)選不一樣。
selecClusters根據(jù)篩選的集群,進行副本分配。這里有2種模式,主要根據(jù)用戶配置的策略去選擇。
a.Static scheduler 只計算所有資源的request,不考慮調(diào)度規(guī)則。
b.Dynamic scheudler 會在計算所有request的同時,也會考慮一部分調(diào)度規(guī)則。
最終計算出每個集群分配的副本數(shù)并更新RB資源,調(diào)度結(jié)束后其它控制器會根據(jù)RB進一步處理。
故障調(diào)度:
比如當集群clusterA發(fā)生故障,在一定判定條件內(nèi),會觸發(fā)Karmada-scheduler重新調(diào)度。
Karmada-scheduler會將故障集群的資源,調(diào)度到clusrerB和clusterC。
3.3.2 重調(diào)度
重調(diào)度的存在主要解決應(yīng)用下發(fā)到member集群沒有真正的運行起來,導(dǎo)致出現(xiàn)這樣的情況可能是集群資源在不斷的變化,應(yīng)用正在Karmada-scheduler多集群調(diào)度的時候可能滿足,但經(jīng)過member集群二次調(diào)度時候無法調(diào)度。
重調(diào)度流程:
過濾RB資源,發(fā)現(xiàn)RB調(diào)度沒有達到預(yù)期。
對workload發(fā)起重新調(diào)度。
進過預(yù)選、優(yōu)選等流程,再次分配調(diào)度結(jié)果。
最終將workload的所有pod調(diào)度起來。
3.3.3 單集群調(diào)度模擬器
目前社區(qū)單集群的調(diào)度估算器,只是簡單模擬了4種調(diào)度算法。和實際的調(diào)度算法有很大差距,目前線上有很多自研的調(diào)度算法和不同集群需要配置不同算法,這樣估算器的精確度就會下降,導(dǎo)致調(diào)度出現(xiàn)pod pending的情況??梢詫渭旱恼{(diào)度模擬器進行優(yōu)化。
使用fake client 去模擬線上集群。
fake client啟動k8s默認的調(diào)度器以及自研的調(diào)度算法,修改binding接口。并配置到每個member集群。
podRequest請求每個集群調(diào)度模擬器,運行真實的調(diào)度算法,并計算調(diào)度結(jié)果。
3.4 灰度上線
3.4.1? 應(yīng)用遷移
對于通過非聯(lián)邦化資源管理的應(yīng)用,不能直接刪除在創(chuàng)建,需要平滑遷移到Karmada管理,對于用戶無感知。
主要流程如下:
管理員通過容器平臺,將需要遷移的應(yīng)用插入遷移白名單。
用戶通過cicd發(fā)布,容器平臺會進行發(fā)布接口調(diào)用。
isKarmada模塊會查看遷移名單,在白名單內(nèi)將資源聯(lián)邦化,接入Karmada管理。不在白名單內(nèi)保持原有的靜態(tài)集群管理。
最終完成應(yīng)用的發(fā)布,用戶完全無感知。保持2種管理方式并行存在。
3.4.2 應(yīng)用回滾
有了應(yīng)用遷移的能力,是否就可以保證整個流程百分百沒有問題,其實是無法保證的。這就必須有應(yīng)用回滾能力,提升用戶的遷移滿意度。
回滾的必要性總結(jié):
應(yīng)用發(fā)布遷移的過程中發(fā)生了未知的錯誤,并且短時間無法恢復(fù)。避免阻塞應(yīng)用正常發(fā)布,需要回滾。
應(yīng)用被Karmada接管后發(fā)生未知的錯誤,需要避免資源聯(lián)邦化后無法控制,需要回滾。
回滾流程:
管理員通過容器管理平臺,將需要回滾的應(yīng)用從遷移白名單刪除。
并對應(yīng)用對應(yīng)的workload以及關(guān)聯(lián)的資源打上注解。
修改exection-controller源碼,exection-controller發(fā)現(xiàn)以上注解,最終調(diào)用update/create時不做處理。
修改defaultInterpreter源碼,發(fā)現(xiàn)以上注解ReviseReplica不修改副本數(shù)。
這樣就可以阻斷Karmada控制平面和member集群的聯(lián)系。這里為什么沒有直接從Karmada刪除資源,主要避免刪除這種高危操作以及方便后期恢復(fù)后重新接入Karmada。
3.4.3 遷移策略
應(yīng)用遷移Karmada原則:
先測試、再預(yù)發(fā)、最后生產(chǎn)
重大變更,分批次灰度,按照17比例灰度遷移
責任人雙方點檢驗證,并觀察監(jiān)控5~10分鐘
灰度后確認沒有異常后繼續(xù)遷移,否則走回滾流程
四、總結(jié)
vivo當前主要通過非聯(lián)邦多集群管理,結(jié)合CICD實現(xiàn)了應(yīng)用靜態(tài)發(fā)布和管理,具備了應(yīng)用的滾動、灰度、手動擴縮容、指定縮容和彈性擴縮容等能力。相對于非聯(lián)邦多集群部分能力不足,如跨集群統(tǒng)一資源管理、調(diào)度和故障轉(zhuǎn)移等,在聯(lián)邦集群進行部分能力的探索和實踐。同時聯(lián)邦集群增加了整體架構(gòu)的復(fù)雜度,集群之間的狀態(tài)同步也會增加控制面的額外開銷和風(fēng)險。當前社區(qū)在聯(lián)邦集群還處在一個探索和不斷完善的階段,企業(yè)在使用聯(lián)邦集群應(yīng)結(jié)合自身需求、建立完善的運維保障和監(jiān)控體系。對于已經(jīng)存在的非聯(lián)邦化的資源需要建設(shè)遷移和回滾能力,控制發(fā)生故障的范圍和快速恢復(fù)能力。
編輯:黃飛
?
評論
查看更多