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