Alibaba Cloud Service Mesh (ASM) を採用する際は、トラフィックの受付を NGINX Ingress コントローラーから ASM イングレスゲートウェイへ移行する必要があります。本ガイドでは、既存のクラシックロードバランサー (CLB) インスタンスおよび IP アドレスを再利用し、DNS レコードを変更せずにゼロダウンタイム移行を実現する手順を説明します。途中で問題が発生した場合は、重みをリセットすることで、即座にすべてのトラフィックを NGINX Ingress コントローラーへ戻すことができます。
仕組み
NGINX Ingress コントローラーと ASM イングレスゲートウェイは、同一の CLB インスタンスのバックエンドとして並列稼働します。両者間のトラフィック配分は、CLB のバックエンド重みによって制御されます。初期状態ではすべてのトラフィックを NGINX Ingress コントローラーに割り当て、段階的に ASM ゲートウェイへ移行し、移行完了後に NGINX Ingress コントローラーを廃止します。

移行は以下の 5 つのステップで実施します:
CLB の NGINX Ingress からのデタッチ — 既存の CLB インスタンスを再利用可能に設定し、NGINX Ingress コントローラーと ASM ゲートウェイが共有できるようにします。
ASM ゲートウェイの作成 — ASM イングレスゲートウェイをデプロイし、重みを 0(トラフィックなし)として同一の CLB にアタッチします。
Ingress リソースを Istio 構成へ変換 — NGINX Ingress ルールを Istio Gateway および VirtualService リソースへ変換します。
構成の検証 — テストトラフィックを送信して、ASM ゲートウェイがリクエストを正しくルーティングすることを確認します。
トラフィックの移行 — ASM ゲートウェイの重みを段階的に増加させ、最終的にすべてのトラフィックを処理するようにします。
両方のゲートウェイが同一の CLB を共有するため、移行中も外部 IP アドレスおよび DNS レコードは変更されません。NGINX Ingress コントローラーは、明示的に重みを変更するまで本番トラフィックを継続して処理します。任意の時点でロールバックを行うには、ASM ゲートウェイの重みを 0 に、NGINX Ingress コントローラーの重みを 100 に設定してください。
前提条件
開始する前に、以下の条件を満たしていることを確認してください。
最新バージョンの ASM Enterprise Edition または Ultimate Edition インスタンスが存在すること。詳細については、「ASM インスタンスの作成」をご参照ください。
ASM インスタンスに追加済みの Container Service for Kubernetes (ACK) クラスターが存在すること。詳細については、「ASM インスタンスへのクラスターの追加」をご参照ください。
ステップ 1:NGINX Ingress の CLB インスタンスを再利用可能にする
デフォルトでは、ACK が NGINX Ingress の CLB インスタンスを管理しており、手動での変更が禁止されています。この CLB を ASM ゲートウェイと共有するには、まず ACK 管理からデタッチする必要があります。
CLB インスタンス ID の取得
以下のコマンドを実行して、CLB インスタンス ID を取得します。
kubectl -n kube-system get svc nginx-ingress-lb -o yaml | grep service.k8s.alibaba/loadbalancer-id期待される出力例:
service.k8s.alibaba/loadbalancer-id: lb-bp1gts52ced2vgaw1ni78CLB インスタンス ID(例:lb-bp1gts52ced2vgaw1ni78)を記録してください。後続のステップで使用します。
コンソールでの CLB 設定の更新
Server Load Balancer コンソールを開きます。
対象の CLB インスタンスを検索し、以下の変更を行います。
設定変更保護を無効にする。
kubernetes.do.not.deleteおよびack.aliyun.comのタグを削除します。k8s/で始まる vServer グループの名前を、shared-<port>形式に変更します。たとえば、k8s/80/nginx-ingress-lb/kube-system/c553a74e6ad13423aa839c8e5********をshared-80に変更します。
NGINX Ingress Service へのアノテーションの追加
NGINX Ingress Service に以下のアノテーションを追加し、ACK 管理による自動検出に依存せず、CLB を明示的に参照するように設定します。
metadata:
annotations:
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id: "<your-clb-instance-id>"
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-force-override-listeners: "false"
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-vgroup-port: "<your-vgroup-id-1>:80,<your-vgroup-id-2>:443"
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-weight: "100"以下のプレースホルダーを実際の値に置き換えてください。
| プレースホルダー | 説明 | 例 |
|---|---|---|
<your-clb-instance-id> | 前のステップで取得した CLB インスタンス ID | lb-bp1gts52ced2vgaw1ni78 |
<your-vgroup-id-1> | ポート 80 用の vServer グループ ID | rsp-bp1k5xxxxxxx |
<your-vgroup-id-2> | ポート 443 用の vServer グループ ID | rsp-bp1k5yyyyyyy |
vServer グループの表示名(例:shared-80)ではなく、vServer グループ ID を使用してください。ID は、Server Load Balancer コンソールで vServer グループの詳細を確認することで取得できます。
ステップ 2:ASM ゲートウェイの作成
YAML を使用して ASM ゲートウェイを作成します。ベースとなる YAML ファイルを生成するには、ASM コンソールで ASM ゲートウェイ作成ページを開き、ビジュアルフォームで設定を構成した後、プレビュー ボタンをクリックします。
serviceAnnotations セクションを編集して、同一の CLB インスタンスを再利用します。アノテーションの内容はステップ 1 と同一ですが、重みを "0" に設定することで、初期状態では ASM ゲートウェイがトラフィックを受信しないようにします。
serviceAnnotations:
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id: "<your-clb-instance-id>"
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-force-override-listeners: "false"
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-vgroup-port: "<your-vgroup-id>:80"
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-weight: "0"以下の表に、各アノテーションの説明を示します。
| アノテーション | 値 | 目的 |
|---|---|---|
alibaba-cloud-loadbalancer-id | ご使用の CLB インスタンス ID | 既存の CLB を再利用 |
alibaba-cloud-loadbalancer-force-override-listeners | "false" | Istio による既存の CLB リスナーのオーバーライドを防止(Istio ではデフォルトでリスナーがオーバーライドされます) |
alibaba-cloud-loadbalancer-vgroup-port | vServer グループ ID およびポートマッピング | トラフィックを正しいバックエンドグループへルーティング |
alibaba-cloud-loadbalancer-weight | "0" | ASM ゲートウェイへのトラフィックを初期状態でゼロにする |
ステップ 3:Ingress リソースを Istio 構成へ変換
各 NGINX Ingress リソースを、Istio Gateway および VirtualService のペアへ変換します。以下に、URL 書き換えを含む基本的な Ingress ルールの変換例を示します。
NGINX Ingress(変換前)
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: helloworld
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- http:
paths:
- backend:
serviceName: helloworld
servicePort: 80
path: /helloworld(/|$)(.*)
host: example.comIstio VirtualService(変換後)
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: example-vs
spec:
gateways:
- istio-system/ingressgateway # 実際の ASM ゲートウェイ名に置き換えてください
hosts:
- example.com
http:
- name: route-helloworld
match:
- uri:
prefix: /helloworld/
- uri:
prefix: /helloworld
rewrite:
uri: /
route:
- destination:
host: helloworld
port:
number: 80Ingress と VirtualService の主な相違点
以下の表に、NGINX Ingress のフィールドとその Istio VirtualService における対応関係をまとめます。
| 項目 | NGINX Ingress | Istio VirtualService |
|---|---|---|
| ルーティング先 | serviceName および servicePort | destination.host および destination.port.number |
| URL 書き換え | rewrite-target アノテーション | rewrite.uri フィールド |
| ホスト一致 | rules[].host | hosts[] |
| ゲートウェイのバインド | 暗黙的(Ingress コントローラー) | 明示的(gateways[] フィールド) |
一般的な NGINX Ingress アノテーションの対応関係
高度な NGINX Ingress アノテーションを使用している場合、以下の表に Istio における対応する構成を示します。
| NGINX Ingress アノテーション | Istio における対応構成 | リソース種別 |
|---|---|---|
nginx.ingress.kubernetes.io/rewrite-target | http[].rewrite.uri | VirtualService |
nginx.ingress.kubernetes.io/ssl-redirect | tls セクション(Gateway) | Gateway |
nginx.ingress.kubernetes.io/proxy-read-timeout | timeout フィールド | VirtualService |
nginx.ingress.kubernetes.io/upstream-hash-by | trafficPolicy 内の consistentHash | DestinationRule |
nginx.ingress.kubernetes.io/cors-enable | corsPolicy フィールド | VirtualService |
名前空間を横断するルーティング
VirtualService とその対象サービスが同一の名前空間にある場合は、短いサービス名(例:helloworld)を使用します。異なる名前空間にある場合は、完全修飾ドメイン名(FQDN)形式を使用します。
<service-name>.<namespace>.svc.cluster.local可能な限り、VirtualService および DestinationRule を対象サービスの Deployment と同じ名前空間に配置してください。これにより、ルーティング構成が簡素化され、FQDN の指定を回避できます。
ステップ 4:構成の検証
本番トラフィックの移行前に、ASM ゲートウェイがリクエストを正しく処理できることを検証します。
オプション A:一時的な CLB を使用したテスト
新しい CLB インスタンスを作成し、ASM イングレスゲートウェイを指すように設定します。この CLB に対してテストリクエストを送信します。
curl -s -I -H "Host: example.com" http://<test-clb-ip>/helloworld/期待される出力(主要ヘッダー):
HTTP/1.1 200 OK
server: istio-envoy応答ヘッダーの server: istio-envoy は、トラフィックが ASM ゲートウェイを経由していることを確認するものです。
オプション B:クラスター内からのテスト
クラスター内で、ASM イングレスゲートウェイの Service に対して直接リクエストを送信します。
# ASM イングレスゲートウェイの ClusterIP を取得
GATEWAY_IP=$(kubectl -n istio-system get svc istio-ingressgateway -o jsonpath='{.spec.clusterIP}')
# テストリクエストを送信
curl -s -I -H "Host: example.com" http://$GATEWAY_IP/helloworld/同様のリクエストに対する NGINX Ingress コントローラーの応答と一致することを確認してください。server: istio-envoy ヘッダーが応答に含まれている場合、トラフィックが ASM ゲートウェイを経由していることを示します。
ステップ 5:NGINX Ingress から ASM ゲートウェイへのトラフィック移行
検証が完了したら、CLB バックエンドの重みを調整して、段階的に本番トラフィックを ASM ゲートウェイへ移行します。
推奨される移行スケジュール
ASM ゲートウェイの重みを段階的に増加させ、各段階でモニタリングを行ってください。
| 段階 | ASM ゲートウェイの重み | NGINX Ingress コントローラーの重み | 操作 |
|---|---|---|---|
| 1 | 1 | 99 | 最小限の本番トラフィックで検証 |
| 2 | 10 | 90 | エラー率およびレイテンシーをモニタリング |
| 3 | 50 | 50 | 定常動作を確認 |
| 4 | 100 | 0 | 移行の完了 |
重みの調整
ASM ゲートウェイの重み:IstioGateway の service.beta.kubernetes.io/alibaba-cloud-loadbalancer-weight アノテーションを、serviceAnnotations 内で更新します。
serviceAnnotations:
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-weight: "50" # この値を調整NGINX Ingress コントローラーの重み:NGINX Ingress Service の service.beta.kubernetes.io/alibaba-cloud-loadbalancer-weight アノテーションを更新します。このアノテーションが設定されていない場合は、CLB コンソールで直接重みを調整してください。
ロールバック
トラフィック移行中に問題が発生した場合、ASM ゲートウェイの重みを "0" に、NGINX Ingress コントローラーの重みを "100" に戻します。
# ASM ゲートウェイ:トラフィック受信を停止
serviceAnnotations:
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-weight: "0"# NGINX Ingress Service:全トラフィックを復元
metadata:
annotations:
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-weight: "100"すべてのトラフィックが即座に NGINX Ingress コントローラーへ戻ります。両方のゲートウェイが同一の CLB インスタンスを共有しているため、DNS の変更は不要です。