ACK One マルチクラスターゲートウェイを使用すると、クラスターごとに個別のロードバランサー IP アドレスを管理したり、各クラスターに Ingress コントローラーをインストールしたりすることなく、複数の Kubernetes クラスターにわたるアプリケーションのゾーンレベルのディザスタリカバリを構築できます。このトピックでは、中国 (香港) リージョンの異なるアベイラビリティーゾーン (AZ) にある 2 つの ACK クラスターに GitOps を介してデプロイされたサンプルアプリケーションを使用して、アクティブなゾーン冗長性とプライマリ/セカンダリという 2 つのリカバリモードについて説明します。
マルチクラスターゲートウェイは、レイヤー 7 トラフィックのフェールオーバーのみを処理します。データのディザスタリカバリは、この機能の範囲外です。
仕組み
ACK One マルチクラスターゲートウェイは、マネージド Microservices Engine (MSE) Ingress に基づいて構築されています。ACK One GitOps (Argo CD) と組み合わせることで、セットアップは次のように機能します。
Argo CD を使用して、異なる AZ にある複数の ACK クラスターにアプリケーションをデプロイします。
フリートインスタンスにマルチクラスターゲートウェイ (
MseIngressConfig) を作成します。このゲートウェイは、リージョンレベルで単一の Server Load Balancer (SLB) IP アドレスをプロビジョニングし、関連付けられたすべてのクラスター全体で指定されたingressClassを持つ Ingress リソースを自動的に検出します。フリートインスタンスに Ingress オブジェクトを作成して、トラフィックルーティングルールを定義します。ゲートウェイは、関連付けられたクラスターのバックエンドサービスにリクエストをルーティングし、クラスターが異常になった場合はトラフィックを自動的にフェールオーバーします。
主要コンポーネント:
| コンポーネント | ロール |
|---|---|
| ACK One フリートインスタンス | マルチクラスターリソースを管理するためのコントロールプレーン。ゲートウェイと Ingress オブジェクトを作成する場所です。 |
| MSE Ingress (MseIngressConfig) | クラスター間でレイヤー 7 ルーティング、負荷分散、フェールオーバーを処理するクラウドネイティブゲートウェイ。 |
| Argo CD (GitOps) | Git リポジトリから複数の ACK クラスターにアプリケーションをデプロイおよび同期します。 |
| ACK クラスター (Cluster 1, Cluster 2) | アプリケーションを実行する別々のアベイラビリティーゾーンにあるワークロードクラスター。バックエンドとしてゲートウェイに追加されます。 |
リカバリモード
どちらのモードも AZ レベルの障害から保護します。違いは、通常の条件下でのトラフィックの分散方法にあります。
| モード | 通常のトラフィック分散 | フェールオーバー動作 | 最適な用途 |
|---|---|---|---|
| アクティブなゾーン冗長性 | レプリカ比率に基づいてすべてのクラスター間で負荷分散 | 正常なクラスターに自動的に再ルーティング | 水平にスケーリングできるステートレスアプリケーション |
| プライマリ/セカンダリ | すべてのトラフィックがプライマリクラスターに送信 | プライマリが異常な場合にセカンダリに自動的に再ルーティング | アクティブ/アクティブが複雑さを増すステートフルなバックエンド (データベース、キャッシュ) を持つアプリケーション |
前提条件
開始する前に、以下を完了していることを確認してください。
同じ Virtual Private Cloud (VPC) 内の 2 つの ACK クラスターをフリートインスタンスに関連付け済み — 「クラスターの関連付け」をご参照ください。
ACK One コンソールからフリートインスタンスの kubeconfig ファイルをダウンロードし、kubectl をそれに接続済み — 「ACK One コンソール」をご参照ください。
マルチクラスターゲートウェイ機能の有効化 — 課金については「課金ルール」をご参照ください。
フリートインスタンスに
gateway-demo名前空間を作成しました(関連付けられたクラスターでアプリケーションがデプロイされている名前空間と一致している必要があります)
ステップ1: アプリケーションを複数のクラスターにデプロイ
Argo CD を使用して、`web-demo` アプリケーションを Cluster 1 と Cluster 2 の両方にデプロイします。アプリケーションは Deployment と Service で構成されます。
Argo CD UI または CLI のいずれかを選択してください。
Argo CD UI を使用したデプロイ
「ACK One コンソール」にログインします。左側のナビゲーションウィンドウで、[Fleet > マルチクラスター アプリケーション] を選択します。
[マルチクラスター GitOps] ページで、[GitOps コンソール] をクリックします。
GitOps がまだ有効になっていない場合は、[GitOps の有効化] をクリックします。パブリックネットワーク経由で GitOps にアクセスするには、「Argo CD へのパブリックアクセスの有効化」をご参照ください。
アプリケーションリポジトリを追加します。
Argo CD の左側のナビゲーションウィンドウで [設定] をクリックし、[リポジトリ > + リポジトリを接続] を選択します。
以下のパラメーターを設定し、[接続] をクリックします。
セクション パラメーター 値 接続方法を選択 — HTTP/HTTPS 経由 HTTP/HTTPS を使用してリポジトリを接続 タイプ git プロジェクト default リポジトリ URL https://github.com/AliyunContainerService/gitops-demo.gitサーバー検証をスキップ このチェックボックスを選択 
接続が成功すると、**[接続ステータス]** に **[成功]** と表示されます。

