Kubernetes 多叢集在開源專案 KubeSphere 的應用

kubesphere發表於2020-08-21

Kubernetes 多叢集使用場景

隨著容器的普及和 Kubernetes 的日漸成熟,企業內部執行多個 Kubernetes 叢集已變得頗為常見。概括起來,多個叢集的使用場景主要有以下幾種。

多叢集使用場景

高可用

可以將業務負載分佈在多個叢集上,使用一個全域性的 VIP 或者 DNS 域名將請求傳送到對應的後端叢集,當一個叢集發生故障無法處理請求時,將 VIP 或者DNS記錄切換健康的叢集。

高可用

低延遲

在多個區域部署叢集,將使用者請求轉向距離最近的叢集處理,以此來最大限度減少網路帶來的延遲。舉個例子,假如在北京,上海,廣州三地部署了三個 Kubernetes 叢集,對於廣東的使用者就將請求轉發到所在廣州的叢集處理,這樣可以減少地理距離帶來的網路延遲,最大限度地實現各地一致的使用者體驗。

故障隔離

通常來說,多個小規模的叢集比一個大規模的叢集更容易隔離故障。當叢集發生諸如斷電、網路故障、資源不足引起的連鎖反應等問題時,使用多個叢集可以將故障隔離在特定的叢集,不會向其他叢集傳播。

業務隔離

雖然 Kubernetes 裡提供了 namespace 來做應用的隔離,但是這只是邏輯上的隔離,不同 namespace 之間網路互通,而且還是存在資源搶佔的問題。要想實現更進一步的隔離需要額外設定諸如網路隔離策略,資源限額等。多叢集可以在物理上實現徹底隔離,安全性和可靠性相比使用 namespace 隔離更高。例如企業內部不同部門部署各自獨立的叢集、使用多個叢集來分別部署開發/測試/生成環境等。

流水線

避免單一廠商鎖定

Kubernetes 已經成容器編排領域的事實標準,在不同雲服務商上部署叢集避免將雞蛋都放在一個籃子裡,可以隨時遷移業務,在不同叢集間伸縮。缺點是成本增加,考慮到不同廠商提供的 Kubernetes 服務對應的儲存、網路介面有差異,業務遷移也不是輕而易舉。

多叢集部署

上面說到了多叢集的主要使用場景,多叢集可以解決很多問題,但是它本身帶來的一個問題就是運維複雜性。對於單個叢集來說,部署、更新應用都非常簡單直白,直接更新叢集上的yaml即可。多個叢集下,雖然可以挨個叢集更新,但如何保證不同叢集的應用負載狀態一致?如何在不同叢集間做服務發現?如何做叢集間的負載均衡?社群給出的答案是聯邦叢集(Federation)。

Federation v1

federation-v1

Federation 方案經歷了兩個版本,最早的 v1 版本已經廢棄。在 v1 版本中,整體架構與 Kubernetes 自身的架構非常相似,在管理的各個叢集之前引入了 Federated APIServer 用來接收建立多叢集部署的請求,在控制平面的 Federation Controller Manager 負責將對應的負載建立到各個叢集上。

annotations

在 API 層面上,聯邦資源的排程通過 annotation 實現,最大程度地保持與原有 Kubernetes API 的相容,這樣的好處是可以複用現有的程式碼,使用者已有的部署檔案也不需要做太大改動即可遷移過來。但這也是制約 Federation 進一步的發展,無法很好地對 API 進行演進,同時對於每一種聯邦資源,需要有對應的 Controller 來實現多叢集的排程,早期的 Federation 只支援有限的幾種資源型別。

Federation v2

federation-v2

社群在 v1 的基礎上發展出了 Federation v2,即 Kubefed。Kubefed 使用 Kubernetes 已經相對成熟的 CRD 定義一套自己的 API 規範,拋棄了之前使用的 annotation 方式。架構上也較之前有很大改變,放棄了之前需要獨立部署的 Federated APIServer/etcd,Kubefed 的控制平面採用了流行的 CRD + Controller 的實現方式,可以直接安裝在現有的 Kubernetes 叢集上,無需額外的部署。

v2定義的資源型別主要包含4種:

