多雲容器編排 Karmada-Operator 實踐

2022-09-29 12:01:35

作者:vivo 網際網路伺服器團隊-Zhang Rong

Karmada作為開源的雲原生多雲容器編排專案,吸引了眾多企業共同參與專案開發,並執行於生產環境中。同時多雲也逐步成為資料中心建設的基礎架構,多區域容災與多活、大規模多叢集管理、跨雲彈性與遷移等場景推動雲原生多雲相關技術的快速發展。

一、 背景

隨著vivo業務不斷遷移到k8s上,叢集規模和叢集的數量快速增長,運維難度也急劇增加。為了構建多叢集技術,我們也自研了多叢集管理,但無法解決我們遇到的更多的問題。後來開始對社群相關專案做了細緻的調研和測試,我們最終選擇了Karmada。

主要原因如下:

  • 具備對多套K8s叢集的統一管理能力,業務通過服務維度去管理資源,降低容器平臺的管理難度。
  • 跨叢集的彈性伸縮和排程能力,實現跨叢集的資源合理利用,從而提升資源利用率並節約成本。
  • Karmada完全使用了K8s原生的API,改造成本低。
  • 容災,Karmada控制平面與member叢集解藕,叢集異常時支援資源重新分配。
  • 可延伸性,如可以新增自研的排程外掛和新增自研Openkruise直譯器外掛等。

在我們探索怎麼使用Karmada的同時,我們也遇到了Karmada自身運維的問題。

社群部署工具較多,需要使用者自己選擇。當前使用者部署方式如下:

  • Karmadactl

  • Karmada charts

  • 二進位制部署

  • hack目錄下指令碼

 對於上面的幾種工具,在Karmada的社群開展了問卷調研,並生成了統計報告

主要總結如下:

  • 社群部署工具較多,需要使用者自己選擇。

  • 部署指令碼也存在缺陷,需要使用者自己解決,github上關於這方面的提問較多。

  • 黑畫面化操作,沒有提供k8s api操作,使用者難以產品化,我們主要期望對接我們的容器平臺,實現視覺化安裝。

  • 缺少CI測試和部署工具的釋出計劃。

  • etcd叢集缺少生產環境的關鍵功能點,如etcd的高可用、定期備份和恢復。

  • 需要安裝很多依賴外掛,涉及到Karmada控制平面、Karmada的host叢集和member叢集。

  • 缺少一鍵部署和設定繁瑣等痛點。

針對以上問題,本文將分享Karmada-Operator的vivo實踐,包括Operator的方案選擇、API、架構設計和CI構建等。

二、Karmada-Operator的落地實踐

2.1 Operator SDK介紹

Operator Framework 是一個開源工具包,用於以有效、自動化且可延伸的方式管理 Kubernetes 原生應用程式,即 Operator。Operator 利用 Kubernetes 的可延伸性來展現雲服務的自動化優勢,如置備、擴充套件以及備份和恢復,同時能夠在 Kubernetes 可執行的任何地方執行。

Operator 有助於簡化對 Kubernetes 上的複雜、有狀態的應用程式的管理。然而,現在編寫 Operator 並不容易,會面臨一些挑戰,如使用低階別 API、編寫樣板檔案以及缺乏模組化功能(這會導致重複工作)。

Operator SDK 是一個框架,通過提供以下內容來降低 Operator 的編寫難度:

  • 高階 API 和抽象,用於更直觀地編寫操作邏輯

  • 支架和程式碼生成工具,用於快速引導新專案

  • 擴充套件項,覆蓋常見的 Operator 用例

 圖片

 如上圖所示,operator sdk可以基於helm、ansilbe和go構建operator,我們需根據當前的情況選擇我們合適的operator框架。

2.2 方案選擇

  • 方案一:golang 開發Operator

圖片
  • 方案二:ansible開發Operator

  • 方案三:golang和ansible混合開發Operator

圖片

根據Karmada的實際生產部署調研情況和vivo自身的實踐,可以總結如下:

  1. 要支援在K8s叢集和不依賴K8s叢集二進位制部署。

  2. 支援外部獨立的etcd叢集部署或者對接已有的etcd叢集。

  3. Karmada叢集具備遷移能力,如機房裁撤和機器故障等,就需要etcd叢集管理有備份和恢復能力,如根據etcd備份資料快速在其它機房恢復叢集。

  4. 需要支援第三方的vip給Karmada-apiserver提供負載均衡,目前vivo都是基於外部vip,並提供了域名。沒有使用K8s的service給Karmada-apiserver提供負載均衡。

  5. Karmada控制平面一鍵部署和member叢集的自動化註冊和登出。也需要獲取member叢集的kubeconfig,pull模式也需要在member叢集部署Karmada-agent。

  6. Karmada叢集的addons外掛安裝,如istio、anp、第三方的crd等安裝,需要在Karmada的控制平面、host主機叢集,甚至需要在member叢集上進行設定。

  7. 提供api能力,實現視覺化部署。

  8. 針對Karmada單個元件的單獨升級和全量升級。

  9. 支援在offline和離線模式。