クラスターごとにアプリケーションを作成します。[アプリケーション] ページで、[+ 新規アプリ] をクリックし、以下のパラメーターを設定します。クラスター 2 についてもこの手順を繰り返し、クラスター URL および
envClusterの値をそれぞれ置き換えます。セクション パラメーター 値 一般 アプリケーション名 アプリケーションの一意の名前 プロジェクト名 default同期ポリシー 手動 (オンデマンド同期) または 自動 (Argo CD は 3 分ごとに Git リポジトリをチェックし、変更を自動的にデプロイ) 同期オプション — 名前空間の自動作成ソース リポジトリ URL https://github.com/AliyunContainerService/gitops-demo.gitリビジョン ブランチ: gateway-demoパス manifests/helm/web-demo送信先 クラスター URL Cluster 1 の URL (または 2 番目のアプリケーションの場合は Cluster 2) を選択 名前空間 gateway-demoHelm > パラメーター envClustercluster-demo-1クラスター 1 用、cluster-demo-2クラスター 2 用
Argo CD CLI を使用したデプロイ
Git リポジトリを追加します。
argocd repo add https://github.com/AliyunContainerService/gitops-demo.git --name ackone-gitops-demos期待される出力:
Repository 'https://github.com/AliyunContainerService/gitops-demo.git' addedリポジトリが追加され、両方のクラスターが登録されていることを確認します。
argocd repo list期待される出力:
TYPE NAME REPO INSECURE OCI LFS CREDS STATUS MESSAGE PROJECT git https://github.com/AliyunContainerService/gitops-demo.git false false false false Successful defaultargocd cluster list期待されるクラスターリスト出力:
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.アプリケーションマニフェストを作成します。
repoURLを実際のリポジトリの URL に置き換え、${cluster1_url}および${cluster2_url}を前のステップのクラスター API サーバーの URL に置き換えます。apps-web-demo.yamlapiVersion: 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-cluster2 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アプリケーションをデプロイします。
kubectl apply -f apps-web-demo.yaml両方のアプリケーションが同期され、正常であることを確認します。
argocd 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
ステップ2: マルチクラスターゲートウェイの作成
フリートインスタンスに MseIngressConfig リソースを作成して、ゲートウェイをプロビジョニングし、両方のクラスターをバックエンドとして関連付けます。
フリートインスタンスの vSwitch ID を取得します — 「vSwitch ID の取得」をご参照ください。
ゲートウェイマニフェストを作成します。gateway.yaml
${vsw-id1}と${vsw-id2}を vSwitch ID に、${cluster1}と${cluster2}を関連付けられたクラスターの ID に置き換えます。 関連付けられた各クラスターについて、そのセキュリティグループのインバウンドルールを設定し、vSwitch CIDR ブロック内のすべての IP アドレスとポートからのアクセスを許可します。パラメーター 説明 mse.alibabacloud.com/remote-clustersゲートウェイに追加するクラスターのコンマ区切りの ID。フリートインスタンスにすでに関連付けられているクラスターである必要があります。 spec.nameゲートウェイインスタンスの名前。 spec.common.instance.spec(オプション) インスタンスタイプ。デフォルト: 4c8g。spec.common.instance.replicas(オプション) ゲートウェイレプリカの数。デフォルト: 3。spec.ingress.local.ingressClass(省略可能)リッスンする Ingress クラス名。ゲートウェイは、 ingressClassがmseに設定されているフリートインスタンス内のすべての Ingress リソースをリッスンします。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ゲートウェイをデプロイします。
kubectl apply -f gateway.yamlゲートウェイが
Listeningステータスになるまでお待ちください。クラウドネイティブゲートウェイの作成中のPending位相には、約 3 分かかる場合があります。ステータス 説明 Pendingゲートウェイのプロビジョニング中(約 3 分) Runningゲートウェイが作成され、実行中です Listeningゲートウェイが実行中であり、Ingress リソースを監視しています Failedゲートウェイが無効です。詳細については、 Statusフィールドをご確認くださいkubectl get mseingressconfig ackone-gateway-hongkong期待される出力:
NAME STATUS AGE ackone-gateway-hongkong Listening 3m15sゲートウェイのステータス値:
両方のクラスターが正常に追加されたことを確認します。
kubectl get mseingressconfig ackone-gateway-hongkong -ojsonpath="{.status.remoteClusters}"期待される出力:
[{"clusterId":"c7fb82****"},{"clusterId":"cd3007****"}]両方のクラスター ID が表示され、
Failedメッセージが表示されていないことから、クラスターがゲートウェイに接続されていることが確認されます。
ステップ3: Ingress を使用したゾーンディザスタリカバリの設定
マルチクラスターゲートウェイは、フリートインスタンスで定義された Ingress リソースを使用して、クラスター間でトラフィックをルーティングします。Ingress オブジェクトは、gateway-demo 名前空間に作成します — アプリケーションがデプロイされているのと同じ名前空間です。
gateway-demo 名前空間は、Ingress リソースを作成する前に、フリート インスタンスに存在している必要があります。
アプリケーションに適合するリカバリモードを選択してください。
アクティブなゾーン冗長性
アクティブなゾーン冗長性モードでは、レプリカ比率に基づいてすべてのクラスターバックエンド間でトラフィックが負荷分散されます。クラスターが異常になった場合、ゲートウェイはトラフィックシェアを自動的に残りの正常なクラスターに再ルーティングします。
例: Cluster 1 に 9 つのレプリカ、Cluster 2 に 1 つのレプリカがある場合、デフォルトではトラフィックの 90% が Cluster 1 に、10% が Cluster 2 に送信されます。Cluster 1 のすべてのバックエンドが失敗した場合、トラフィックの 100% が Cluster 2 にシフトします。

