跨集群服務——實現 Kubernetes 應用的高可用

wx67w2g4 8年前發布 | 9K 次閱讀 Nginx Kubernetes

本文主要介紹跨集群服務的創建和和使用,該功能是集群聯邦在Kubernetes 1.3版本的核心功能。

我們在進行生產環境部署時得到的一個明確的需求,是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制定服務屬性。

當服務創建后,聯邦服務自動進行如下操作:

  1. 在聯邦中注冊的所有Kubernetes集群中創建服務;

  2. 監控服務碎片(以及它們所在集群)的健康狀況;

  3. 在公共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 <a dir="ltr" href="tel:21600%203600" x-apple-data-detectors="true" x-apple-data-detectors-type="telephone" x-apple-data-detectors-result="17">21600 3600</a> 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,有三個選擇)很多客戶端會返回其中一個可選地址。

 

 

 

 

 

 

來自:https://mp.weixin.qq.com/s?__biz=MzA5OTAyNzQ2OA==&mid=2649691715&idx=2&sn=c438c94a6e208601d183e71f43f0594a&chksm=88932920bfe4a036b11e3f0753f0b65f8a97bbc71715eee98efcdbdee95187701c1f61449e63&scene=1&srcid=0923h2qx60jMUSxunzUSXKZw&pass_ticket=By%2Bxg1gk8ONkmOogV3byQCPfHgETqHr3gZRt9JjtYN0%3D#rd

 

 本文由用戶 wx67w2g4 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!