咱们在进行生产环境部署时获得的一个明确的需求,是Kubernetes用户但愿服务部署可以zone、跨区域、跨集群甚至跨云边界(译者:如跨云供应商)。相比单集群多zone部署,跨集群服务提供按地域分布,支持混合云、多云场景,提高高可用等级。客户但愿服务可以跨一到多个集群(多是本地或者远程集群),并但愿这些集群不管内部或外部都有一致稳定的链接。 |
在Kubernetes 1.3版本,咱们但愿下降跨集群跨地区服务部署相关的管理和运营难度。本文介绍如何实现此目标。linux
注意:虽然本文示例使用谷歌容器引擎(GKE)来提供Kubernetes集群,您能够在任何的其余环境部署Kubernetes。nginx
咱们正式开始。第一步是在谷歌的四个云平台地区经过GKE建立Kubernetes集群。缓存
asia-east1-b europe-west1-b us-east1-b us-central1-b
咱们经过下面的命令建立集群:服务器
gcloud container clusters create gce-asia-east1 \ --scopes cloud-platform \ --zone asia-east1-b gcloud container clusters create gce-europe-west1 \ --scopes cloud-platform \ --zone=europe-west1-b gcloud container clusters create gce-us-east1 \ --scopes cloud-platform \ --zone=us-east1-b gcloud container clusters create gce-us-central1 \ --scopes cloud-platform \ --zone=us-central1-b
验证建立的集群网络
gcloud container clusters list NAME ZONE MASTER_VERSION MASTER_IP NUM_NODES STATUS gce-asia-east1 asia-east1-b 1.2.4 104.XXX.XXX.XXX 3 RUNNING gce-europe-west1 europe-west1-b 1.2.4 130.XXX.XX.XX 3 RUNNING gce-us-central1 us-central1-b 1.2.4 104.XXX.XXX.XX 3 RUNNING gce-us-east1 us-east1-b 1.2.4 104.XXX.XX.XXX 3 RUNNING
下一步是起动集群并在建立的其中一个集群中部署联邦控制模块(Control Plane)。您能够参考和依照Kelsey Hightower的示例进行这步配置。dom
联邦服务工具
从联邦API获取信息,所以您能够经过联邦API制定服务属性。google
当服务建立后,联邦服务自动进行以下操做:spa
在联邦中注册的全部Kubernetes集群中建立服务;3d
监控服务碎片(以及它们所在集群)的健康情况;
在公共DNS提供商上面建立 DNS记录(如谷歌Cloud DNS,或者AWS Route 53),以此肯定你的服务客户端可以在任什么时候候无缝的得到相关的健康服务终端,即便当集群,可用区或者地区出现服务中断的状况时。
在注册到联邦的Kubernetes集群中的服务客户端,当联邦服务在本地集群碎片工做正常时,会优先使用本地服务碎片,不然会在最近的其余集群中选取健康的服务碎片。
Kubernetes集群联邦可以联合不一样的云供应商(好比GCP、AWS)以及私有云(如OpenStack)。您只需在相应的云供应商和位置建立您的集群,而且将每一个集群的API Server地址和证书信息注册到联邦集群中。
在咱们的示例中,咱们在四个区域建立了集群,而且在其中的一个集群中部署了联邦控制模块,咱们会用这个环境来部署咱们的服务。具体请参考下图。
建立联邦服务
咱们先查看联邦中全部注册好的集群:
kubectl --context=federation-cluster get clusters NAME STATUS VERSION AGE gce-asia-east1 Ready 1m gce-europe-west1 Ready 57s gce-us-central1 Ready 47s gce-us-east1 Ready 34s
建立联邦服务:
kubectl --context=federation-cluster create -f services/nginx.yaml --context=federation-cluster参数通知kubectl把带相关证书信息的请求提交至联邦API服务器。联邦服务会自动在联邦中全部集群建立相应的Kubernetes服务。
你能够经过检查每个集群中的服务进行验证,好比:
kubectl --context=gce-asia-east1a get svc nginx NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx 10.63.250.98 104.199.136.89 80/TCP 9m
上面的命令假设你有一个名为gce-asia-east1a的kubectl的上下文设置,而且你有集群部署在这个区(zone)。Kubernetes服务的名字和名空间自动与你上面建立的集群服务一致。
联邦服务状态会实时体现Kubernetes对应的服务状态,例如:
kubectl --context=federation-cluster describe services nginx Name: nginx Namespace: default Labels: run=nginx Selector: run=nginx Type: LoadBalancer IP: LoadBalancer Ingress: 104.XXX.XX.XXX, 104.XXX.XX.XXX, 104.XXX.XX.XXX, 104.XXX.XXX.XX Port: http 80/TCP Endpoints: <none> Session Affinity: None No events.
联邦服务的LoadBalancer Ingress地址会汇总全部注册的Kubernetes集群服务的LoadBalancer Ingress地址。为了让同一联邦服务在不通集群之间以及不一样云供应商之间的网络正确工做,你的服务须要有外部可见的IP地址,好比Loadbalancer是常见的服务类型。
请注意咱们尚未部署任何后台Pod来接收指向这些地址的网络流量(好比服务终端),因此此时联邦服务还不会认为这些服务碎片是健康的,因此联邦服务对应的DNS记录也还没有建立。
增长后台Pod
为了渲染底层服务碎片的健康情况,咱们须要为服务增长后台Pod。目前须要经过直接操做底层集群的API Server来完成(为节省您的时间,将来咱们能够经过一条命令在联邦服务器中建立)。例如咱们在底层集群中建立后台Pod:
for CLUSTER in asia-east1-a europe-west1-a us-east1-a us-central1-a do kubectl --context=$CLUSTER run nginx --image=nginx:1.11.1-alpine --port=80 done
验证公共DNS记录
一旦Pod开始成功启动并开始监听链接,每一个集群(经过健康检查)会汇报服务的健康终端至集群联邦。集群联邦会依次认为这些服务碎片是健康的,而且建立相应的公共DNS记录。你可使用你喜欢的DNS供应商的接口来验证。好比,若是你使用谷歌Cloud DNS配置联邦, 你的DNS域为 ‘example.com’:
$ gcloud dns managed-zones describe example-dot-com creationTime: '2016-06-26T18:18:39.229Z' description: Example domain for Kubernetes Cluster Federation dnsName: example.com. id: '3229332181334243121' kind: dns#managedZone name: example-dot-com nameServers: - ns-cloud-a1.googledomains.com. - ns-cloud-a2.googledomains.com. - ns-cloud-a3.googledomains.com. - ns-cloud-a4.googledomains.com. $ gcloud dns record-sets list --zone example-dot-com NAME TYPE TTL DATA example.com. NS 21600 ns-cloud-e1.googledomains.com., ns-cloud-e2.googledomains.com. example.com. SOA 21600 ns-cloud-e1.googledomains.com. cloud-dns-hostmaster.google.com. 1 21600 3600 1209600 300 nginx.mynamespace.myfederation.svc.example.com. A 180 104.XXX.XXX.XXX, 130.XXX.XX.XXX, 104.XXX.XX.XXX, 104.XXX.XXX.XX nginx.mynamespace.myfederation.svc.us-central1-a.example.com. A 180 104.XXX.XXX.XXX nginx.mynamespace.myfederation.svc.us-central1.example.com. nginx.mynamespace.myfederation.svc.us-central1.example.com. A 180 104.XXX.XXX.XXX, 104.XXX.XXX.XXX, 104.XXX.XXX.XXX nginx.mynamespace.myfederation.svc.asia-east1-a.example.com. A 180 130.XXX.XX.XXX nginx.mynamespace.myfederation.svc.asia-east1.example.com. nginx.mynamespace.myfederation.svc.asia-east1.example.com. A 180 130.XXX.XX.XXX, 130.XXX.XX.XXX nginx.mynamespace.myfederation.svc.europe-west1.example.com. CNAME 180 nginx.mynamespace.myfederation.svc.example.com. ... etc.
注意:若是您使用AWS Route53来配置联邦,你可使用相应的AWS工具,例如:
$aws route53 list-hosted-zones $aws route53 list-resource-record-sets --hosted-zone-id Z3ECL0L9QLOVBX
无论您使用什么DNS供应商, 您可使用DNS查询工具(例如 ‘dig’ 或者 ‘nslookup’)来查看联邦为您建立的DNS记录。
从联邦集群内部的pod发现联邦服务
默认状况下,Kubernetes集群有内置的本地域名服务器(KubeDNS),而且有智能的DNS搜索路径确保针对“myservice”、“myservice.mynamespace”、”bobsservice.othernamespace”等等被您运行在Pod中的的应用软件自动扩展和解析至相应的本地集群中的服务IP。
经过引入联邦服务以及跨集群服务发现,这个概念被扩展至全局,覆盖您联邦中全部的集群。为了利用这个扩展带来的便利性,您只需使用稍微不一样的服务名(好比,myservice.mynamespace.myfederation)进行解析。
使用不一样的DNS名同时避免了您现有的服务在您没有作明确的配置和选择状况下,意外的被解析到不一样区(zone)或地域(region)网络,致使额外的网络费用或延迟。
所以,使用咱们上面的NGINX 服务,以及刚刚介绍的联邦服务DNS名,咱们构想一个示例:在可用性区域us-central1-a的集群中的pod须要访问咱们的NGINX服务。与其使用传统的本地集群DNS名 (“nginx.mynamespace”,自动扩展为“nginx.mynamespace.svc.cluster.local”),如今可使用联邦服务名“nginx.mynamespace.myfederation”。此名称会被自动扩展和解析至个人Nginx服务最近的健康节点,不管它在世界的哪里。若是本地集群存在健康服务碎片,那么本地集群IP地址(一般是10.x.y.z)会被返回(被集群本地KubeDNS)。这与非联邦服务解析彻底一致。
若是服务在本地集群不存在(或者服务存在但本地没有健康的后台pod),DNS查询会自动扩充至`”nginx.mynamespace.myfederation.svc.us-central1-a.example.com”。实际的行为是查找离当前可用性区域最近的服务碎片的外部IP。该扩展被KubeDNS自动触发执行,返回相关的CNAME记录。这会遍历上面示例中的DNS记录,直到找到本地us-central1 区域联邦服务的外部IP。
经过明确指定DNS名,直接指向非本地可用区域(AZ)和地域(region)的服务碎片,而不依赖于自动DNS扩展,是可行的。例如,
“nginx.mynamespace.myfederation.svc.europe-west1.example.com” 会被解析至位于欧洲的全部健康服务碎片,即便经过nslookup解析出的服务位于美国,并没有论在美国是否有该服务的健康碎片。这对远程监控和其它相似应用颇有用。
从联邦集群外部发现联邦服务
对于外部客户端,前文描述的DNS自动扩展已不适用。外部客户端须要指定联邦服务的全名(FQDN),能够是区域,地域或全局名。为方便起见,最好为您的服务手工建立CNAME记录,好比:
eu.nginx.acme.com CNAME nginx.mynamespace.myfederation.svc.europe-west1.example.com. us.nginx.acme.com CNAME nginx.mynamespace.myfederation.svc.us-central1.example.com. nginx.acme.com CNAME nginx.mynamespace.myfederation.svc.example.com.
这样您的客户端能够一直使用左侧的短名形式,而且会被自动解析到它所在大陆的最近的健康节点上。集群联邦会帮您处理服务的failover。
处理后台Pod和整个集群的失败状况
标准Kubernetes服务集群IP已经确保无响应的Pod会被及时从服务中移除。Kubernetes联邦集群系统自动监控集群以及联邦服务全部碎片对应的终端的健康情况,并按需增长和删除服务碎片。
由于DNS缓存形成的延迟(缓存超时,或者联邦服务DNS记录TTL默认设置为三分钟,但能够调节) 可能须要这么长时间才能在某集群或服务碎片出现问题时,正确将客户端,请求failover到可用集群上。然而,由于每一个服务终端能够返回多个ip地址,(如上面的us-central1,有三个选择)不少客户端会返回其中一个可选地址。