Cluster Configuration:定義了 Member Cluster 加入到控制平面時所需要用到的註冊資訊,包含叢集的名稱, APIServer 地址以及建立部署時需要用到的憑證。

Type Configuration:定義了 Federation 可以處理的資源物件。每個 Type Configuration 即是一個 CRD 物件,包含下面三個配置項:

  • Template Template 包含了要處理的資源物件,如果處理的物件在即將部署的叢集上沒有相應的定義,則會建立失敗。下面例子中的 FederatedDeployment,template 包含了建立 Deployment 物件所需要的全部資訊。
  • Placement 定義了該資源物件將要建立到的叢集名稱,可以使用 clusters 和 clusterSelector 兩種方式。
  • Override 顧名思義,Override 可以根據不同叢集覆蓋 Template 中的內容,做個性化配置。下面例子中,模板定義的副本數為 1,Override 裡覆蓋了 gondor 叢集的副本數,當部署到 gondor 叢集時不再時模板中的 1 副本,而是 4 副本。Override 實現了 jsonpatch 的一個子集,理論上 template 裡的所有內容都可以被覆蓋。

FederatedDeployment

Schedule:主要定義應用在叢集間的分佈,目前主要涉及到 ReplicaSet 和Deployment。可以通過 Schedule 定義負載在叢集中的最大副本和最小副本數,這部分是將之前 v1 中通過 annotation 排程的方式獨立出來。

MultiClusterDNS:MultiClusterDNS 實現了多個叢集間的服務發現。多叢集下的服務發現相比單個叢集下要複雜許多,kubefed 裡使用了 ServiceDNSRecord、IngressDNSRecord、DNSEndpoint 物件來處理多叢集的服務發現,需要配合 DNS 使用。

總體來說,Kubefed 解決了 v1 存在的許多問題,使用 CRD 的方式很大程度地保證了聯邦資源的可擴充套件性,基本上 Kubernetes 所有的資源都可以實現多叢集部署,包含使用者自定義的 CRD 資源。

Kubefed 目前也存在一些值得關注的問題:

  • 單點問題:Kubefed 的控制平面即是 CRD + Controller 的實現方式,雖然 controller 本身可以實現高可用,但如果其執行所在的 Kubernetes 無法使用,則整個控制平面即會失效。這點上在社群中也有討論,Kubefed 目前使用的是一種 Push reconcile 的方式,當聯邦資源建立時,由控制平面上對應的 Controller 將資源物件的傳送對應的叢集上,至於資源之後怎麼處理那是 Member Cluster 自己的事情了,和控制平面無關。所以當 Kubefed 控制平面不可用時,不影響已經存在的應用負載。

  • 成熟度:Kubefed 社群不如 Kubernetes 社群活躍,版本迭代的週期較長,目前很多功能仍處在 beta 階段。

  • 過於抽象:Kubefed 使用 Type Configuration 來定義需要管理的資源,不同的 Type Configuration 僅是 Template 不同,好處是對應處理邏輯可以統一,便於快速實現,Kubefed 裡 Type Configuration 資源對應的 Controller 都是模板化的。但是缺點也很明顯,不能針對特殊的 Type 實現個性化的功能。例如 FederatedDeployment 物件,對於 Kubefed 來說僅需要根據 Template 和 Override 生成對應的 Deployment 物件,然後建立到 Placement 指定的叢集,至於 Deployment 在叢集上是否生成了對應的 Pod,狀態是否正常則不能反映到 FederatedDeployment 上,只能去對應的叢集上檢視。社群目前也意識到這點,正在積極的解決,已經有對應的提案

KubeSphere 多叢集

上面提到的 Federation 是社群提出的解決多叢集部署問題的方案,可以通過將資源聯邦化來實現多叢集的部署。對於很多企業使用者來說,多叢集的聯合部署其實並不是剛需,更需要的在一處能夠同時管理多個叢集的資源即可。

我們開源的 KubeSphere v3.0 支援了多叢集管理的功能,實現了資源獨立管理和聯邦部署的功能,支援對叢集與應用等不同維度的資源實現監控、日誌、事件與審計的查詢,以及多渠道的告警通知,以及可以結合 CI/CD 流水線部署應用至多個叢集中。

