すべてのプロダクト
Search
ドキュメントセンター

Alibaba Cloud Service Mesh:トラフィックレーンとハッシュタグ付けを使用したユーザーベースのカナリーテスト

最終更新日:Jun 22, 2026

Service Mesh (ASM) を使用すると、アプリケーションの複数のバージョンや機能をトラフィックレーンと呼ばれる独立した実行環境に分離し、レーンルールを定義することで、一致するリクエストトラフィックをターゲットのバージョンや機能にルーティングできます。本番環境では、レーンを使用して安定版とカナリーリリース版を分離し、ユーザー ID に基づいてトラフィックを異なるレーンにルーティングすることが考えられます。具体的には、特定の識別されたユーザーからのリクエストをテストのためにカナリーバージョンに直接ルーティングし、他のユーザーのトラフィックの一部を重みに基づいてランダムにカナリーバージョンにルーティングすることができます。このトピックでは、トラフィックレーンとハッシュタグ付けを組み合わせて、ユーザーベースのカナリーテストを実装する方法について説明します。

前提条件

操作手順

このシナリオ例では、次の呼び出しチェーンを持つ 3 つのアプリケーションを作成します。

  • mocka、バージョン v1

  • mockb、バージョン v1

  • mockc、バージョン v1 および v2

アプリケーションは、リクエストヘッダーの x-user-id を使用してユーザー ID を識別し、このヘッダーはサービス呼び出し間で渡されます。このシナリオでは、以下を実証します。

  • x-user-id: jason の場合、リクエストは新しいバージョンにルーティングされます。

  • 他のすべてのユーザーについては、x-user-id の値のハッシュを計算し、ハッシュ結果に基づいて指定された割合のユーザーを新しいバージョンにルーティングします。

ステップ 1:サンプルアプリケーションのデプロイ

  1. 次の内容で `sample.yaml` という名前のファイルを作成します。

    YAML コンテンツを展開して表示

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mocka-v1
      labels:
        app: mocka
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: mocka
          version: v1
          ASM_TRAFFIC_TAG: v1
      template:
        metadata:
          labels:
            app: mocka
            version: v1
            ASM_TRAFFIC_TAG: v1
        spec:
          containers:
          - name: default
            image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/go-http-sample:tracing
            imagePullPolicy: IfNotPresent
            env:
            - name: version
              value: v1
            - name: app
              value: mocka
            - name: upstream_url
              value: "http://mockb:8000/"
            ports:
            - containerPort: 8000
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mockb-v1
      labels:
        app: mockb
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: mockb
          version: v1
          ASM_TRAFFIC_TAG: v1
      template:
        metadata:
          labels:
            app: mockb
            version: v1
            ASM_TRAFFIC_TAG: v1
        spec:
          containers:
          - name: default
            image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/go-http-sample:tracing
            imagePullPolicy: IfNotPresent
            env:
            - name: version
              value: v1
            - name: app
              value: mockb
            - name: upstream_url
              value: "http://mockc:8000/"
            ports:
            - containerPort: 8000
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mockc-v1
      namespace: default
      labels:
        app: mockc
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: mockc
          version: v1
          ASM_TRAFFIC_TAG: v1
      template:
        metadata:
          labels:
            app: mockc
            version: v1
            ASM_TRAFFIC_TAG: v1
        spec:
          containers:
          - name: default
            image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/go-http-sample:tracing
            imagePullPolicy: IfNotPresent
            env:
            - name: version
              value: v1
            - name: app
              value: mockc
            ports:
            - containerPort: 8000
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mockc-v2
      namespace: default
      labels:
        app: mockc
        version: v2
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: mockc
          version: v2
          ASM_TRAFFIC_TAG: v2
      template:
        metadata:
          labels:
            app: mockc
            version: v2
            ASM_TRAFFIC_TAG: v2
        spec:
          containers:
          - name: default
            image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/go-http-sample:tracing
            imagePullPolicy: IfNotPresent
            env:
            - name: version
              value: v2
            - name: app
              value: mockc
            ports:
            - containerPort: 8000
  2. データプレーンクラスターの kubeconfig を使用して、次のコマンドを実行し、サンプルアプリケーションをデプロイします。

    kubectl apply -f sample.yaml