面對Karmada如此複雜的條件限制,我們再來分析下上面3個方案誰可能比較合適。

方案一,基於go開發的Operator,比較適合基於K8s叢集的有狀態服務管理,如etcd,資料庫等,比較成熟的有etcd-Operator。Karmada涉及到不依賴K8s叢集二進位制部署、外部etcd、member叢集的註冊、登出和外掛安裝,不能很好的支援或者需要增加開發量。

方案二,基於ansible開發的Operator,既可以基於K8s叢集的對狀態服務管理,也可以脫離K8s叢集對如不依賴K8s叢集二進位制部署、外部etcd、member叢集的註冊、登出和外掛安裝。這裡主要通過ansible 的ssh登入能力和K8s模組管理,通過調研我們也發現90%以上的使用者可以提供ssh登入。

方案三,基於go+ansible的混合的Operator,讀者可以閱讀vivo開發的Kubernetes-Operator,就是基於這種方案。方案三具備方案二的所有能力,因為底層都是通過ansible去執行。

首先我們排除了方案一,對於方案二和方案三,本人也糾結了很長是時間,最終我們選擇了方案二。主要原因如下:

  1. Operator SDK ansible已具備了和Operator SDK go相等的能力,並提供K8s、K8s_status模組、相似的webhook功能去對k8s的資源管理,以及reconciliation的能力。

  2. 符合目前Karmada實際生產部署的需求。

  3. 簡單易學,只要知道ansbile的jinja模版、和K8s相同的yaml檔案。你只需要編寫ansible task,開箱即用,reconciliation由Operator SDK 解決。

  4. 對於常用ansible的人比較友好,不需要寫golang程式碼。

  5. 擴充套件能力強,使用者可自定義外掛。管理端也支援local、ssh、zeromq三種方式連線。local模式可以直接對接K8s介面,ssh模式可以登入執行指令碼。可以很好的混合使用,解決我們當前的需求。

  6. Karmada運維操作相對K8s要簡單,不需要複雜的crd定義,ansible需要解析少量vars去執行playbook就行。golang+ansible模式比較適合複雜CRD定義和業務邏輯複雜的系統。

2.3 API設計

圖片

如上圖所示,我們只需要執行Operator-SDK create api命令,就可以建立 KarmadaDeployment的CRD,然後就可以定義KarmadaDeployment的API。在watches.yaml裡實現Reconcile的業務邏輯。

圖片

 

這裡主要定義KarmadaDeployment、EtcdBackup和EtcdRestore個資源,分別用於Karmada的部署,和etcd的資料備份和恢復。ansible Operator會根據spec裡定義解析成ansible的vars。status將通過 ansible runner 輸出為使用者自定義的狀態。也可以通過ansible的k8s_status更新KarmadaDeployment的狀態。當前主要考慮的是在K8s執行Karmada,後面會新增二進位制部署模式,當前的CR沒有涉及。

2.4 架構設計

圖片

 如圖所示Karmada Operator提供了容器化和二進位制叢集部署設計,其中Karmada的容器化部署不需要執行ssh登入,只需通過K8s和k8s_status就可以完成karmada控制面的管控。Karmada的二進位制部署主要通過ssh登入完成Karmada控制平面的管控。member叢集的join和unjoin需要提前提供member叢集的kubeconfig檔案,也可以設定member的登入許可權操作,需要在CR裡定義member叢集的使用者和金鑰。

 

執行流程如下。

  1. 使用者通過KarmadaDeployment定義Karmada操作

  2. Karmada Operator感知KarmadaDeployment的CR變化,開始進入控制器邏輯

  3. 根據使用者的定義,選擇是容器化部署或者二進位制部署,開始執行安裝、擴所容和備份等操作

  4. 執行join/unjoin操作,將member叢集註冊到Karmada叢集或者登出member叢集

2.5 Karmada控制平面管理

圖片

 如上圖所示,主要是karmada控制平面生命週期管理,對比當前社群的部署工具我們如下優化:

  1. 標準化證書管理,主要是用openssl生成證書。其中etcd和Karmada證書單獨分開維護,和k8s叢集證書命名相同,方便接入我們的監控。

  2. Karmada-apiserver支援外部負載均衡,不限於當前的k8s service提供的負載均衡。

  3. 更靈活的升級策略,支援單獨元件升級和全量升級。

  4. 更豐富的全域性變數定義,計劃支援元件設定變更等。

