Kubernetes 多集群在開源項目 KubeSphere 的應用

  • 2020 年 8 月 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 官網//kubesphere.io/
KubeSphere GitHub//github.com/kubesphere/kubesphere

KubeSphere 微信公眾號

本文由博客一文多發平台 OpenWrite 發佈!