kubesphere-workflow

許可權管理基於 Kubefed、RBAC 和 Open Policy Agent,多租戶的設計主要是為了方便業務部門、開發人員與運維人員在一個統一的管理皮膚中對資源進行隔離與按需管理。

business

整體架構

kubesphere-架構

KubeSphere 多叢集的整體架構圖如圖所示,多叢集控制平面所在的叢集稱之為 Host 叢集,其管理的叢集稱為 Member 叢集,本質上是一個安裝了 KubeSphere 的 Kubernetes 叢集,Host 叢集需要能夠訪問 Member 叢集的 kube-apiserver,Member 叢集之間的網路連通性沒有要求。管理叢集 Host Cluster 獨立於其所管理的成員叢集,Member Cluster 並不知道 Host Cluster 存在,這樣做的好處是當控制平面發生故障時不會影響到成員叢集,已經部署的負載仍然可以正常執行,不會受到影響。

Host 叢集同時承擔著 API 入口的作用,由 Host Cluster 將對 Member 叢集的資源請求轉發到 Member 叢集,這樣做的目的是方便聚合,而且也利於做統一的許可權認證。

認證鑑權

從架構圖上可以看出,Host 叢集負責同步叢集間的身份和許可權資訊,這是通過 Kubefed 的聯邦資源實現的,Host 叢集上建立 FederatedUser/FederatedRole/FederatedRoleBinding ,Kubefed 會將 User/Role/Rolebinding 推送到 Member 叢集。涉及到許可權的改動只會應用到 Host 叢集,然後再同步到 Member 叢集。這樣做的目的是為了保持每個 Member 叢集的本身的完整性,Member 叢集上儲存身份和許可權資料使得叢集本身可以獨立的進行鑑權和授權,不依賴 Host 叢集。在 KubeSphere 多叢集架構中,Host 叢集的角色是一個資源的協調者,而不是一個獨裁者,儘可能地將權力下放給 Member 叢集。

叢集連通性

KubeSphere 多叢集中只要求 Host 叢集能夠訪問 Member 叢集的 Kubernetes APIServer,對於叢集層面的網路連通性沒有要求。KubeSphere中對於 Host 和 Member 叢集的連線提供了兩種方式:

直接連線:如果 Member 叢集的 kube-apiserver 地址可以在 Host 叢集上的任一節點都能連通,那麼即可以使用這種直接連線的方式,Member 叢集只需提供叢集的 kubeconfig 即可。這種方式適用於大多數的公有云 Kubernetes 服務,或者 Host 叢集和 Member 叢集在同一網路的情形。

代理連線:如果 Member 叢集在私有網路中,無法暴露 kube-apiserver 地址, KubeSphere 提供了一種代理的方式,即 Tower。具體來說 Host 叢集上會執行一個代理服務,當有新叢集需要加入時,Host 叢集會生成加入所有的憑證資訊,Member 叢集上執行 Agent 會去連線 Host 叢集的代理服務,連線成功後建立一個反向代理隧道。由於 Member 叢集的 kube-apiserver 地址在代理連線下會發生變化,需要 Host 叢集為 Member 叢集生成一個新的 Kubeconfig 。這樣的好處是可以遮蔽底層細節,對於控制平面來說無論是直接連線還是代理方式連線,呈現給控制平面的都是一個可以直接使用的 Kubeconfig。

cluster-tunnel

API 轉發

api-轉發

KubeSphere 多叢集架構中,Host 叢集承擔著叢集入口的職責,所有的使用者請求 API 是直接發往 Host 叢集,再由 Host 叢集決定請求發往何處。為了儘可能相容之前的 API,在多叢集環境下,API 請求路徑中以 /apis/clusters/{cluster} 開頭的請求會被轉發到 {cluster} 叢集,並且去除 /clusters/{cluster},這樣的好處對應的叢集收到請求和其他的請求並無任何區別,無需做額外的工作。舉個例子:

api-轉發1

會被轉發到名稱為 rohan 的叢集,並且請求會被處理為:

api-轉發2

總結

