如何連接不同資料中心的 Kubernetes 集群

如何連接不同資料中心的 Kubernetes 集群
歡迎來到我們的 Kubernetes 快速入門系列。 這是一個定期專欄,其中包含我們在線上和培訓中收到的最有趣的問題。 Kubernetes 專家解答。

今天的專家是 Daniel Polenchik(丹尼爾波倫西奇)。 丹尼爾在以下公司擔任講師和軟體開發人員 學習8s.

如果您希望在下一篇文章中回答您的問題, 透過電子郵件聯絡我們推特:@learnk8s.

錯過了以前的帖子嗎? 在這裡找到他們.

如何連接不同資料中心的Kubernetes叢集?

簡要地: Kubefed v2 即將推出,我還建議閱讀有關 發貨人 и 多集群調度程序項目.

通常,基礎設施會在不同區域進行複製和分佈,尤其是在受控環境中。

如果一個區域不可用,流量將被重定向到另一個區域以避免中斷。

借助 Kubernetes,您可以使用類似的策略並將工作負載指派到不同的區域。

您可以為每個團隊、區域、環境或這些元素的組合擁有一個或多個叢集。

您的叢集可以託管在不同的雲端和本地端。

但如何針對如此地理分佈規劃基礎建設呢?
您是否需要透過單一網路為多個雲端環境建立大型叢集?
或者有很多小集群並找到一種方法來控制和同步它們?

一個領導集群

透過單一網路創建一個叢集並不是那麼容易。

想像一下,您發生了事故,集群段之間的連接丟失了。

如果您有一台主伺服器,一半的資源將無法接收新命令,因為它們將無法聯繫主伺服器。

同時你還有舊的路由表(kube-proxy 無法下載新的)且沒有額外的 pod(kubelet 無法要求更新)。

更糟的是,如果 Kubernetes 沒有看到某個節點,它會將其標記為孤立節點,並將遺失的 pod 分發到現有節點。

因此,您的 Pod 數量是原來的兩倍。

如果為每個區域製作一台主伺服器,etcd 資料庫中的共識演算法就會出現問題。 (約。 編輯。 — 事實上,etcd 資料庫不一定必須位於主伺服器上。 它可以在同一區域的一組單獨的伺服器上運行。 確實,同時獲得了集群的故障點。 但要快。)

etcd 用途 筏演算法在將值寫入磁碟之前協商該值。
也就是說,在將狀態寫入 etcd 之前,大多數實例必須達成共識。

如果etcd實例之間的延遲急劇增加,例如不同區域的三個etcd實例,則協商一個值並將其寫入磁碟需要很長時間。
這反映在 Kubernetes 控制器中。

控制器管理器需要更多時間來了解變更並將回應寫入資料庫。

由於控制器不是一個,而是多個, 連鎖反應的結果,整個集群開始工作非常緩慢.

etcd 對延遲非常敏感 官方文件建議使用SSD代替普通硬碟.

目前還沒有針對單一集群的大型網路的良好範例。

基本上,開發者社群和 SIG 叢集小組正在嘗試找出如何像 Kubernetes 編排容器一樣編排叢集。

選項 1:使用 kubefed 進行叢集聯合

SIG-cluster 的官方回應 - kubefed2,原始 kube federation 用戶端和營運商的新版本.

我們第一次嘗試使用 kube federation 工具將群集集合作為單一物件進行管理。

開始是好的,但最終 kube federation 從未流行起來,因為它不支援所有資源。

例如,它支援聯合交付和服務,但不支援 StatefulSet。
而且聯邦配置都是以註解的形式傳遞的,不夠彈性。

想像如何只使用註解來描述聯合中每個集群的副本分區。

真是一團糟。

SIG-cluster 在 kubefed v1 之後做了很多工作,並決定從不同的角度來處理這個問題。

他們決定發布安裝在叢集上的控制器,而不是註釋。 可以使用自訂資源定義 (CRD) 對其進行自訂。

對於將成為聯合一部分的每個資源,您都有一個包含三個部分的自訂 CRD 定義:

  • 資源的標準定義,例如部署;
  • 部分 placement,您可以在其中定義資源在聯合中的分配方式;
  • 部分 override,對於特定資源,您可以覆寫放置中的權重和參數。

以下是包含放置部分和覆蓋部分的組合交付的範例。

apiVersion: types.federation.k8s.io/v1alpha1
kind: FederatedDeployment
metadata:
  name: test-deployment
  namespace: test-namespace
spec:
  template:
    metadata:
      labels:
        app: nginx
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
            - image: nginx
              name: nginx
  placement:
    clusterNames:
      - cluster2
      - cluster1
  overrides:
    - clusterName: cluster2
      clusterOverrides:
        - path: spec.replicas
          value: 5

如您所見,供應分佈在兩個集群中: cluster1 и cluster2.

第一個叢集提供 5 個副本,第二個叢集設定為 XNUMX 個。

如果您需要對副本數量進行更多控制,kubefed2 提供了一個新的 ReplicaSchedulingPreference 對象,可以在其中對副本進行加權:

