咱們在進行生產環境部署時獲得的一個明確的需求,是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,有三個選擇)不少客戶端會返回其中一個可選地址。