本文發表於一年多前。舊文章可能包含過時內容。請檢查頁面中的資訊自發布以來是否已變得不正確。

Kubernetes Federation 演進

Kubernetes 為將應用程式部署到叢集提供了出色的原語:它可以像 kubectl create -f app.yaml 一樣簡單。在多個叢集中部署應用程式從未如此簡單。應用程式工作負載應該如何分配?應用程式資源應該複製到所有叢集、複製到選定的叢集,還是分割槽到叢集中?如何管理對叢集的訪問?如果使用者想要分發的一些資源以某種形式預先存在於部分或所有叢集中,會發生什麼?

在 SIG Multicluster 中,我們的探索表明存在多種可能的模型來解決這些問題,並且可能沒有一個單一的最佳解決方案。然而,Kubernetes Cluster Federation (簡稱 KubeFed) 是最大的 Kubernetes 開源子專案,並且在這個問題領域獲得了社群最大的興趣和貢獻。該專案最初重用了 Kubernetes API,以消除現有 Kubernetes 使用者的額外使用複雜性。這種方法不可行,原因總結如下:

  • 在叢集級別重新實現 Kubernetes API 存在困難,因為聯邦特定的擴充套件儲存在註解中。
  • 由於 Kubernetes API 的 1:1 模擬,聯邦型別、放置和協調的靈活性有限。
  • 沒有明確的 GA 路徑,並且對 API 成熟度普遍存在困惑;例如,Deployments 在 Kubernetes 中是 GA 狀態,但在 Federation v1 中甚至不是 Beta 狀態。

這些想法隨著聯邦特定的 API 架構和社群努力而進一步發展,目前以 Federation v2 的形式繼續。

概念概述

由於聯邦試圖解決一系列複雜問題,因此有必要將這些問題的不同部分分解開來。讓我們看看所涉及的不同高階領域:

Kubernetes Federation v2 Concepts

Kubernetes Federation v2 概念

聯邦任意資源

聯邦的主要目標之一是能夠定義 API 和 API 組,這些 API 和 API 組包含聯邦任何給定 Kubernetes 資源所需的基本原則。這至關重要,因為 CustomResourceDefinitions 作為一種用新 API 擴充套件 Kubernetes 的方式非常流行。

工作組就聯邦 API 和 API 組的共同定義達成一致,即“一種將‘普通’Kubernetes API 資源分發到不同叢集的機制”。最簡單的分發形式可以想象為將這種“普通 Kubernetes API 資源”簡單地傳播到聯邦叢集中。細心的讀者當然可以辨別出比這種簡單的 Kubernetes 資源傳播更復雜的機制。

在定義聯邦 API 的構建塊的過程中,一個近期目標也演變為“能夠建立簡單的聯邦,即任何 Kubernetes 資源或 CRD 的簡單傳播,幾乎無需編寫程式碼”。隨後,一個核心 API 組定義了構建塊,包括每個給定 Kubernetes 資源的 `Template` 資源、`Placement` 資源和 `Override` 資源,以及一個 `TypeConfig` 用於指定給定資源是否同步,以及執行同步的關聯控制器。更多詳細資訊請參閱下一節。後續章節還將討論如何透過更高級別的聯邦 API 消耗這些核心構建塊的行為來實現分層行為,以及使用者能夠消費 API 的全部或部分以及關聯的控制器。最後,這種架構還允許使用者編寫額外的控制器或用自己的控制器替換可用的參考控制器,以實現所需行為。

能夠“輕鬆聯邦任意 Kubernetes 資源”,以及解耦的 API,分為構建塊 API、高階 API 和可能的面向使用者型別,以便不同使用者可以消費部分並編寫控制器以組成特定於他們的解決方案,這些都為 Federation v2 提供了令人信服的理由。

聯邦資源:詳細資訊

從根本上說,聯邦必須配置兩種型別的資訊:

  • 聯邦應該處理哪些 API 型別
  • 聯邦應該針對哪些叢集來分發這些資源。