2.6 etcd叢集管理

圖片

 etcd叢集是Karmada的後設資料叢集,生產中需要保證etcd叢集高可用和故障恢復等。如上圖展示了etcd叢集必要的生產要素,如自動擴縮容、升級、備份和etcd叢集的故障恢復。自研了基於ansible的pluginslibrary, 實現etcd叢集管理能力如下:

  1. 新增member到存在的etcd叢集。

  2. etcd叢集刪除member。

  3. etcd叢集的備份,比如支援cephfs的資料備份。

  4. etcd叢集故障恢復。

  5. etcd叢集健康狀態查詢。

 這裡定義了etcdBackup和etcdRestore的CR,沒有合併到KarmadaDeployment裡。主要考慮到etcd叢集本身操作的安全性和簡化KarmadaDeployment的ansible任務。其中etcdRestore功能,可以根據etcd叢集備份資料,實現匯入到新的etcd叢集,從而恢復Karmada叢集所有的業務狀態。當前主要場景如下:

  1. Karmada叢集所在的機房裁撤,需要備份etcd資料,遷移到新的Karmada叢集。

  2. 期望通過Karmada-Operator管理Karmada叢集,只需備份etcd資料,實現etcdRestore功能即可。

  3. Karmada叢集故障,可以通過etcd備份資料,結合etcdRestroe實現故障恢復。

2.7 member叢集管理

圖片

 member叢集的生命週期管理主要有註冊和登出,上圖是執行的流程。為了處理member叢集的註冊和登出,這裡會動態的生成inventory。Ansible Inventory 是包含靜態 Inventory 和動態 Inventory 兩部分的,靜態 Inventory 指的是在檔案中指定的主機和組,動態 Inventory 指通過外部指令碼獲取主機列表,並按照 ansible 所要求的格式返回給 ansilbe 命令的。

這裡Karmada-Operator基於k8s的CR實現了動態inventory plugins,主要通過解析KarmadaDeployment的members定義去動態的生成inventory。這裡新增了add-member和del-member 2個角色, add-member裡叢集會被註冊到Karmada控制平面,del-member裡的叢集會被從Karmada控制平面登出,這樣就可以並行的註冊和登出多個member叢集。同時也可以提供ssh登入模式,方便後期擴充套件。

三、Karmada-Operator的CI介紹

圖片

為了更好的提高開發人員的體驗,計劃提供Karmada-Operator的CI構建能力。這裡在K8s叢集裡部署github的self-hosted Runner和kubevirt。

  1. 使用者在github上提交PR

  2. 觸發github Actions,我們在self-hosted裡定義的流程

  3. 執行語法和單元測試

  4. 通過kubevirt建立vm

  5. 在多個vm裡部署1個host和2個member叢集

  6. 部署Karmada和新增member叢集

  7. 執行Karmada e2e和bookfinfo案例測試

 

計劃新增的CI矩陣測試如下:

  • 語法測試:

  • ansible-lint

  • shellcheck

  • yamllint

  • syntax-check

  • pep8

 

  • 叢集部署測試:

  • Karmadactl、charts、yaml和二進位制部署和所有設定項安裝測試

  • join/ unjoin member 叢集

  • 升級Karmada

  • etcd叢集的備份和恢復

 

  • 功能測試:

  • Karmada e2e測試

  • 建立bookinfo案例

  • 效能測試:

我們主要通過kubemark元件模擬了多個2000節點的member叢集進行了效能測試,其中一個測試案例是叢集故障轉移,結論是4w個無狀態pod能夠在15分鐘完成故障遷移,有機會可以分享我們的效能測試。

四、總結

通過社群的調研和vivo的實踐,最終確定了Karmada-Operator方案設計。Karmada-Operator具有高度可延伸性、可靠性、更直觀地編寫操作邏輯和開箱即用等特點,我們相信通過這種高度可延伸的宣告式、自我修復雲原生系統管理Karmada,為我們全面切換到Karmada去管理業務提供了強有力可靠保障。

基於ansible的operator也存在如下缺點。第一點沒有提供webhook的能力,需要自己新增或者在ansible的task新增相關的校驗;第二點是自動生成了通用的CRD模版,沒有詳細可定義的腳手架工具去自動生成CRD。

當前Karmada-operator還在初始階段,提供了方案和部分實踐,具體功能還需不斷的完善和改進。具體可以檢視vivo的Karmada-Operator倉庫,歡迎大家試用和提建議。當前程式碼提供的能力矩陣可以檢視專案規劃