アクティブなゾーン冗長性用の Ingress の作成
ドメイン example.com 下で、service1 にトラフィックをルーティングする Ingress を作成します。ゲートウェイは、両方のクラスター内の同じ名前のサービス間でリクエストを分散します。
ingress-demo.yaml
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フリートインスタンスに Ingress をデプロイします。
kubectl apply -f ingress-demo.yaml -n gateway-demoアクティブなゾーン冗長性の検証
マルチクラスターゲートウェイのパブリック IP アドレスを取得します。
kubectl get ingress web-demo -n gateway-demo -ojsonpath="{.status.loadBalancer}"100 件のリクエストを送信し、トラフィックの分布を確認します。
XX.XX.XX.XXをゲートウェイのIP アドレスに置き換えます。for i in {1..100}; do curl -H "host: example.com" XX.XX.XX.XX; done期待される結果: トラフィックは Cluster 1 と Cluster 2 の間で 9:1 の比率で分散されます。

Cluster 1 の Deployment レプリカを 0 にスケーリングして、クラスター障害をシミュレートします。すべてのトラフィックは自動的に Cluster 2 に再ルーティングされます。

ヘッダーベースのルーティングによるカナリアリリースの実行
アクティブなゾーン冗長性モードでは、ライブトラフィックに影響を与えることなく、1 つのクラスターでカナリアリリースをテストできます。カナリアバージョンを別の Service および Deployment としてデプロイし、Ingress アノテーションを使用して、特定のヘッダーを持つリクエストをそれにルーティングします。
Cluster 1 にカナリアアプリケーションをデプロイします。new-app.yaml
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-demokubectl apply -f new-app.yamlフリートインスタンスにヘッダーに基づくカナリー Ingress を作成します。ヘッダー
canary-dest: cluster1を含むリクエストは、カナリー サービスにルーティングされます。new-ingress.yamlアノテーション 説明 nginx.ingress.kubernetes.io/canary"true"に設定すると、この Ingress でヘッダーベースのルーティングが有効になります。nginx.ingress.kubernetes.io/canary-by-header一致させるヘッダーキーを指定します。例: canary-destnginx.ingress.kubernetes.io/canary-by-header-value一致させるヘッダー値を指定します。例: cluster1apiVersion: 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: 80kubectl apply -f new-ingress.yamlヘッダーを持つリクエストがカナリアバージョンにルーティングされることを確認します。
for i in {1..100}; do curl -H "host: example.com" -H "canary-dest: cluster1" XX.XX.XX.XX/svc1; sleep 1; done期待される結果:
canary-dest: cluster1を含むすべてのリクエストは、クラスター 1 のカナリアリリースによって処理されます。
プライマリ/セカンダリディザスタリカバリ
プライマリ/セカンダリモードでは、通常の条件下ではすべてのトラフィックが Cluster 1 (プライマリ) に送信されます。Cluster 1 が異常になった場合、ゲートウェイはトラフィックを自動的に Cluster 2 (セカンダリ) に再ルーティングします。