對於聯邦處理的每種 API 型別,宣告狀態的不同部分存在於不同的 API 資源中:

  • Template 型別儲存資源的基本規範——例如,一個名為 FederatedReplicaSet 的型別儲存了應該分發到目標叢集的 ReplicaSet 的基本規範。
  • Placement 型別儲存資源應該分發到的叢集的規範——例如,一個名為 FederatedReplicaSetPlacement 的型別儲存了關於 FederatedReplicaSets 應該分發到哪些叢集的資訊。
  • 可選的 Overrides 型別儲存了在某些叢集中如何更改 Template 資源的規範——例如,一個名為 FederatedReplicaSetOverrides 的型別儲存了關於在某些叢集中如何更改 FederatedReplicaSet 的資訊。

這些型別都透過名稱關聯起來——這意味著對於一個名稱為 `foo` 的特定 Template 資源,該資源的 Placement 和 Override 資訊包含在名稱為 `foo` 且與 Template 位於同一名稱空間中的 Override 和 Placement 資源中。

高階行為

v2 API 的架構允許為給定資源構建更高層次的 API,這些 API 利用了核心 API 型別(`Template`、`Placement` 和 `Override`)及其關聯控制器提供的機制。在社群中,我們發現了幾個用例,併為這些用例實現了有用的更高層次 API 和關聯控制器。在後續章節中描述的一些型別也為任何有興趣解決更復雜用例的人提供了有用的參考,這些用例基於 v2 API 已有的機制構建。

副本排程偏好

ReplicaSchedulingPreference 提供了一種自動化機制,用於將基於 Deployment 或 ReplicaSet 的聯邦工作負載的總副本數分配並維護到聯邦叢集中。這基於使用者給出的高階使用者偏好。這些偏好包括加權分配和分發副本的限制(最小和最大值)的語義。它們還包括在某些副本 Pod 在某些叢集中未排程的情況下(例如,由於該叢集資源不足)動態重新分配副本的語義。更多詳細資訊可以在 ReplicaSchedulingPreferences 使用者指南中找到。

聯邦服務和跨叢集服務發現

Kubernetes 服務在構建微服務架構中非常有用。人們強烈希望在叢集、區域、地區和雲邊界之間部署服務。跨叢集的服務提供地理分佈,支援混合雲和多雲場景,並提高了超越單個叢集部署的高可用性水平。希望其服務跨一個或多個(可能是遠端的)叢集的客戶需要能夠以一致的方式從叢集內部和外部訪問這些服務。

聯邦 Service 的核心包含一個 Template(Kubernetes Service 的定義)、一個 Placement(要部署到的叢集)、一個 Override(特定叢集中的可選變體)和一個 ServiceDNSRecord(指定如何發現它的詳細資訊)。

注意:聯邦服務必須是 LoadBalancer 型別,才能在叢集之間被發現。

從聯邦叢集中的 Pod 發現聯邦服務

預設情況下,Kubernetes 叢集預先配置了叢集本地 DNS 伺服器,以及一個智慧構建的 DNS 搜尋路徑,它們共同確保 Pod 內執行的軟體發出的 DNS 查詢(如 `myservice`、`myservice.mynamespace` 或 `some-other-service.other-namespace`)會自動展開並正確解析為在本地叢集中執行的服務的相應 IP。

隨著聯邦服務和跨叢集服務發現的引入,這一概念得到了擴充套件,以涵蓋在全球範圍內跨叢集聯邦的任何其他叢集中執行的 Kubernetes 服務。要利用這一擴充套件範圍,您需要使用略有不同的 DNS 名稱(例如 `myservice.mynamespace.myfederation`)來解析聯邦服務。使用不同的 DNS 名稱還可以避免您的現有應用程式意外地遍歷跨區域或跨區域網路,並且在您沒有明確選擇此行為的情況下,您可能不會產生不必要的網路費用或延遲。

讓我們考慮一個使用名為 nginx 的服務的例子。

