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

Kubernetes 1.5 中的叢集聯邦

編者按:這篇博文是關於 Kubernetes 1.5 新功能系列深度文章的一部分。

在最新的Kubernetes 1.5 釋出中,您會注意到叢集聯邦的支援正在日趨成熟。該功能在 Kubernetes 1.3 中引入,而 1.5 版本包含多項新功能,包括更簡單的設定體驗,以及向支援所有 Kubernetes API 物件邁進了一步。

引入了一個名為“kubefed”的新命令列工具,使叢集聯邦的入門變得更加簡單。此外,還添加了對聯邦 DaemonSets、Deployments 和 ConfigMaps 的 Alpha 級支援。總之

  • DaemonSets 是 Kubernetes 部署規則,它保證當新節點新增到叢集時,特定 Pod 始終存在於每個節點上(更多資訊)。
  • Deployments 描述了 Replica Sets 的所需狀態(更多資訊)。
  • ConfigMaps 是應用於 Replica Sets 的變數(這極大地提高了映象的可重用性,因為它們的引數可以外部化 - 更多資訊)。聯邦 DaemonSets聯邦 Deployments聯邦 ConfigMaps 將基本概念的質量提升到新的水平。例如,聯邦 DaemonSets 保證 Pod 部署在新新增叢集的每個節點上。

但是,“聯邦”究竟是什麼?我們透過它滿足的需求來解釋。想象一個在全球範圍內執行的服務。自然,它的所有使用者都希望獲得相同的服務質量,無論他們位於亞洲、歐洲還是美國。這意味著服務必須對每個位置的請求做出同樣快速的響應。這聽起來很簡單,但幕後涉及大量的邏輯。這就是 Kubernetes 叢集聯邦的目標。

它是如何工作的?其中一個 Kubernetes 叢集必須透過執行聯邦控制平面成為主叢集。實際上,這是一個控制器,它監控其他叢集的健康狀況,並提供一個統一的管理入口點。該入口點行為類似於典型的 Kubernetes 叢集。它允許建立Replica SetsDeploymentsServices,但聯邦控制平面將資源傳遞給底層叢集。這意味著如果我們請求聯邦控制平面建立一個包含 1,000 個副本的 Replica Set,它會將請求分散到所有底層叢集。如果我們有 5 個叢集,那麼預設情況下每個叢集將獲得 200 個副本。

這本身就是一個強大的機制。但還有更多。還可以建立聯邦 Ingress。實際上,這是一個全域性應用層負載均衡器。由於對應用層的理解,它允許負載均衡“更智慧”——例如,透過考慮客戶端和伺服器的地理位置,並以最佳方式在它們之間路由流量。

總而言之,透過 Kubernetes 叢集聯邦,我們可以方便地管理所有叢集(單一訪問點),還可以最佳化全球內容交付。在下面的章節中,我們將展示它是如何工作的。

建立聯邦平面

在此練習中,我們將聯邦一些叢集。為方便起見,所有命令已分組到此處提供的 6 個指令碼中

  • 0-settings.sh
  • 1-create.sh
  • 2-getcredentials.sh
  • 3-initfed.sh
  • 4-joinfed.sh
  • 5-destroy.sh 首先我們需要定義幾個變數(0-settings.sh)
$ cat 0-settings.sh && . 0-settings.sh

# this project create 3 clusters in 3 zones. FED\_HOST\_CLUSTER points to the one, which will be used to deploy federation control plane

export FED\_HOST\_CLUSTER=us-east1-b


# Google Cloud project name

export FED\_PROJECT=\<YOUR PROJECT e.g. company-project\>


# DNS suffix for this federation. Federated Service DNS names are published with this suffix. This must be a real domain name that you control and is programmable by one of the DNS providers (Google Cloud DNS or AWS Route53)

export FED\_DNS\_ZONE=\<YOUR DNS SUFFIX e.g. example.com\>

並獲取 kubectl 和 kubefed 二進位制檔案。(有關安裝說明,請參閱此處此處的指南)。
現在設定已準備好使用 gcloud container clusters create (1-create.sh) 建立一些 Google Container Engine (GKE) 叢集。在此示例中,一個在美國,一個在歐洲,一個在亞洲。

$ cat 1-create.sh && . 1-create.sh

gcloud container clusters create gce-us-east1-b --project=${FED\_PROJECT} --zone=us-east1-b --scopes cloud-platform,storage-ro,logging-write,monitoring-write,service-control,service-management,https://www.googleapis.com/auth/ndev.clouddns.readwrite


gcloud container clusters create gce-europe-west1-b --project=${FED\_PROJECT} --zone=europe-west1-b --scopes cloud-platform,storage-ro,logging-write,monitoring-write,service-control,service-management,https://www.googleapis.com/auth/ndev.clouddns.readwrite


gcloud container clusters create gce-asia-east1-a --project=${FED\_PROJECT} --zone=asia-east1-a --scopes cloud-platform,storage-ro,logging-write,monitoring-write,service-control,service-management,https://www.googleapis.com/auth/ndev.clouddns.readwrite

下一步是使用 gcloud -q container clusters get-credentials (2-getcredentials.sh) 獲取 kubectl 配置。這些配置將用於指示 kubectl 命令的當前上下文。

$ cat 2-getcredentials.sh && . 2-getcredentials.sh

gcloud -q container clusters get-credentials gce-us-east1-b --zone=us-east1-b --project=${FED\_PROJECT}


gcloud -q container clusters get-credentials gce-europe-west1-b --zone=europe-west1-b --project=${FED\_PROJECT}


gcloud -q container clusters get-credentials gce-asia-east1-a --zone=asia-east1-a --project=${FED\_PROJECT}