このモードでは、Ingress ルートを特定のクラスターに固定するために、2 つの MSE 固有のアノテーションを使用します。
| アノテーション | 説明 |
|---|---|
mse.ingress.kubernetes.io/service-subset | サービスサブセットの読み取り可能なラベルです。対象クラスターを示す名前を使用してください。 |
mse.ingress.kubernetes.io/subset-labels | topology.istio.io/cluster ラベルを用いて、ルーティング先のクラスター ID を指定します。 |
MSE Ingress アノテーションの完全なリストについては、「MSE Ingress ゲートウェイでサポートされるアノテーション」をご参照ください。
プライマリ/セカンダリディザスタリカバリ用の Ingress の作成
クラスター 1 にトラフィックを固定するプライマリ Ingress を作成します。
${cluster1-id}を実際のクラスター ID に置き換えます。 ingress-demo-cluster-one.yamlapiVersion: 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: 80kubectl apply -f ingress-demo-cluster-one.yaml -n gateway-demo
クラスターレベルのカナリアリリースの実行
デフォルトのトラフィックパスを変更することなく、プライマリ Ingress とともにヘッダーベースのカナリア Ingress を使用して、検証のために特定の要求を Cluster 2 にルーティングします。
クラスター 2 をターゲットとするカナリア Ingress を作成します。
${cluster2-id}を実際のクラスター ID に置き換えます。ingress-demo-cluster-gray.yamlapiVersion: 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 spec: ingressClassName: mse rules: - host: example.com http: paths: - path: /service1 pathType: Exact backend: service: name: service1 port: number: 80kubectl apply -f ingress-demo-cluster-gray.yaml -n gateway-demo
プライマリ/セカンダリディザスタリカバリの検証
マルチクラスターゲートウェイのパブリック IP アドレスを取得します。
kubectl get ingress web-demo -n gateway-demo -ojsonpath="{.status.loadBalancer}"デフォルトのトラフィックが Cluster 1 に送信されることを確認します。
for i in {1..100}; do curl -H "host: example.com" XX.XX.XX.XX/service1; sleep 1; done期待される結果: すべてのデフォルトトラフィックは Cluster 1 によって処理されます。

カナリアトラフィックが Cluster 2 に送信されることを確認します。
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期待される結果:
app-web-demo-version: grayを含むすべてのリクエストは、クラスター 2 によって処理されます。
Deployment レプリカを 0 にスケーリングして Cluster 1 の障害をシミュレートします。すべてのデフォルトトラフィックは自動的に Cluster 2 に再ルーティングされます。

次のステップ
南北のトラフィックの管理 — Container Service for Kubernetes (ACK) One のマルチクラスターゲートウェイが提供するトラフィック管理機能を詳しくご確認ください。
GitOps クイックスタート — ACK One 上で Argo CD を使用したアプリケーションのデプロイ方法について詳しくご確認ください。