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

Alibaba Cloud Service Mesh:トラフィックレーンとハッシュタグプラグインを使用して、ユーザーセグメント別にカナリアリリースを実装する

最終更新日:Jan 13, 2025

Service Mesh (ASM) では、アプリケーションのバージョンまたは特定の機能を独立したランタイム環境(スイムレーンと呼ばれる)に分離できます。次に、スイムレーンのルールを設定して、ルールに一致するリクエストをアプリケーションの宛先バージョンまたは機能にルーティングできます。開発環境では、開発者はスイムレーンを設定することで安定バージョンとカナリアバージョンを分離し、ユーザーを異なるスイムレーンにルーティングできます。この場合、特定の割合のユーザーをバージョンに誘導して機能をテストし、残りのユーザーは重みベースのルーティングルールに基づいてカナリアリリースバージョンにランダムにルーティングできます。このトピックでは、スイムレーンとハッシュタグプラグインを設定して、ユーザーセグメント別にカナリアリリースを実装する方法について説明します。

前提条件

手順

この例では、 3 つのアプリケーションが作成され、呼び出しチェーンは次の図のようになります。

  • バージョン 1 の mocka。

  • バージョン 1 の mockb。

  • バージョン 1 と 2 の mockc。

この例では、アプリケーションは 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/" # mockb サービスへのリクエストを転送
            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/" # mockc サービスへのリクエストを転送
            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 という名前の Istio ゲートウェイを作成します。詳細については、「Istio ゲートウェイの管理」をご参照ください。

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: ingressgateway
  namespace: istio-system
spec:
  selector:
    istio: ingressgateway # istio ingressgateway セレクターラベル
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      hosts:
        - '*' # 全てのホストを許可

ステップ 3:レーングループとレーンを作成する

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

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

    2. [メッシュ管理] ページで、ターゲット ASM インスタンスをクリックします。左側のナビゲーションペインで、[トラフィック管理センター] > [トラフィックスイムレーン] を選択します。

    3. [トラフィックスイムレーン] ページで、[スイムレーングループの作成] をクリックします。[スイムレーングループの作成] パネルで関連設定を行い、[OK] をクリックします。

      パラメーター

      説明

      スイムレーングループの名前

      この例では、 canary と入力します。

      イングレスの種類

      [ingressgateway] を選択します。

      レーンモード

      [緩和モード] を選択します。

      トレースコンテキストのパススルーモード

      [トレース ID のパススルー] を選択します。

      トレース ID リクエストヘッダー

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

      リクエストルーティングヘッダー

      ゲートウェイがリクエストコンテンツに基づいてトラフィックを異なるレーンにルーティングし、レーンコンテキストでヘッダーをパススルーできるようにします。このパラメーターはユーザー定義です。この例では、 x-asm-prefer-tag と入力します。

      スイムレーンサービス

      Kubernetes クラスターフィールドでターゲットクラスターを選択し、ネームスペースフィールドで [default] を選択します。以下のリストから [mocka][mockb][mockc] サービスを選択し、移动 アイコンをクリックしてターゲットサービスを [選択済み] ペインに追加します。

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

    1. [トラフィックスイムレーン] ページで、[トラフィックルール定義] ペインの [スイムレーンの作成] をクリックします。

    2. [スイムレーンの作成] ダイアログボックスで、関連設定を行い、[OK] をクリックします。

      パラメーター

      説明

      スイムレーン名

      それぞれ s1 と s2 と入力します。

      サービスタグの設定

      ラベルキー: ASM_TRAFFIC_TAG を選択します。

      ラベル値: 2 つのレーンにそれぞれ v1v2 を選択します。

      サービスの追加

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

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

      次の図は、スイムレーン s1 を設定する例を示しています。

      image

      2 つのスイムレーンは次のとおりです。

      image

      説明

      デフォルトでは、レーングループで最初に作成したレーンがベースラインレーンとして機能します。このベースラインレーン内のサービスを変更できます。他のレーンに存在しないサービスにリクエストが送信されると、フォールバックメカニズムによってリクエストはベースラインレーンに転送されます。詳細については、「緩和モードでのベースラインレーンの変更」をご参照ください。

  3. スイムレーンのリクエストルーティングルールを作成します。

    1. 次の内容でスイムレーンのリクエストルーティングルールを作成します。ルールは次のとおりです。

      1. x-user-id: jason ヘッダーを含むリクエストは、スイムレーン s2 にルーティングされます。リクエストに提供される x-asm-prefer-tag: s2 ヘッダーは、リクエストがスイムレーン 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 にルーティングされます
        # リクエストに提供される x-asm-prefer-tag: s2 ヘッダーは、リクエストがスイムレーン s2 にルーティングされることを示します
        - match:
          - headers:
              x-user-id: # x-user-id ヘッダーに基づいてリクエストをマッチ
                exact: jason
            uri:
              exact: /
          name: r2
          route:
          - destination:
              host: mocka.default.svc.cluster.local
              subset: s2 # サブセット s2 にルーティング
            fallback:
              target:
                host: mocka.default.svc.cluster.local
                subset: s1 # フォールバックとしてサブセット s1 を使用する
            headers:
              request:
                set:
                  x-asm-prefer-tag: s2 # x-asm-prefer-tag ヘッダーを設定
        # ルーティングルール 2: x-asm-prefer-tag: s2 ヘッダーを含むリクエストはスイムレーン s2 にルーティングされます
        - match:
          - headers:
              x-asm-prefer-tag: # x-asm-prefer-tag ヘッダーに基づいてリクエストをマッチ
                exact: s2
            uri:
              exact: /
          name: r2
          route:
          - destination:
              host: mocka.default.svc.cluster.local
              subset: s2 # サブセット s2 にルーティング
            # mocka アプリケーションがレーン s2 に含まれていない場合、リクエストはスイムレーン s1 の mocka に転送されます
            fallback:
              target:
                host: mocka.default.svc.cluster.local
                subset: s1 # フォールバックとしてサブセット s1 を使用する
        # ルーティングルール 3: x-asm-prefer-tag: s1 ヘッダーを含むリクエストはスイムレーン s1 にルーティングされます
        - match:
          - headers:
              x-asm-prefer-tag: # x-asm-prefer-tag ヘッダーに基づいてリクエストをマッチ
                exact: s1
            uri:
              exact: /
          name: r1
          route:
          - destination:
              host: mocka.default.svc.cluster.local
              subset: s1 # サブセット 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 # 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 アプリケーションのバージョン 2 に直接ルーティングされることを示しています。

  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 アプリケーションのバージョン 2 に直接ルーティングされ、他のユーザーのリクエストはバージョン 1 にルーティングされることを示しています。