多叢集問題遠比想象的要複雜,從社群 Federation 方案就能看出,經歷了前後兩個版本但是時至今日還未釋出正式版。軟體領域有句經典的話,No Silver Bullet,Kubefed、KubeSphere 等多叢集工具並不能也不可能解決多叢集的所有問題,還是需要根據具體業務場景選擇合適自己的。相信隨著時間的推移,這些工具也會變得更加成熟,屆時可以覆蓋到更多的使用場景。

Q&A

Q:多叢集方案是偏向高可用還是容災方向?如果是高可用(涉及到跨叢集呼叫),應該如何對微服務進行改造,比如 Spring Cloud?

A:多叢集可以用來做高可用,也可以用來做容災,社群的 Federation 方案是比較通用的方案,比較偏向容災。高可用一般需要結合具體的業務來看,Federation 更偏向一個多叢集部署,至於底層資料如何同步來支援 HA 需要業務本身來做了。

Q:多叢集的管理操作介面是自研的嗎?如果是,能分享下大致的研發步驟和介面操作圖給大家嗎?

A:Yes,是自研的。操作介面可以通過下面幾個視訊瞭解下:

Q:大佬,你們的業務在Kubernetes中執行期間有碰到一些網路通訊問題嗎?能分享下問題和大致排查步驟嗎,謝謝。

A:網路問題太多了,可以看看這個,能覆蓋大部分網路問題場景了。至於太難的,不容易碰到。

Q:聯邦層面的 HPA 你們是怎麼處理的呢?

A:目前 KubeSphere 多叢集中還沒有涉及到多叢集的 HPA,這需要對底層的監控設施進行一定的改造,在 roadmap 裡。

Q:我們之前也有嘗試使用聯邦來解決多叢集下的服務發現問題,但是後面還是放棄了,不敢用,能否分享下多叢集服務發現這塊的解決方案呢?

A:是的,Kubefed 服務發現相比較單個叢集不是那麼好用,這塊我們也在和社群一起積極推進,遇到問題還是要向社群提 issue 的,幫助社群瞭解使用者場景,也是為開源做貢獻 : )

Q:KubeSphere 在多雲管理的時候,如何打通公有云和私有云?另外是否會動態調整不同叢集裡的 Pod 副本數?依據是什麼?

A:KubeSphere 管理的叢集是一個 KubeSphere 叢集,實際是用 Kubernetes 來消除了公有云和私有云底層的異構性,需要解決的僅是網路問題。今天分享提到了 KubeSphere 多叢集如何實現和 Member Cluster 的連通性,有一種方式就是適合私有云的,可以瞭解下。

Q:多叢集下的 http 的解決方案是什麼,我們在用的單叢集是 ingress-nginx -》service,多叢集該如何處理?

A:多叢集下如果你使用的是 kubefed ,那麼可以瞭解下 multiclusterdns,裡面有做多叢集 Ingress 的。如果不是的話,只是多個獨立的 Kubernetes 叢集,那就需要人肉去配置下了。

本文來自 KubeSphere 團隊在 DockOne 社群的分享,您可以檢視原文

相關連結:

關於 KubeSphere

KubeSphere 是在 Kubernetes 之上構建的容器混合雲,提供全棧的 IT 自動化運維的能力,簡化企業的 DevOps 工作流。

KubeSphere 已被 Aqara 智慧家居、本來生活、新浪、中國人保壽險、華夏銀行、浦發矽谷銀行、四川航空、國藥集團、微眾銀行、紫金保險、Radore、ZaloPay 等海內外數千家企業採用。KubeSphere 提供了運維友好的嚮導式操作介面和豐富的企業級功能,包括多雲與多叢集管理、Kubernetes 資源管理、DevOps (CI/CD)、應用生命週期管理、微服務治理 (Service Mesh)、多租戶管理、監控日誌、告警通知、儲存與網路管理、GPU support 等功能,幫助企業快速構建一個強大和功能豐富的容器雲平臺。

KubeSphere 官網https://kubesphere.io/
KubeSphere GitHubhttps://github.com/kubesphere/kubesphere

KubeSphere 微信公眾號

本文由部落格一文多發平臺 OpenWrite 釋出!

相關文章