ステップ 2:ゲートウェイルールの作成

次の構成を使用して、`istio-system` 名前空間に `ingressgateway` という名前の Gateway リソースを作成します。詳細については、「ゲートウェイルールの管理」をご参照ください。

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: ingressgateway
  namespace: istio-system
spec:
  selector:
    istio: ingressgateway
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      hosts:
        - '*'

ステップ 3:スイムレーングループとスイムレーンの作成

  1. スイムレーングループを作成します。

    1. ASM コンソールにログインします。左側のナビゲーションウィンドウで、[Service Mesh] > [メッシュ管理] を選択します。

    2. Mesh Management ページで、ターゲットインスタンス名をクリックします。左側のナビゲーションウィンドウで、Traffic Management Center > Traffic Lane を選択します。

    3. Traffic Lane ページで、Create Swimlane Group をクリックします。Create Swimlane Group パネルで設定を構成し、OK をクリックします。

      設定項目

      説明

      Name of swim lane group

      この例では canary に設定します。

      Entrance gateway

      [ingressgateway] を選択します。

      Lane Mode

      Permissive Mode を選択します。

      Pass-through Mode of Trace Context

      Pass Through Trace ID を選択します。

      Trace ID Request Header

      この例では x-user-id に設定します。

      Routing Request Header

      ゲートウェイがトラフィックを異なるレーンにルーティングし、レーンコンテキストを維持するために使用するヘッダーを指定します。任意の値に設定できます。この例では、x-asm-prefer-tag に設定します。

      Swimlane Services

      ターゲットの Kubernetes クラスターと default 名前空間を選択します。下のリストで、mockamockbmockc サービスを選択し、移动 アイコンをクリックして selected エリアに追加します。

  2. s1 と s2 の 2 つのスイムレーンを作成し、それぞれをバージョン v1 と v2 にバインドします。

    1. Traffic Lane ページの Traffic Rule Definition セクションで、Create swimlanes をクリックします。

    2. Create swimlanes ダイアログボックスで設定を構成し、OK をクリックします。

      設定項目

      説明

      Swimlane Name

      それぞれ s1 と s2 に設定します。

      Configure Service Tag

      Label Key[ASM_TRAFFIC_TAG] を選択します。

      Label Value:一方のレーンには v1 を、もう一方には v2 を選択します。

      Add Service

      レーン s1:mocka(default)mockb(default)mockc(default) を選択します。

      レーン s2:mockc(default) を選択します。

      次の図は、レーン s1 を作成する例です。

      image

      両方のレーンが作成されると、結果は次のようになります。

      image

      説明

      デフォルトでは、スイムレーングループで最初に作成したスイムレーンがベースラインレーンになります。ベースラインレーンは変更可能です。これにより、トラフィックが別のレーンに存在しないサービスをターゲットにした場合に、リクエストがベースラインレーンにフォールバックするようになります。詳細については、「疎結合モードでベースラインレーンを変更する」をご参照ください。

  3. レーンのルーティングルールを作成します。

    1. 次の構成を使用して、レーンのゲートウェイルーティングルールを作成します。このルールは 3 つの部分で構成されています。

      1. x-user-id: jason を含むリクエストはレーン s2 にルーティングされ、システムはリクエストをレーン s2 用にマークするために x-asm-prefer-tag: s2 ヘッダーを追加します。

      2. x-asm-prefer-tag: s2 を含むリクエストはレーン s2 にルーティングされます。

      3. x-asm-prefer-tag: s1 を含むリクエストはレーン s1 にルーティングされます。

      YAML コンテンツを展開して表示

      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: swimlane-ingress-vs
        namespace: istio-system
      spec:
        gateways:
        - istio-system/ingressgateway
        hosts:
        - '*'
        http:
        # ルーティングルール 1: x-user-id: jason を含むリクエストはレーン s2 に移動
        # リクエストをレーン s2 用にマークするために x-asm-prefer-tag: s2 を追加
        - match:
          - headers:
              x-user-id:
                exact: jason
            uri:
              exact: /
          name: r2
          route:
          - destination:
              host: mocka.default.svc.cluster.local
              subset: s2
            fallback:
              target:
                host: mocka.default.svc.cluster.local
                subset: s1
            headers:
              request:
                set:
                  x-asm-prefer-tag: s2
        # ルーティングルール 2: x-asm-prefer-tag: s2 を含むリクエストはレーン s2 に移動
        - match:
          - headers:
              x-asm-prefer-tag:
                exact: s2
            uri:
              exact: /
          name: r2
          route:
          - destination:
              host: mocka.default.svc.cluster.local
              subset: s2
            # mocka がレーン s2 にない場合、レーン s1 の mocka にフォールバック
            fallback:
              target:
                host: mocka.default.svc.cluster.local
                subset: s1
        # ルーティングルール 3: x-asm-prefer-tag: s1 を含むリクエストはレーン s1 に移動
        - match:
          - headers:
              x-asm-prefer-tag:
                exact: s1
            uri:
              exact: /
          name: r1
          route:
          - destination:
              host: mocka.default.svc.cluster.local
              subset: s1

