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

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

我們準備就緒。

使用聯邦來執行應用程式

在我們的儲存庫中,您會找到關於如何建構 Docker 映像檔的說明,該映像檔包含一個顯示容器主機名稱和 Google Cloud Platform (GCP) 區域的 Web 服務。

範例輸出可能如下所示

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

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

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

和聯邦服務 (k8shserver.yaml)

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

如您所見,這兩個命令都參照「聯邦」環境,即聯邦控制平面。 幾分鐘後,您將意識到底層叢集正在執行 Replica Set 和服務。

建立 Ingress

在服務就緒後,我們可以建立 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 階段,而其他 API 則處於 Alpha 階段。 缺少某些功能,例如不支援跨雲端負載平衡(聯邦 Ingress 目前僅適用於 Google Cloud Platform,因為它取決於 GCP HTTP(S) 負載平衡)。

儘管如此,隨著功能的成熟,它將成為所有以全球市場為目標的公司的推動者,但目前這些公司無法負擔 Netflix 或 Amazon 等公司使用的複雜管理技術。 這就是為什麼我們密切關注這項技術,希望它很快就能實現其承諾。

附註:完成後,請記得摧毀您的叢集

$ . 5-destroy.sh