通過ACK One ALB多集群網關,結合ACK One GitOps或多集群應用分發,可以快速實現應用的同城多活容災,保證應用高可用,并在故障發生時自動平滑遷移。本文介紹如何通過多集群網關構建同城容災系統。
容災概述
目前云上容災主要分為以下三類:
同城跨AZ容災:同城容災包含同城多活容災和同城主備容災2種策略,同城中心之間物理距離較近,網絡延遲低,可防范AZ級別性質的災難損害,例如火災、斷網或斷電等。此方案在實現數據備份和快速恢復方面相對簡單,仍具備較強的實用意義。
跨地域多活容災:跨地域多活容災對于網絡延遲相對較高,但可以防范地域性質的災難損害,例如地震、水災等。
兩地三中心:兩地三中心將同城雙中心和跨地域災備結合起來,兼具兩者的優點,適用于應用與數據連續性和可用性要求高的場景。
從業務架構上來說,企業的業務系統自上而下通常分為接入層、應用層和數據層。
接入層:流量入口,負責接收流量,根據路由轉發規則將流量轉發到后端應用層。
應用層:應用服務,根據請求對數據進行處理,并返回給上游。
數據層:數據存儲服務,為應用層提供數據和存儲數據。
為了實現整個業務容災,需對上述每一層實施相應的容災處理措施。
接入層:ACK One多集群網關作為接入層,其自身支持同城跨AZ高可用。
應用層:ACK One多集群網關處理應用層容災,可實現應用的同城多活/主備容災、跨地域容災。
數據層:數據層容災和數據同步,需要依賴于中間件自身。
功能優勢
基于ACK One多集群網關的容災方案與基于DNS流量分發的容災方案對比優勢如下:
基于DNS流量分發的容災方案需要多個LB IP(每個集群1個),而基于多集群網關的容災方案在地域級別僅需要1個LB IP,且默認提供同地域多可用區的高可用性。
基于多集群網關的容災支持七層路由轉發能力,而基于DNS流量分發的容災不支持七層路由轉發。
基于DNS流量分發的容災方案在IP切換時,通常會因客戶端緩存造成服務短暫不可用,而基于多集群網關的容災方案則可以更平滑地將流量Fallback到另一個集群的服務后端。
多集群網關是地域級別的,所有操作都僅需在Fleet實例中進行,無需在每個ACK集群中安裝Ingress Controller和創建Ingress資源。它提供地域級全局流量管理能力的同時,還能減少多集群管理成本。
方案架構
本文以Web應用為示例,展示了通過ALB多集群網關實現同城容災的方案架構,包括Deployment和Service資源,具體結構如下圖所示。
在同一個地域兩個不同可用區AZ 1和AZ 2中,分別創建一個ACK集群Cluster 1和Cluster 2。
通過ACK One GitOps將應用分發到已創建的Cluster 1和Cluster 2集群中。
在ACK One Fleet實例中通過AlbConfig資源來創建ALB多集群網關。
創建ALB多集群網關后,通過創建Ingress來實現按權重路由流量、根據Header將流量路由到指定集群的能力,當其中一個集群異常時,流量將自動路由到另一個集群中。
RDS數據同步需要依賴中間件自身能力。
前提條件
已從ACK One控制臺獲取Fleet實例的KubeConfig,并通過kubectl連接至Fleet實例。
步驟一:使用GitOps或應用分發部署應用到多個集群
ACK One支持多集群GitOps和多集群應用資源分發兩種方式,方便您將應用部署到多個集群。請參見GitOps快速入門、創建多集群應用與應用分發快速入門。本步驟以GitOps的多集群應用分發為例。
登錄ACK One控制臺,在左側導航欄選擇 。
在多集群應用頁面左上角,單擊艦隊名稱后的按鈕,在下拉列表中選擇目標艦隊。
單擊
進入創建多集群應用 - GitOps頁面。說明若您的ACK One Fleet實例未開啟GitOps,請先開啟GitOps。具體操作,請參見在ACK One Fleet實例中開啟GitOps。
如需通過公網訪問GitOps,請開通公網訪問GitOps。
在YAML創建頁簽,將以下YAML內容復制到控制臺,然后點擊確定進行創建和部署應用。
說明以下YAML內容是將
web-demo
部署到所有關聯集群中,您也可以通過快捷創建選擇集群,變化會同步到YAML創建的內容。apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: name: appset-web-demo namespace: argocd spec: template: metadata: name: '{{.metadata.annotations.cluster_id}}-web-demo' namespace: argocd spec: destination: name: '{{.name}}' namespace: gateway-demo project: default source: repoURL: https://github.com/AliyunContainerService/gitops-demo.git path: manifests/helm/web-demo targetRevision: main helm: valueFiles: - values.yaml parameters: - name: envCluster value: '{{.metadata.annotations.cluster_name}}' syncPolicy: automated: {} syncOptions: - CreateNamespace=true generators: - clusters: selector: matchExpressions: - values: - cluster key: argocd.argoproj.io/secret-type operator: In - values: - in-cluster key: name operator: NotIn goTemplateOptions: - missingkey=error syncPolicy: preserveResourcesOnDeletion: false goTemplate: true
步驟二:在艦隊中通過kubectl創建ALB多集群網關
通過在ACK One Fleet實例中創建AlbConfig對象來創建一個ACK One ALB多集群網關,并為ALB多集群網關添加關聯集群。
從ACK One艦隊所在VPC,獲取兩個虛擬交換機ID。
使用以下內容,創建
gateway.yaml
文件。說明請將
${vsw-id1}
和${vsw-id2}
替換為您上一步獲取的交換機ID,${cluster1}
、${cluster2}
替換為您待添加的關聯集群ID。子集群
${cluster1}
、${cluster2}
的安全組的入方向需要允許該交換機網段的IP和所有端口通過。
apiVersion: alibabacloud.com/v1 kind: AlbConfig metadata: name: ackone-gateway-demo annotations: # 添加要處理流量的關聯集群到ALB多集群實例。 alb.ingress.kubernetes.io/remote-clusters: ${cluster1},${cluster2} spec: config: name: one-alb-demo addressType: Internet addressAllocatedMode: Fixed zoneMappings: - vSwitchId: ${vsw-id1} - vSwitchId: ${vsw-id2} listeners: - port: 8001 protocol: HTTP --- apiVersion: networking.k8s.io/v1 kind: IngressClass metadata: name: alb spec: controller: ingress.k8s.alibabacloud/alb parameters: apiGroup: alibabacloud.com kind: AlbConfig name: ackone-gateway-demo
需要同步的參數及其說明如下表所示:
參數
是否必填
說明
metadata.name
是
AlbConfig的名稱。
metadata.annotations:
alb.ingress.kubernetes.io/remote-clusters
是
表示待添加到ALB多集群網關的關聯集群列表。此處所填的是已經關聯到艦隊實例的集群ID。
spec.config.name
否
ALB實例的名稱。
spec.config.addressType
否
ALB實例的網絡類型。取值如下:
Internet(默認值):公網類型。面向公網提供應用型負載均衡服務,公網可訪問。
說明應用型負載均衡通過綁定彈性公網IP進行公網服務,使用公網類型ALB實例將收取彈性公網IP的實例費與帶寬、流量費用,詳情參見按量付費。
Intranet:私網類型。面向VPC內部提供應用型負載均衡服務,公網不可訪問。
spec.config.zoneMappings
是
設置ALB交換機ID。創建交換機具體操作請參見創建和管理交換機。
說明指定的交換機必須在ALB當前所支持的可用區內,且與集群處于同一VPC。關于ALB支持的地域與可用區,請參見ALB支持的地域與可用區。
應用型負載均衡支持多可用區部署,若當前地域支持2個及以上可用區,為保障業務高可用,請至少選擇2個或以上不同可用區的交換機。
spec.listeners
否
配置ALB的監聽端口和協議。本文配置示例為端口8001的HTTP監聽。
監聽定義了流量進入負載均衡的方式和規則,此處建議保留該配置,否則您需要另行創建監聽才可使用ALB Ingress。
執行以下命令,部署
gateway.yaml
,創建ALB多集群網關和IngressClass。kubectl apply -f gateway.yaml
執行以下命令,查看ALB多集群網關是否創建成功(1~3min)。
kubectl get albconfig ackone-gateway-demo
預期輸出如下:
NAME ALBID DNSNAME PORT&PROTOCOL CERTID AGE ackone-gateway-demo alb-xxxx alb-xxxx.<regionid>.alb.aliyuncs.com 4d9h
確認關聯集群是否添加成功,執行以下命令查看狀態。
kubectl get albconfig ackone-gateway-demo -ojsonpath='{.status.loadBalancer.subClusters}'
預期輸出為集群ID列表。
步驟三:使用Ingress實現同城容災
多集群網關通過Ingress對多集群流量進行管理,您可以在ACK One Fleet實例中創建Ingress對象來實現同城多活容災。
在艦隊實例中創建Service所在的Namespace,本示例為
gateway-demo
。使用以下內容,創建
ingress-demo.yaml
文件。說明多個
alb.ingress.kubernetes.io/cluster-weight
注解權重總和必須等于100。通過域名
example.com
下的/svc1
路由規則暴露后端服務service1
。請先替換${cluster1-id}
和${cluster2-id}
。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: alb.ingress.kubernetes.io/listen-ports: | [{"HTTP": 8001}] alb.ingress.kubernetes.io/cluster-weight.${cluster1-id}: "20" alb.ingress.kubernetes.io/cluster-weight.${cluster2-id}: "80" name: web-demo namespace: gateway-demo spec: ingressClassName: alb rules: - host: alb.ingress.alibaba.com http: paths: - path: /svc1 pathType: Prefix backend: service: name: service1 port: number: 80
執行以下命令,在ACK One艦隊中部署Ingress。
kubectl apply -f ingress-demo.yaml -n gateway-demo
步驟四:驗證同城多活容災效果
流量按設置比例路由到各集群處理
訪問服務的格式如下:
curl -H "host: alb.ingress.alibaba.com" alb-xxxx.<regionid>.alb.aliyuncs.com:<listeners port>/svc1
需要同步的參數及其說明如下表所示:
參數 | 說明 |
| 步驟二中獲取的AlbConfig的 |
| AlbConfig中定義及Ingress中 |
執行以下命令后,從結果可以看出,請求按照20:80的比例發送到集群1(poc-ack-1)和集群2(poc-ack-2)處理。
for i in {1..500}; do curl -H "host: alb.ingress.alibaba.com" alb-xxxx.cn-beijing.alb.aliyuncs.com:8001/svc1; done > res.txt
某個集群應用異常時流量自動平滑遷移
執行以下命令后,我們手動將集群2的應用副本數設置為0,此時流量自動平滑遷移至集群1。
for i in {1..500}; do curl -H "host: alb.ingress.alibaba.com" alb-xxxx.cn-beijing.alb.aliyuncs.com:8001/svc1; sleep 1; done