ステップ 4:ハッシュタグ付けプラグインのデプロイ

  1. 次の内容で `wasm.yaml` という名前のファイルを作成します。

    apiVersion: extensions.istio.io/v1alpha1
    kind: WasmPlugin
    metadata:
      name: hash-tagging
      namespace: istio-system
    spec:
      imagePullPolicy: IfNotPresent 
      selector:
        matchLabels:
          istio: ingressgateway
      url: registry-cn-hangzhou.ack.aliyuncs.com/acs/asm-wasm-hash-tagging:v1.22.6.2-g72656ba-aliyun 
      phase: AUTHN
      pluginConfig:
        rules:
          - header: x-user-id
            modulo: 100
            tagHeader: x-asm-prefer-tag
            policies:
              # ユーザートラフィックの 20% をレーン s2 にルーティング
              - range: 20
                tagValue: s2
              # ユーザートラフィックの 80% をレーン s1 にルーティング
              - range: 100
                tagValue: s1
  2. ASM インスタンスの kubeconfig を使用して、次のコマンドを実行し、タグ付けプラグインをデプロイします。

    kubectl apply -f wasm.yaml

ステップ 5:設定の確認

  1. 次のコマンドを実行して、イングレスゲートウェイアドレスの一時的な環境変数を設定します。

    export GATEWAY_ADDRESS=`kubectl get svc -n istio-system | grep istio-ingressgateway | awk '{print $4}'`
  2. 次のコマンドを実行して、Jason としてアプリケーションにアクセスします。

    curl ${GATEWAY_ADDRESS} -H 'x-user-id: jason'

    期待される出力:

    -> mocka(version: v1, ip: 10.0.0.15)-> mockb(version: v1, ip: 10.0.0.130)-> mockc(version: v2, ip: 10.0.0.133)%     

    リクエストは mockc アプリケーションのバージョン v2 に直接ルーティングされます。

  3. 次のコマンドを実行して、ランダムなユーザーを新しいバージョンにルーティングできます。

     for i in 'bob' 'stacy' 'jessie' 'vance' 'jack'; do curl ${GATEWAY_ADDRESS} -H "x-user-id: $i";echo "   user $i requested"; done

    期待される出力:

    -> mocka(version: v1, ip: 10.0.0.15)-> mockb(version: v1, ip: 10.0.0.130)-> mockc(version: v1, ip: 10.0.0.131)   user bob requested
    -> mocka(version: v1, ip: 10.0.0.15)-> mockb(version: v1, ip: 10.0.0.130)-> mockc(version: v1, ip: 10.0.0.131)   user stacy requested
    -> mocka(version: v1, ip: 10.0.0.15)-> mockb(version: v1, ip: 10.0.0.130)-> mockc(version: v2, ip: 10.0.0.133)   user jessie requested
    -> mocka(version: v1, ip: 10.0.0.15)-> mockb(version: v1, ip: 10.0.0.130)-> mockc(version: v1, ip: 10.0.0.131)   user vance requested
    -> mocka(version: v1, ip: 10.0.0.15)-> mockb(version: v1, ip: 10.0.0.130)-> mockc(version: v2, ip: 10.0.0.133)   user jack requested

    ユーザー Jessie と Jack からのリクエストは mockc のバージョン v2 にルーティングされ、他のユーザーからのリクエストはバージョン v1 にルーティングされます。