實現Kubernetes跨叢集服務應用的高可用
我們在進行生產環境部署時得到的一個明確的需求,是Kubernetes使用者希望服務部署能夠zone、跨區域、跨叢集甚至跨雲邊界(譯者:如跨雲供應商)。相比單叢集多zone部署,跨叢集服務提供按地域分佈,支援混合雲、多雲場景,提升高可用等級。客戶希望服務能夠跨一到多個叢集(可能是本地或者遠端叢集),並希望這些叢集無論內部或外部都有一致穩定的連線。 |
在Kubernetes 1.3版本,我們希望降低跨叢集跨地區服務部署相關的管理和運營難度。本文介紹如何實現此目標。
注意:雖然本文示例使用谷歌容器引擎(GKE)來提供Kubernetes叢集,您可以在任何的其他環境部署Kubernetes。
我們正式開始。第一步是在谷歌的四個雲平臺地區通過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的示例進行這步配置。
從聯邦API獲取資訊,因此您可以通過聯邦API制定服務屬性。
當服務建立後,聯邦服務自動進行如下操作:
在聯邦中註冊的所有Kubernetes叢集中建立服務;
監控服務碎片(以及它們所在叢集)的健康狀況;
在公NS提供商上面建立 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。目前需要通過直接操作底層叢集的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
一旦Pod開始成功啟動並開始監聽連線,每個叢集(通過健康檢查)會彙報服務的健康終端至叢集聯邦。叢集聯邦會依次認為這些服務碎片是健康的,並且建立相應的公NS記錄。你可以使用你喜歡的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記錄。
預設情況下,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。
標準Kubernetes服務叢集IP已經確保無響應的Pod會被及時從服務中移除。Kubernetes聯邦叢集系統自動監控叢集以及聯邦服務所有碎片對應的終端的健康狀況,並按需增加和刪除服務碎片。
因為DNS快取造成的延遲(快取超時,或者聯邦服務DNS記錄TTL預設設定為三分鐘,但可以調節) 可能需要這麼長時間才能在某叢集或服務碎片出現問題時,正確將客戶端,請求failover到可用叢集上。然而,因為每個服務終端可以返回多個ip地址,(如上面的us-central1,有三個選擇)很多客戶端會返回其中一個可選地址。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31559985/viewspace-2641380/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- WEB叢集- 高可用服務Web
- 搭建 Kubernetes 高可用叢集
- Kubernetes實戰:高可用叢集的搭建和部署
- 使用Kubeadm搭建高可用Kubernetes叢集
- 搭建高可用kubernetes叢集(keepalived+haproxy)
- Kubernetes-高可用叢集證書更新
- 部署Kubernetes v1.22.10高可用叢集
- 構建生產環境可用的高可用kubernetes叢集
- Keepalived實現服務高可用
- Kubernetes部署叢集Mysql服務MySql
- 11、redis使用ruby實現叢集高可用Redis
- 手動搭建高可用的 kubernetes 叢集(v1.31)
- Eureka高可用叢集服務端和客戶端配置服務端客戶端
- Kubernetes — 在 OpenStack 上使用 kubeadm 部署高可用叢集
- 用kubeadm建立高可用kubernetes叢集后,如何重新新增控制平面
- Spring Cloud:使用Eureka叢集搭建高可用服務註冊中心SpringCloud
- 教你如何用Keepalived和HAproxy配置高可用 Kubernetes 叢集
- PostgreSQL repmgr高可用叢集+keepalived高可用SQL
- 構建MHA實現MySQL高可用叢集架構MySql架構
- (13) SpringCloud-使用Eureka叢集搭建實現高可用SpringGCCloud
- (15) SpringCloud-使用Eureka叢集搭建實現高可用SpringGCCloud
- LVS+Keepalive 實現負載均衡高可用叢集負載
- 在大規模 Kubernetes 叢集上實現高 SLO 的方法
- 高可用服務之Keepalived利用指令碼實現服務的可用性檢測指令碼
- 分散式服務高可用實現:複製分散式
- zookeeper 高可用叢集搭建
- MongoDB高可用叢集搭建MongoDB
- Redis叢集與高可用Redis
- PostgreSQL patroni高可用叢集SQL
- Kubernetes 高可用叢集落地二三事
- 使用kubeadm安裝kubernetes 1.13高可用叢集(使用calico網路)
- 使用Karmada實現Helm應用的跨叢集部署
- 詳解Redis三大叢集模式,輕鬆實現高可用!Redis模式
- RabbitMQ從零到叢集高可用(.NetCore5.0) -高可用叢集構建落地MQNetCore
- 阿里雲應用高可用服務公測釋出阿里
- [雲原生微服務架構](十一) Kubernetes高可用叢集二進位制部署(Runtime Containerd)微服務架構AI
- 高可用mongodb叢集(分片+副本)MongoDB
- 10、redis哨兵叢集高可用Redis