本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。

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