us-central1-a 可用區中的一個 Pod 需要聯絡我們的 nginx 服務。它可以使用服務的聯邦 DNS 名稱 nginx.mynamespace.myfederation,而不是使用服務傳統的叢集本地 DNS 名稱(nginx.mynamespace,它會自動擴充套件為 nginx.mynamespace.svc.cluster.local)。這將被自動擴充套件並解析到我的 nginx 服務最近的健康分片,無論它位於世界的哪個地方。如果本地叢集中存在健康分片,將返回該服務的叢集本地 IP 地址(由叢集本地 DNS)。這與非聯邦服務解析完全相同。

如果服務在本地叢集中不存在(或者存在但沒有健康的後端 Pod),DNS 查詢會自動擴充套件為 `nginx.mynamespace.myfederation.svc.us-central1-a.us-central1.example.com`。在後臺,這會找到離我的可用區最近的分片的外部 IP。此擴充套件由叢集本地 DNS 伺服器自動執行,該伺服器返回關聯的 CNAME 記錄。這導致遍歷 DNS 記錄的層次結構,並最終到達附近聯邦服務的某個外部 IP。

透過明確指定適當的 DNS 名稱,並且不依賴自動 DNS 擴充套件,還可以將服務分片定位到 Pod 所在可用區和區域之外的可用區和區域。例如,`nginx.mynamespace.myfederation.svc.europe-west1.example.com` 將解析到歐洲所有當前健康的服務分片,即使發出查詢的 Pod 位於美國,並且無論服務在美國是否有健康的分片。這對於遠端監控和其他類似應用程式非常有用。

從聯邦叢集之外的其他客戶端發現聯邦服務

對於外部客戶端,目前無法實現自動 DNS 擴充套件。外部客戶端需要指定聯邦服務的完整合格 DNS 名稱之一,無論是區域、區域或全域性名稱。為了方便起見,通常最好手動配置您服務中的額外靜態 CNAME 記錄,例如:

短名稱CNAME
eu.nginx.acme.comnginx.mynamespace.myfederation.svc.europe-west1.example.com
us.nginx.acme.comnginx.mynamespace.myfederation.svc.us-central1.example.com
nginx.acme.comnginx.mynamespace.myfederation.svc.example.com

這樣,您的客戶就可以始終使用左側的簡短形式,並始終自動路由到其本洲最近的健康分片。所有必要的故障轉移都由 Kubernetes 叢集聯邦自動為您處理。

作為進一步閱讀,Multi-Cluster Service DNS with ExternalDNS 指南中提供了更詳細的使用者示例

親身體驗

要開始使用 Federation v2,請參考使用者指南。部署可以透過 Helm chart 完成,一旦控制平面可用,可以使用使用者指南的示例來親身體驗 Federation V2 的使用。

Federation v2 可以部署為叢集範圍名稱空間範圍配置。叢集範圍部署將需要主機叢集和成員叢集的叢集管理員許可權,可能適合在未執行關鍵工作負載的叢集上評估聯邦。名稱空間範圍部署只需要主機叢集和成員叢集上單個名稱空間的訪問許可權,更適合在執行工作負載的叢集上評估聯邦。使用者指南的大部分內容都涉及叢集範圍部署,而名稱空間聯邦部分則說明了名稱空間部署的不同之處。同一個叢集可以託管多個聯邦,並且在使用名稱空間聯邦時,叢集可以成為多個聯邦的一部分。

後續步驟

正如我們在本文開頭指出的那樣,多叢集問題空間非常廣泛。如果沒有具體的軟體來圍繞這些對話進行框架,很難確切地知道如何處理如此廣泛的問題空間。我們希望在聯邦工作組中,Federation v2 能夠成為一個具體的構件,以圍繞其展開討論。我們很樂意瞭解人們在這個問題空間中的經驗,他們對 Federation v2 的看法,以及他們未來有興趣探索的用例。

歡迎加入我們的 sig-multicluster slack 頻道或參加每週三太平洋時間 07:30 舉行的 聯邦工作組會議