讓我們驗證一下設定

$ kubectl config get-contexts

CURRENT   NAME CLUSTER  AUTHINFO  NAMESPACE

\*         

gke\_container-solutions\_europe-west1-b\_gce-europe-west1-b

gke\_container-solutions\_europe-west1-b\_gce-europe-west1-b   

gke\_container-solutions\_europe-west1-b\_gce-europe-west1-b      

gke\_container-solutions\_us-east1-b\_gce-us-east1-b

gke\_container-solutions\_us-east1-b\_gce-us-east1-b           

gke\_container-solutions\_us-east1-b\_gce-us-east1-b

gke\_container-solutions\_asia-east1-a\_gce-asia-east1-a

gke\_container-solutions\_asia-east1-a\_gce-asia-east1-a  

gke\_container-solutions\_asia-east1-a\_gce-asia-east1-a

我們有 3 個叢集。其中一個,由 FED_HOST_CLUSTER 環境變數指示,將用於執行聯邦平面。為此,我們將使用 kubefed init federation 命令(3-initfed.sh)。

$ cat 3-initfed.sh && . 3-initfed.sh

kubefed init federation --host-cluster-context=gke\_${FED\_PROJECT}\_${FED\_HOST\_CLUSTER}\_gce-${FED\_HOST\_CLUSTER} --dns-zone-name=${FED\_DNS\_ZONE}

您會注意到,執行上述命令後,出現了一個新的 kubectl 上下文

$ kubectl config get-contexts

CURRENT   NAME  CLUSTER  AUTHINFO NAMESPACE

...         

federation

federation

聯邦上下文將成為我們的管理入口點。現在是時候加入叢集了(4-joinfed.sh)

$ cat 4-joinfed.sh && . 4-joinfed.sh

kubefed --context=federation join cluster-europe-west1-b --cluster-context=gke\_${FED\_PROJECT}\_europe-west1-b\_gce-europe-west1-b --host-cluster-context=gke\_${FED\_PROJECT}\_${FED\_HOST\_CLUSTER}\_gce-${FED\_HOST\_CLUSTER}


kubefed --context=federation join cluster-asia-east1-a --cluster-context=gke\_${FED\_PROJECT}\_asia-east1-a\_gce-asia-east1-a --host-cluster-context=gke\_${FED\_PROJECT}\_${FED\_HOST\_CLUSTER}\_gce-${FED\_HOST\_CLUSTER}


kubefed --context=federation join cluster-us-east1-b --cluster-context=gke\_${FED\_PROJECT}\_us-east1-b\_gce-us-east1-b --host-cluster-context=gke\_${FED\_PROJECT}\_${FED\_HOST\_CLUSTER}\_gce-${FED\_HOST\_CLUSTER}

請注意,這裡使用叢集 gce-us-east1-b 來執行聯邦控制平面,並作為工作叢集。這種迴圈依賴有助於更有效地利用資源,可以透過使用 kubectl --context=federation get clusters 命令進行驗證

$ kubectl --context=federation get clusters

NAME                        STATUS    AGE

cluster-asia-east1-a        Ready     7s

cluster-europe-west1-b      Ready     10s

cluster-us-east1-b          Ready     10s

我們準備就緒。

使用聯邦執行應用程式

在我們的儲存庫中,您將找到如何構建一個帶有顯示容器主機名和 Google Cloud Platform (GCP) 區域的 Web 服務的 Docker 映象的說明。

一個示例輸出可能如下所示

{"hostname":"k8shserver-6we2u","zone":"europe-west1-b"}

現在我們將部署 Replica Set (k8shserver.yaml)

$ kubectl --context=federation create -f rs/k8shserver

以及聯邦 Service (k8shserver.yaml)

$ kubectl --context=federation create -f service/k8shserver

如您所見,這兩個命令引用了“federation”上下文,即聯邦控制平面。幾分鐘後,您會發現底層叢集執行著 Replica Set 和 Service。

建立 Ingress

Service 準備好後,我們可以建立 Ingress - 全域性負載均衡器。命令如下

kubectl --context=federation create -f ingress/k8shserver.yaml

檔案的內容指向我們在上一步中建立的服務

apiVersion: extensions/v1beta1

kind: Ingress

metadata:

  name: k8shserver

spec:

  backend:

    serviceName: k8shserver

    servicePort: 80

幾分鐘後,我們應該得到一個全球 IP 地址

$ kubectl --context=federation get ingress

NAME         HOSTS     ADDRESS          PORTS     AGE

k8shserver   \*         130.211.40.125   80        20m

實際上,以下請求的響應

$ curl 130.211.40.125

取決於客戶端的位置。在美國可能會看到類似這樣的內容

{"hostname":"k8shserver-w56n4","zone":"us-east1-b"}

而在歐洲,我們可能會看到

{"hostname":"k8shserver-z31p1","zone":"eu-west1-b"}

有關我們所描述的一切工作原理的更多詳細資訊,請參閱此問題

演示

總結

叢集聯邦仍在積極開發中,尚未完全普遍可用。一些 API 處於 Beta 階段,另一些處於 Alpha 階段。一些功能缺失,例如不支援跨雲負載均衡(聯邦 Ingress 目前僅在 Google Cloud Platform 上執行,因為它依賴於 GCP HTTP(S) 負載均衡)。

然而,隨著功能的成熟,它將成為所有瞄準全球市場,但目前無法承擔 Netflix 或 Amazon 等公司使用的複雜管理技術的企業的推動者。這就是我們密切關注這項技術,並希望它能儘快實現其承諾的原因。

PS. 完成後,請記住銷燬您的叢集

$ . 5-destroy.sh