Kubernetes 1.5 新功能解析之「集群联盟」

编者注:
这篇帖子来源于 Kubernetes 官方文档,是「深度探讨 Kubernetes 1.5 系列」之中的一篇,深度阐述集群联盟。

最近,Kubernetes 1.5 发布,不难发现,它对于集群联盟的支持正趋于成熟。集群联盟功能是在 Kubernetes1.3 的时候引入的。1.5 版本不仅包含了很多新功能,而且更容易设置,目测不久之后就可以支持所有的 Kubernetes API 对象了。

1.5 版本此次还引入了‘kubefed’命令行工具,用于简化集群开启步骤。同样,该功能处于 Alpha 阶段,用于 Federated DaemonSets,Deployments 和 ConfigMaps。总结如下:

DaemonSets——它是 Kubernetes 的部署规则,确保在新的节点被添加到集群的时候,已给的 Pod 可以呈现在任意节点上。(更多信息链接:http://kubernetes.io/docs/admin/daemons/ )
Deployments——描述了 Replica Sets 的理想状态。(更多信息链接:http://kubernetes.io/docs/user-guide/deployments/ )
ConfigMaps——它是应用于 Replica Sets 的变量,当镜像参数被外化的时候,它很大程度上提升了镜像的可重复使用率。(更多信息链接:http://kubernetes.io/docs/user-guide/configmap/ )

Federated DaemonSets,Federated Deployments,Federated ConfigMaps 是下一阶段的核心概念。比如,Federated DaemonSets 确保 pod 部署在新添加集群的每个节点上。
说到这里,到底什么是“federation”?让我们来解释一下。假设现在有一个 service 全球都在用。当然,无论用户是在亚洲、欧洲还是在美国,所有的用户都希望获得相同数量的 service。也就是说,无论在哪里落地,用户们都希望 service 的回应速度跟需求速度能够对等。虽然这听起来非常简单,但是要实现这样的场景,需要不少精力。

这就是 Kubernetes 集群需要去做的事情。

那么,它是如何运作的呢?通过运行 Federation 控制面板,Kubernetes 众多集群中,其中一个必定会变成 master。就实践上来说,这就是一个管理集群健康的 controller,并且为管理提供单一入口点。入口点的功能有点像 Kubernetes 集群,能够创建 Replica Sets,Deployments,Service,但是 Federated 控制面板通过资源到达底层集群。也就是说,如果我们要求 federation 控制面板用 1000 个 replicas 来创建 Replica Set,它就会传播请求到所有集群;如果我们有 5 个集群,那么默认设置下,每个集群都会分享到 200 个 replica 中。

这对于 Kubernetes 本身来说就是一个很强大的机制。但是,这个功能还远远不止于此。这个功能用于创建 Federated Ingress 也是可能的。实际上,这是一个全球应用程序层面的负载均衡器。得益于对应用程序层面的了解,它使得负载均衡器更加“智能化”——比如,将客户端和服务器的地址位置也纳入考虑因素,并且对他们之间的流量用最佳方法进行引导。
总而言之,Kubernetes 集群联盟可以促进对集群(单个访问点)的管理,但是同时也会对全球内容交付进行优化。接下来,我们会展示具体运作细节。

创建 Federation 面板

在以下实践中,我们会将一些集群结成联盟。方便起见,所有的命令会被分成 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 变量。(参考指令:http://kubernetes.io/docs/user-guide/prereqs/)

现在,设置已经 OK,接下来就使用 gcloudcontainer cluster create(1-create.sh)创建新的谷歌 GCE 集群。在这个例子里面,一个是在美国,一个是在欧洲,另外一个是在亚洲。

$ 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 containercluster 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 指示环境变量,被用于运行federated面板。对于这点,我们会使用 kubefed init federated 命令(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 被用于运行 federation 控制面板,并且也被用作 worker 集群。循环依赖可以更加高效地使用资源,它可以通过使用 kubectl –context=federationget 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

使用 Federation 运行应用程序

在我们的 repository 中,你会知道如何使用网页服务来创建 Docker 镜像,这个网页服务展示了容器的 hostname 以及谷歌 GCP 地带。

展示一个输出的例子:

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

现在我们要开始部署 Replica Set(地址:https://github.com/ContainerSolutions/k8shserver/blob/master/rs/k8shserver.yaml)

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

以及 Federated Service(地址:https://github.com/ContainerSolutions/k8shserver/blob/master/services/k8shserver.yaml)

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

正如你所看到的,两个命令行指向“federation”内容,也就是指向 federation 控制面板。几分钟后,你就会发现,以下集群在运行 Replica Set 和 Service 了。

创建 Ingress

在 Service 准备就绪之后,我们创建了 Ingress——全局负载均衡器。命令行如下所示:

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

文件内容指向我们在之前步骤中创建的 service:

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"}

除了上述我们描述过的东西,额外的细节可以参考这个链接:https://github.com/kubernetes/kubernetes/issues/39087

Demo:

总结

集群联盟已经被用户投入使用,但是还不通用。一些 API 还在 beta 测试阶段,其余的也还都在 alpha 测试阶段。有些功能丢失了,比如它就不支持跨云负载均衡(federated ingress 目前只在谷歌 GCP 平台上运行,因为它依赖于 GCP HTTP(S)负载均衡,网址链接:https://cloud.google.com/compute/docs/load-balancing/http/)。

然而,随着功能的成熟,对于所有意在全球市场的公司来说,该功能会变成一个促成者,但是目前就 Netflix 或者 Amazon 使用来看,这个功能还无法支持复杂的管理技术。这也就是为什么我们近观这项技术,会希望它能够按照期望的方向来发展,越做越好!

PS,部署结束的时候,记得删掉你的集群:

$ . 5-destroy.sh

原文:http://blog.kubernetes.io/2016/12/cluster-federation-in-kubernetes-1.5.html