apiVersion: scheduling.federation.k8s.io/v1alpha1
kind: ReplicaSchedulingPreference
metadata:
  name: test-deployment
  namespace: test-ns
spec:
  targetKind: FederatedDeployment
  totalReplicas: 9
  clusters:
    A:
      weight: 1
    B:
      weight: 2

CRD 結構和 API 尚未完全準備好,官方專案儲存庫正在進行積極的工作。

密切關注 kubefed2,但請記住它尚不適合生產。

了解有關 kubefed2 的更多信息 關於 kubefed2 的官方文章 在有關 Kubernetes 的部落格中以及 kubefed 專案的官方儲存庫.

選項 2:以 Booking.com 風格組合集群

Booking.com 的開發人員並未開發 kubefed v2,但他們提出了 Shipper - 一個在多個集群、多個區域和多個雲中進行交付的運營商。

發貨人 有點類似 kubefed2。

這兩個工具都允許您自訂多叢集部署策略(使用哪些叢集以及它們擁有多少個副本)。

托運人的目標是降低交付過程中出現錯誤的風險。

在 Shipper 中,您可以定義一系列步驟來描述先前和目前部署之間的副本分割以及傳入流量。

當您將資源推送到叢集時,Shipper 控制器會在所有已加入的叢集中逐步推出該變更。

此外,托運人非常有限。

例如, 它接受舵圖作為輸入 並且不支援普通資源。
一般來說,Shipper 的工作方式是這樣的。

您需要建立一個包含 Helm 圖表的應用程式資源,而不是標準交付:

apiVersion: shipper.booking.com/v1alpha1
kind: Application
metadata:
  name: super-server
spec:
  revisionHistoryLimit: 3
  template:
    chart:
      name: nginx
      repoUrl: https://storage.googleapis.com/shipper-demo
      version: 0.0.1
    clusterRequirements:
      regions:
        - name: local
    strategy:
      steps:
        - capacity:
            contender: 1
            incumbent: 100
          name: staging
          traffic:
            contender: 0
            incumbent: 100
        - capacity:
            contender: 100
            incumbent: 0
          name: full on
          traffic:
            contender: 100
            incumbent: 0
    values:
      replicaCount: 3

Shipper 是管理多個叢集的好選擇,但它與 Helm 的密切關係只會造成阻礙。

如果我們都從 Helm 切換到 客製化卡皮坦?

了解有關 Shipper 及其理念的更多信息,請訪問 本官方新聞稿.

如果你想深入研究程式碼, 前往官方專案儲存庫.

選項 3:「神奇」叢集合併

Kubefed v2 和 Shipper 與叢集共同配合使用,透過自訂資源定義為叢集提供新資源。

但是如果您不想重寫所有交付、StatefulSet、DaemonSet 等來合併怎麼辦?

如何在不更改 YAML 的情況下將現有群集納入聯邦?

多集群調度器是一個 Admirality 項目,它處理叢集上的工作負載調度。

但多集群調度程序並沒有提出一種與集群交互並將資源包裝在自訂定義中的新方法,而是嵌入到標準 Kubernetes 生命週期中並攔截所有創建 Pod 的呼叫。

每個建立的 Pod 都會立即替換為虛擬 Pod。

多集群調度器的用途 用於存取修改的 webhook攔截呼叫並建立一個空閒的虛擬 Pod。

原始 Pod 經歷另一個規劃週期,在輪詢整個聯邦後,做出放置決定。

最後將Pod投遞到目標叢集。

結果,你有一個額外的 Pod,它什麼都不做,只是佔空間。

優點是您不必編寫新資源來組合供應。

建立 Pod 的每個資源都會自動準備好合併。

這很有趣,因為突然間你的物資分佈在多個地區,而你甚至沒有註意到。 然而,這是相當冒險的,因為這裡的一切都依賴魔法。

但是,雖然 Shipper 試圖在很大程度上減輕交付的影響,但多叢集調度程序可以處理更一般的任務,並且可能更適合批次作業。

它沒有先進的漸進交付機制。

有關多集群調度程序的更多信息,請訪問 官方儲存庫頁面.

如果您想了解實際的多集群調度程序,Admiralty 有 Argo 的有趣用例 — 工作流程、事件、CI 和 CD Kubernetes。

其他工具和解決方案

連接和管理多個叢集是一項複雜的任務,並且沒有通用的解決方案。

如果您想進一步探討這個主題,這裡有一些資源:

這就是今天的全部內容

感謝您閱讀到最後!

如果您知道如何更有效地連接多個集群, 告訴我們.

我們會將您的方法加入連結中。

特別感謝克里斯·內斯比特·史密斯(Chris Nesbitt-Smith)(克里斯·內斯比特-史密斯)和文森特·德·斯梅(文森特·德·斯梅特)(可靠性工程師 swatmobile.io)閱讀文章並分享有關聯盟如何運作的有用資訊。

來源: www.habr.com

添加評論