基于ACK One MSE多集群網(wǎng)關(guān)實(shí)現(xiàn)同城容災(zāi)
多集群網(wǎng)關(guān)(Multi-cluster Gateways)是ACK One為多云、多集群環(huán)境提供的云原生網(wǎng)關(guān),通過(guò)托管MSE Ingress并使用Ingress API以管理七層南北向流量。多集群網(wǎng)關(guān)支持同城自動(dòng)容災(zāi)和基于Header的灰度發(fā)布,可以幫您簡(jiǎn)化多集群應(yīng)用的運(yùn)維和節(jié)省成本,結(jié)合ACK One GitOps的能力,您可以快速構(gòu)建同城多活或主備容災(zāi)系統(tǒng)(不包含數(shù)據(jù)容災(zāi))。
容災(zāi)概述
目前云上容災(zāi)主要分為以下三類:
同城跨AZ容災(zāi)
同城容災(zāi)包含多活容災(zāi)和主備容災(zāi),同城中心之間物理距離較近,網(wǎng)絡(luò)延遲低,可防范AZ級(jí)別性質(zhì)的災(zāi)難損害,例如火災(zāi)、斷網(wǎng)或斷電等。
跨地域多活容災(zāi)
跨地域多活容災(zāi)對(duì)于網(wǎng)絡(luò)延遲相對(duì)較高,但可以防范地域性質(zhì)的災(zāi)難損害,例如地震、水災(zāi)等。
兩地三中心
兩地三中心將同城雙中心和跨地域?yàn)?zāi)備結(jié)合起來(lái),兼具兩者的優(yōu)點(diǎn),適用于對(duì)應(yīng)用與數(shù)據(jù)連續(xù)性和可用性要求高的場(chǎng)景。
而從實(shí)際情況考慮,同城容災(zāi)相比于跨地域容災(zāi),在數(shù)據(jù)容災(zāi)方面更容易實(shí)現(xiàn),所以同城容災(zāi)仍然具有非常重要的意義。
功能優(yōu)勢(shì)
基于多集群網(wǎng)關(guān)的容災(zāi)方案與基于DNS流量分發(fā)的容災(zāi)方案對(duì)比優(yōu)勢(shì)如下:
基于DNS流量分發(fā)的容災(zāi)方案需要多個(gè)LB IP(每個(gè)集群1個(gè)),而基于多集群網(wǎng)關(guān)的容災(zāi)方案在地域級(jí)別僅需要1個(gè)LB IP,且默認(rèn)提供同地域多可用區(qū)的高可用性。
基于多集群網(wǎng)關(guān)的容災(zāi)支持七層路由轉(zhuǎn)發(fā)能力,而基于DNS流量分發(fā)的容災(zāi)不支持七層路由轉(zhuǎn)發(fā)。
基于DNS流量分發(fā)的容災(zāi)方案在IP切換時(shí),通常會(huì)有客戶端緩存而造成服務(wù)短暫不可用,而基于多集群網(wǎng)關(guān)的容災(zāi)方案則可以平滑地將流量Fallback到另一個(gè)集群的服務(wù)后端。
多集群網(wǎng)關(guān)是地域級(jí)別的,所以所有操作都僅需在Fleet實(shí)例中操作(創(chuàng)建網(wǎng)關(guān)、Ingress資源等),無(wú)需在每個(gè)ACK集群中都安裝Ingress Controller和創(chuàng)建Ingress資源,提供地域級(jí)全局流量管理能力的同時(shí),還能減少多集群管理成本。
方案架構(gòu)
ACK One多集群網(wǎng)關(guān)通過(guò)托管MSE Ingress來(lái)實(shí)現(xiàn),結(jié)合ACK One GitOps的應(yīng)用多集群分發(fā)能力,可以幫助您快速實(shí)現(xiàn)應(yīng)用的同城容災(zāi)系統(tǒng)。本文將通過(guò)GitOps部署示例應(yīng)用到中國(guó)(香港)地域的兩個(gè)不同可用區(qū)的ACK集群(Cluster 1、Cluster 2)為例,介紹如何實(shí)現(xiàn)同城多活容災(zāi)和同城主備容災(zāi)。
本文示例應(yīng)用為Web應(yīng)用,包含Deployment、Service資源,通過(guò)多集群網(wǎng)關(guān)實(shí)現(xiàn)同城容災(zāi)的方案架構(gòu)如下圖所示。
在ACK One Fleet中通過(guò)MseIngressConfig資源來(lái)創(chuàng)建MSE網(wǎng)關(guān)。
在同一個(gè)地域的兩個(gè)不同可用區(qū)AZ 1和AZ 2中,分別創(chuàng)建一個(gè)ACK集群Cluster 1和Cluster 2。
通過(guò)ACK One GitOps將應(yīng)用分發(fā)到已創(chuàng)建的Cluster 1和Cluster 2集群中。
創(chuàng)建多集群網(wǎng)關(guān)后,通過(guò)設(shè)置流量規(guī)則可以實(shí)現(xiàn)按權(quán)重路由流量、根據(jù)Header將流量路由到指定集群的能力,當(dāng)其中一個(gè)集群異常時(shí),流量將自動(dòng)路由到另一個(gè)集群中。
前提條件
已開(kāi)啟艦隊(duì)管理功能。具體操作,請(qǐng)參見(jiàn)開(kāi)啟艦隊(duì)管理功能。
ACK One Fleet已關(guān)聯(lián)2個(gè)與Fleet實(shí)例相同VPC的ACK集群。具體操作,請(qǐng)參見(jiàn)添加關(guān)聯(lián)集群。
已從ACK One控制臺(tái)獲取Fleet實(shí)例的KubeConfig,并通過(guò)kubectl連接至Fleet實(shí)例。
- 說(shuō)明
關(guān)于多集群網(wǎng)關(guān)計(jì)費(fèi)的更多信息,請(qǐng)參見(jiàn)計(jì)費(fèi)規(guī)則。
已在ACK One Fleet實(shí)例中創(chuàng)建Namespace,該Namespace與關(guān)聯(lián)集群中部署應(yīng)用的Namespace一致(本文示例的Namespace為
gateway-demo
)
步驟一:使用GitOps部署應(yīng)用到多個(gè)集群
通過(guò)ArgoCD UI部署
登錄ACK One控制臺(tái),在左側(cè)導(dǎo)航欄選擇 。
在GitOps頁(yè)面,單擊GitOps控制臺(tái)跳轉(zhuǎn)至GitOps頁(yè)面。
說(shuō)明若ACK One艦隊(duì)的Fleet實(shí)例未開(kāi)啟GitOps,請(qǐng)先單擊開(kāi)啟GitOps,才能登錄GitOps控制臺(tái)。
如需通過(guò)公網(wǎng)訪問(wèn)GitOps,請(qǐng)開(kāi)通公網(wǎng)訪問(wèn)GitOps。
添加應(yīng)用倉(cāng)庫(kù)。
在ArgoCD UI左側(cè)導(dǎo)航欄選擇Settings,然后選擇
。在彈出的面板中配置以下信息,然后單擊CONNECT添加連接。
區(qū)域
參數(shù)
參數(shù)值
Choose your connection method
VIA HTTPS
CONNECT REPO USING HTTPS
Type
git
Project
default
Repository URL
https://github.com/AliyunContainerService/gitops-demo.git
Skip server verification
勾選
連接添加成功后會(huì)顯示Git的CONNECTION STATUS為Successful。
創(chuàng)建應(yīng)用。
在ArgoCD的Applications頁(yè)面中,單擊+ NEW APP,進(jìn)行如下參數(shù)配置。
區(qū)域
參數(shù)
說(shuō)明
GENERAL
Application Name
自定義應(yīng)用名稱。
Project Name
default
SYNC POLICY
可根據(jù)實(shí)際情況選擇同步策略。取值:
Manual:當(dāng)Git端有變更時(shí),需手動(dòng)執(zhí)行同步動(dòng)作將其部署至目標(biāo)集群。
Automatic:ArgoCD Server每隔3分鐘自動(dòng)檢測(cè)Git端的變更并將其自動(dòng)部署至目標(biāo)集群。
SYNC OPTIONS
勾選
AUTO-CREATE NAMESPACE
。SOURCE
Repository URL
在下拉列表選擇已有Git Repo,此處選擇上一步已添加的
https://github.com/AliyunContainerService/gitops-demo.git
。Revision
選擇Branches:
gateway-demo
。Path
manifests/helm/web-demo
DESTINATION
Cluster URL
選擇集群1或集群2的URL。
也可以單擊右側(cè)的
URL
,切換為根據(jù)CLUSTER NAME
字段選擇。Namespace
本示例使用
gateway-demo
。表示應(yīng)用資源(Service、Deployment)將被創(chuàng)建在此Namespace下。Helm
Parameters
envCluster
值設(shè)置為cluster-demo-1
或cluster-demo-2
,用于區(qū)分請(qǐng)求由哪個(gè)集群的后端處理。
通過(guò)ArgoCD CLI部署
在ACK One Fleet實(shí)例中開(kāi)啟GitOps。具體操作,請(qǐng)參見(jiàn)在ACK One Fleet實(shí)例中開(kāi)啟GitOps。
訪問(wèn)ArgoCD。具體操作,請(qǐng)參見(jiàn)通過(guò)ArgoCD CLI方式訪問(wèn)ArgoCD。
創(chuàng)建并發(fā)布應(yīng)用。
執(zhí)行以下命令,添加Git Repo。
argocd repo add https://github.com/AliyunContainerService/gitops-demo.git --name ackone-gitops-demos
預(yù)期輸出:
Repository 'https://github.com/AliyunContainerService/gitops-demo.git' added
執(zhí)行以下命令,查看已添加的Git Repo列表。
argocd repo list
預(yù)期輸出:
TYPE NAME REPO INSECURE OCI LFS CREDS STATUS MESSAGE PROJECT git https://github.com/AliyunContainerService/gitops-demo.git false false false false Successful default
執(zhí)行以下命令,查看Clusters列表。
argocd cluster list
預(yù)期輸出:
SERVER NAME VERSION STATUS MESSAGE PROJECT https://1.1.XX.XX:6443 c83f3cbc90a****-temp01 1.22+ Successful https://2.2.XX.XX:6443 c83f3cbc90a****-temp02 1.22+ Successful https://kubernetes.default.svc in-cluster Unknown Cluster has no applications and is not being monitored.
使用Application方式創(chuàng)建并發(fā)布Demo應(yīng)用到目標(biāo)集群。
使用以下內(nèi)容,創(chuàng)建apps-web-demo.yaml文件。
其中
repoURL
需替換為您實(shí)際的倉(cāng)庫(kù)地址。apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: app-demo-cluster1 namespace: argocd spec: destination: namespace: gateway-demo # https://1.1.XX.XX:6443 server: ${cluster1_url} project: default source: helm: releaseName: "web-demo" parameters: - name: envCluster value: cluster-demo-1 valueFiles: - values.yaml path: manifests/helm/web-demo repoURL: https://github.com/AliyunContainerService/gitops-demo.git targetRevision: gateway-demo syncPolicy: syncOptions: - CreateNamespace=true --- apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: app-demo-cluster1 namespace: argocd spec: destination: namespace: gateway-demo server: ${cluster2_url} project: default source: helm: releaseName: "web-demo" parameters: - name: envCluster value: cluster-demo-2 valueFiles: - values.yaml path: manifests/helm/web-demo repoURL: https://github.com/AliyunContainerService/gitops-demo.git targetRevision: gateway-demo syncPolicy: syncOptions: - CreateNamespace=true
執(zhí)行以下命令,部署應(yīng)用。
kubectl apply -f apps-web-demo.yaml
執(zhí)行以下命令,查看應(yīng)用列表。
argocd app list
預(yù)期輸出:
# app list NAME CLUSTER NAMESPACE PROJECT STATUS HEALTH SYNCPOLICY CONDITIONS REPO PATH TARGET argocd/web-demo-cluster1 https://10.1.XX.XX:6443 default Synced Healthy Auto <none> https://github.com/AliyunContainerService/gitops-demo.git manifests/helm/web-demo main argocd/web-demo-cluster2 https://10.1.XX.XX:6443 default Synced Healthy Auto <none> https://github.com/AliyunContainerService/gitops-demo.git manifests/helm/web-demo main
步驟二:在Fleet實(shí)例中通過(guò)kubectl創(chuàng)建多集群網(wǎng)關(guān)
通過(guò)在ACK One Fleet中創(chuàng)建MseIngressConfig對(duì)象來(lái)創(chuàng)建一個(gè)多集群網(wǎng)關(guān),并將關(guān)聯(lián)集群添加至多集群網(wǎng)關(guān)。
獲取ACK One Fleet實(shí)例的虛擬交換機(jī)ID并記錄。具體操作,請(qǐng)參見(jiàn)獲取交換機(jī)ID。
使用以下內(nèi)容,創(chuàng)建gateway.yaml文件。
說(shuō)明請(qǐng)將
${vsw-id1}
和${vsw-id2}
替換為您上一步獲取的交換機(jī)ID,${cluster1}
、${cluster2}
替換為您待添加的關(guān)聯(lián)集群ID。子集群
${cluster1}
、${cluster2}
的安全組的入方向需要允許該交換機(jī)網(wǎng)段的IP和所有端口通過(guò)。
apiVersion: mse.alibabacloud.com/v1alpha1 kind: MseIngressConfig metadata: annotations: mse.alibabacloud.com/remote-clusters: ${cluster1},${cluster2} name: ackone-gateway-hongkong spec: common: instance: replicas: 3 spec: 2c4g network: vSwitches: - ${vsw-id} ingress: local: ingressClass: mse name: mse-ingress
參數(shù)
說(shuō)明
mse.alibabacloud.com/remote-clusters
表示待添加到多集群網(wǎng)關(guān)的集群。此處所填的是已經(jīng)關(guān)聯(lián)到Fleet實(shí)例的集群ID。
spec.name
網(wǎng)關(guān)實(shí)例名稱。
spec.common.instance.spec
可選,網(wǎng)關(guān)實(shí)例規(guī)格。默認(rèn)為
4c8g
。spec.common.instance.replicas
可選,網(wǎng)關(guān)實(shí)例副本數(shù)。默認(rèn)為3個(gè)。
spec.ingress.local.ingressClass
可選,待監(jiān)聽(tīng)的ingressClass名稱,表示監(jiān)聽(tīng)Fleet實(shí)例中所有
ingressClass
字段設(shè)置為mse
的Ingress。執(zhí)行以下命令,部署多集群網(wǎng)關(guān)。
kubectl apply -f gateway.yaml
執(zhí)行以下命令,驗(yàn)證多集群網(wǎng)關(guān)是否創(chuàng)建成功并處于監(jiān)聽(tīng)狀態(tài)。
kubectl get mseingressconfig ackone-gateway-hongkong
預(yù)期輸出:
NAME STATUS AGE ackone-gateway-hongkong Listening 3m15s
預(yù)期輸出中網(wǎng)關(guān)狀態(tài)為
Listening
,表明云原生網(wǎng)關(guān)創(chuàng)建成功處于運(yùn)行狀態(tài),并自動(dòng)監(jiān)聽(tīng)集群中IngressClass為mse
的Ingress資源。通過(guò)MseIngressConfig創(chuàng)建的多集群網(wǎng)關(guān)會(huì)按照Pending、Running、Listening的狀態(tài)依次變化。各狀態(tài)說(shuō)明如下:
Pending:表明云原生網(wǎng)關(guān)正在創(chuàng)建中,需等待3分鐘左右。
Running:表明云原生網(wǎng)關(guān)創(chuàng)建成功,并處于運(yùn)行狀態(tài)。
Listening:表明云原生網(wǎng)關(guān)處于運(yùn)行狀態(tài),并監(jiān)聽(tīng)集群中Ingress資源。
Failed:表明云原生網(wǎng)關(guān)處于非法狀態(tài),可以查看Status字段中的Message來(lái)進(jìn)一步明確原因。
執(zhí)行以下命令,確認(rèn)關(guān)聯(lián)集群是否添加成功。
kubectl get mseingressconfig ackone-gateway-hongkong -ojsonpath="{.status.remoteClusters}"
預(yù)期輸出:
[{"clusterId":"c7fb82****"},{"clusterId":"cd3007****"}]
預(yù)期輸出中已包含指定的Cluster ID,并且無(wú)Failed信息,表明關(guān)聯(lián)集群已成功添加至多集群網(wǎng)關(guān)。
步驟三:使用Ingress實(shí)現(xiàn)同城容災(zāi)
多集群網(wǎng)關(guān)通過(guò)Ingress對(duì)多集群流量進(jìn)行管理,您可以在ACK One Fleet實(shí)例中創(chuàng)建Ingress對(duì)象來(lái)實(shí)現(xiàn)同城多活容災(zāi)和同城主備容災(zāi)。
確認(rèn)您已經(jīng)在Fleet實(shí)例中創(chuàng)建Namespacegateway-demo
,此處創(chuàng)建的Ingress需要和上一步部署的Demo應(yīng)用中Service的Namespace保持一致為gateway-demo
。
同城多活容災(zāi)
創(chuàng)建Ingress實(shí)現(xiàn)同城多活容災(zāi)
在ACK One Fleet實(shí)例中創(chuàng)建以下Ingress對(duì)象,可以實(shí)現(xiàn)同城多活容災(zāi)。
默認(rèn)將流量負(fù)載均衡到已添加到多集群網(wǎng)關(guān)的兩個(gè)集群的同名服務(wù)后端的每個(gè)副本中,如果其中的Cluster 1后端異常,網(wǎng)關(guān)自動(dòng)將流量全都路由到Cluster 2。Cluster 1和Cluster 2的副本數(shù)比為9:1,所以默認(rèn)90%流量被路由到Cluster 1, 10%流量被路由到Cluster 2,在Cluster 1后端全部異常后,100%流量自動(dòng)被路由到Cluster 2。拓?fù)淙缦滤荆?img id="896848a07e26z" src="https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/4020259961/p736646.png" alt="image.png" placement="break" width="500" class="image break">
使用以下內(nèi)容,創(chuàng)建ingress-demo.yaml文件。
以下代碼中,通過(guò)域名
example.com
下的/svc1
路由規(guī)則暴露后端服務(wù)service1
。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: web-demo spec: ingressClassName: mse rules: - host: example.com http: paths: - path: /svc1 pathType: Exact backend: service: name: service1 port: number: 80
執(zhí)行以下命令,在ACK One Fleet實(shí)例中部署Ingress。
kubectl apply -f ingress-demo.yaml -n gateway-demo
實(shí)現(xiàn)灰度發(fā)布驗(yàn)證
在多活容災(zāi)場(chǎng)景下,不影響業(yè)務(wù)的前提下,您可以通過(guò)以下方式對(duì)應(yīng)用進(jìn)行灰度發(fā)布驗(yàn)證。
在已有集群中新建應(yīng)用,僅將Service和Deployment的name
和selector
與原應(yīng)用進(jìn)行區(qū)分,之后基于Header在新建的應(yīng)用上進(jìn)行驗(yàn)證。
使用以下內(nèi)容,在Cluster 1中新建new-app.yaml文件。僅Service和Deployment與原應(yīng)用有差異,其他均一致。
apiVersion: v1 kind: Service metadata: name: service1-canary-1 namespace: gateway-demo spec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: app: web-demo-canary-1 sessionAffinity: None type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: name: web-demo-canary-1 namespace: gateway-demo spec: replicas: 1 selector: matchLabels: app: web-demo-canary-1 template: metadata: labels: app: web-demo-canary-1 spec: containers: - env: - name: ENV_NAME value: cluster-demo-1-canary image: 'registry-cn-hangzhou.ack.aliyuncs.com/acs/web-demo:0.6.0' imagePullPolicy: Always name: web-demo
執(zhí)行以下命令,在Cluster 1中部署新的應(yīng)用。
kubectl apply -f new-app.yaml
使用以下內(nèi)容,創(chuàng)建new-ingress.yaml文件。
在Fleet實(shí)例中創(chuàng)建基于Header的Ingress。通過(guò)添加Annotations開(kāi)啟Canary,并指定Header,在請(qǐng)求中使用Header:
canary-dest: cluster1
來(lái)將流量路由到灰度版本進(jìn)行驗(yàn)證。nginx.ingress.kubernetes.io/canary
:設(shè)置為"true"
,表示開(kāi)啟灰度發(fā)布能力。nginx.ingress.kubernetes.io/canary-by-header
:請(qǐng)求到該集群的header key。nginx.ingress.kubernetes.io/canary-by-header-value
:請(qǐng)求到該集群的header value。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: web-demo-canary-1 namespace: gateway-demo annotations: nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-by-header: "canary-dest" nginx.ingress.kubernetes.io/canary-by-header-value: "cluster1" spec: ingressClassName: mse rules: - host: example.com http: paths: - path: /svc1 pathType: Exact backend: service: name: service1-canary-1 port: number: 80
執(zhí)行以下命令,在Fleet實(shí)例中部署基于Header的Ingress。
kubectl apply -f new-ingress.yaml
驗(yàn)證同城多活容災(zāi)實(shí)現(xiàn)效果
修改部署到Cluster 1的副本數(shù)為9,Cluster 2的副本數(shù)為1,即期望默認(rèn)流量按照9:1路由到Cluster 1和Cluster 2,并且在Cluster1異常后,自動(dòng)將所有流量路由到Cluster 2。
執(zhí)行以下命令,獲取多集群網(wǎng)關(guān)的對(duì)外IP。
kubectl get ingress web-demo -n gateway-demo -ojsonpath="{.status.loadBalancer}"
默認(rèn)流量按比例路由到兩個(gè)集群
執(zhí)行以下命令,查看流量的路由情況。
替換以下
XX.XX.XX.XX
為上一步獲取的多集群網(wǎng)關(guān)的對(duì)外IP。for i in {1..100}; do curl -H "host: example.com" XX.XX.XX.XX done
預(yù)期輸出:預(yù)期輸出表明,流量被負(fù)載均衡到了Cluster 1和Cluster 2,到Cluster 1和Cluster 2的流量比為9:1。
Cluster 1異常后流量全部容災(zāi)到Cluster 2
如果將Cluster 1的Deployment的
replica
縮為0時(shí),得到的輸出結(jié)果如下,表明流量已被自動(dòng)容災(zāi)到Cluster 2。通過(guò)Header將請(qǐng)求路由到灰度版本
執(zhí)行以下命令,查看流量的路由情況。
替換以下
XX.XX.XX.XX
為實(shí)現(xiàn)灰度發(fā)布驗(yàn)證中的應(yīng)用和Ingress部署完成后查詢到的IP。for i in {1..100}; do curl -H "host: example.com" -H "canary-dest: cluster1" xx.xx.xx.xx/svc1; sleep 1; done
預(yù)期輸出:預(yù)期輸出表明,添加了header:
canary-dest: cluster1
的請(qǐng)求都被路由到了Cluster 1中的灰度版本。
同城主備容災(zāi)
在ACK One Fleet實(shí)例中創(chuàng)建以下Ingress對(duì)象,可以實(shí)現(xiàn)同城主備容災(zāi)。
當(dāng)兩個(gè)集群后端都正常時(shí),流量?jī)H路由到Cluster 1的服務(wù)后端;如果其中一個(gè)Cluster 1后端異常,網(wǎng)關(guān)會(huì)自動(dòng)將流量路由到Cluster 2。拓?fù)淙缦滤荆?img id="4cb390e07et4c" src="https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/1735810071/p736664.png" alt="image.png" placement="break" width="500" translate="yes" class="image break">
創(chuàng)建Ingress實(shí)現(xiàn)同城主備容災(zāi)
使用以下內(nèi)容,創(chuàng)建ingress-demo-cluster-one.yaml文件。
以下Ingress對(duì)象的YAML文件中,通過(guò)添加兩個(gè)Annotations
mse.ingress.kubernetes.io/service-subset
、mse.ingress.kubernetes.io/subset-labels
以實(shí)現(xiàn)域名example.com
下的/service1
路由規(guī)則暴露后端服務(wù)service1
。關(guān)于MSE Ingress支持的Annotations詳情,請(qǐng)參見(jiàn)MSE Ingress支持的Annotation。mse.ingress.kubernetes.io/service-subset
:服務(wù)的子版本名稱。建議定義為與目標(biāo)集群相關(guān)且可讀性強(qiáng)的值。mse.ingress.kubernetes.io/subset-labels
:指定目標(biāo)集群的ID。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: mse.ingress.kubernetes.io/service-subset: cluster-demo-1 mse.ingress.kubernetes.io/subset-labels: | topology.istio.io/cluster ${cluster1-id} name: web-demo-cluster-one spec: ingressClassName: mse rules: - host: example.com http: paths: - path: /service1 pathType: Exact backend: service: name: service1 port: number: 80
執(zhí)行以下命令,在ACK One Fleet實(shí)例中部署Ingress。
kubectl apply -f ingress-demo-cluster-one.yaml -ngateway-demo
實(shí)現(xiàn)集群級(jí)別灰度發(fā)布
多集群網(wǎng)關(guān)支持創(chuàng)建基于Header的Ingress以實(shí)現(xiàn)將請(qǐng)求路由到指定集群,基于該能力與創(chuàng)建Ingress實(shí)現(xiàn)同城主備容災(zāi)中Ingress對(duì)象實(shí)現(xiàn)的全副本負(fù)載均衡的能力,可以實(shí)現(xiàn)基于Header的灰度發(fā)布。
已創(chuàng)建Ingress實(shí)現(xiàn)同城主備容災(zāi)中的Ingress。
在ACK One Fleet實(shí)例中創(chuàng)建包含Header相關(guān)Annotation的Ingress,實(shí)現(xiàn)集群級(jí)別的灰度發(fā)布。請(qǐng)求的Header與Ingress中的配置相匹配時(shí),請(qǐng)求將被路由到灰度版本的后端。
使用以下內(nèi)容,創(chuàng)建ingress-demo-cluster-gray.yaml文件。
以下Ingress對(duì)象的YAML文件中,替換YAML中的
${cluster1-id}
為目標(biāo)集群ID。除了mse.ingress.kubernetes.io/service-subset
和mse.ingress.kubernetes.io/subset-labels
兩個(gè)Annotation之外,您還需要添加以下Annotation以實(shí)現(xiàn)域名example.com
下的/service1
路由規(guī)則暴露后端服務(wù)service1
nginx.ingress.kubernetes.io/canary
:設(shè)置為"true"
,表示開(kāi)啟灰度發(fā)布能力。nginx.ingress.kubernetes.io/canary-by-header
:表示請(qǐng)求到該集群的header key。nginx.ingress.kubernetes.io/canary-by-header-value
:表示請(qǐng)求到該集群的header value。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: mse.ingress.kubernetes.io/service-subset: cluster-demo-2 mse.ingress.kubernetes.io/subset-labels: | topology.istio.io/cluster ${cluster2-id} nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-by-header: "app-web-demo-version" nginx.ingress.kubernetes.io/canary-by-header-value: "gray" name: web-demo-cluster-gray name: web-demo spec: ingressClassName: mse rules: - host: example.com http: paths: - path: /service1 pathType: Exact backend: service: name: service1 port: number: 80
執(zhí)行以下命令,在ACK One Fleet實(shí)例中部署Ingress。
kubectl apply -f ingress-demo-cluster-gray.yaml -n gateway-demo
驗(yàn)證同城主備容災(zāi)實(shí)現(xiàn)效果
為便于驗(yàn)證,修改部署到Cluster 1和Cluster 2的副本數(shù)都為1,期望默認(rèn)流量只被路由到Cluster 1,加灰度Header的流量被路由到Cluster 2,當(dāng)Cluster 1應(yīng)用異常后,默認(rèn)流量也被路由到Cluster 2。
執(zhí)行以下命令,獲取多集群網(wǎng)關(guān)的對(duì)外IP。
kubectl get ingress web-demo -n gateway-demo -ojsonpath="{.status.loadBalancer}"
默認(rèn)流量路由到Cluster 1
執(zhí)行以下命令,查看默認(rèn)流量是否被路由到Cluster 1。
替換以下
XX.XX.XX.XX
為上一步獲取的多集群網(wǎng)關(guān)的對(duì)外IP。for i in {1..100}; do curl -H "host: example.com" xx.xx.xx.xx/service1; sleep 1; done
預(yù)期輸出:預(yù)期輸出表明,默認(rèn)流量全都被路由到Cluster 1了。
通過(guò)header將請(qǐng)求路由到灰度版本
執(zhí)行以下命令,查看Header的請(qǐng)求是否被路由到灰度版本。
替換以下
XX.XX.XX.XX
為上一步獲取的多集群網(wǎng)關(guān)的對(duì)外IP。for i in {1..50}; do curl -H "host: example.com" -H "app-web-demo-version: gray" xx.xx.xx.xx/service1; sleep 1; done
預(yù)期輸出:預(yù)期輸出表明,添加了Header:
app-web-demo-version: gray
的請(qǐng)求都被路由到了Cluster 2(灰度版本)。Cluster 1異常后流量被容災(zāi)到Cluster 2
如果將Cluster 1的Deployment的
replica
縮為0時(shí),得到的輸出結(jié)果如下,表明流量已被自動(dòng)容災(zāi)到Cluster 2。
相關(guān)文檔
如需了解ACK One多集群網(wǎng)關(guān)的南北流量管理能力,請(qǐng)參見(jiàn)管理南北流量。
關(guān)于ACK One GitOps應(yīng)用分發(fā)的相關(guān)操作,請(qǐng)參見(jiàn)GitOps快速入門。