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

:サービスメッシュ層でクラスターをまたいでトラフィックミラーリングを使用する

最終更新日:Jan 15, 2025

トラフィックミラーリング機能を使用して、本番トラフィックをテスト クラスターまたはテスト サービス バージョンにミラーリングできます。ミラーリングされた本番トラフィックを使用したテストは、本番環境に影響を与えることなく、バージョンの変更に伴うリスクを軽減します。このトピックでは、トラフィックミラーリングとは何か、サービスメッシュ層でクラスターをまたいでこの機能を使用する方法について説明します。

トラフィックミラーリングとは

マイクロサービス アーキテクチャは、アプリケーションの開発とデプロイを高速化しますが、サービス バージョンの変更にはリスクが伴います。Service Mesh (ASM) は、リスクを軽減するためにトラフィックミラーリング機能を提供します。トラフィックシャドーイングとも呼ばれるこの機能は、本番トラフィックをリアルタイムでミラーリングされたサービスに送信します。ミラーリングされたトラフィックは、本番サービスのクリティカルなリクエスト パスの帯域外で発生します。トラフィックがミラーリングされると、ミラーリングされたサービス バージョンに送信されるリクエストの Host/Authority ヘッダーに -shadow が追加されます。これにより、本番トラフィックとミラーリングされたトラフィックが区別されます。この機能を使用して、クラスターまたはサービス バージョンが本番環境で実行される前に、本番トラフィックをテスト クラスターまたはテスト サービス バージョンにミラーリングできます。これにより、バージョンの変更に伴うリスクが軽減されます。

利点

利点

説明

本番環境に近いテスト環境でのリスクの少ないバージョンのデプロイ

本番トラフィックをテスト クラスターまたはテスト サービス バージョンにコピーし、ミラーリングされたユースケースとトラフィックを使用してテストを実行できます。より正確なテスト結果により、本番環境でのデプロイのリスクが軽減されます。

本番環境への影響なし

  • ミラーリングされたトラフィックは、本番サービスのクリティカルなリクエスト パスの帯域外で発生します。ミラーリングされたトラフィックによって発生した問題は、本番環境には影響しません。

  • リクエストは「送信して忘れる」ようにミラーリングされます。つまり、レスポンスは破棄されます。

シナリオ

トラフィックミラーリングを使用すると、エンドユーザーに影響を与えることなく、本番環境で実行されているサービスをテストできます。2 つのバージョンのサービスのベンチマーク テストを実行して、新しいバージョンが既存のバージョンと同じ方法で受信リクエストを処理できるかどうかを判断できます。

次の表に、トラフィックミラーリングを使用できる典型的なシナリオを示します。

シナリオ

説明

試運転とシミュレーション テストのための本番トラフィック ミラーリング

テストのために、本番クラスターからテスト クラスターにトラフィックをミラーリングできます。これは、本番環境のクリティカルなリクエスト パスには影響しません。古いシステムを新しいシステムに置き換えたり、変換したりするとします。試運転のために、古いシステムの本番トラフィックをミラーリングして新しいシステムにインポートできます。実験的なアーキテクチャ調整を実行する場合は、シミュレーション テストのために本番トラフィックをミラーリングすることもできます。

新しいバージョンの検証

本番トラフィックとミラーリングされたトラフィックの出力結果をリアルタイムで比較できます。新しいサービスをリリースする前に、ミラーリングされたトラフィックをドリルで使用できます。すべての本番トラフィックをミラーリングできます。従来の手動ドリルは、サンプル データに基づいて実行されます。(サービスが本番トラフィックにどのように応答するかを予測することは困難です。) ミラーリングされた本番トラフィックを使用すると、悪意のある攻撃を受ける例外的な特殊文字やトークンなど、本番環境のすべての状況をシミュレートできます。これにより、リリースされるサービスの処理能力とトラブルシューティング能力を理解するのに役立ちます。

データベース データとテスト データの分離

データ処理パフォーマンスをテストする場合は、テスト データを空のデータベースにインポートし、本番トラフィックをこのテスト データベースにミラーリングできます。これにより、テスト データが本番データベースのデータから分離されます。

実行中のサービスのトラブルシューティング

実行中のサービスに予期しない問題が発生した場合、オンプレミス ネットワークで問題を再現することは困難です。この場合、一時的なサービスを開始し、実行中のサービスから一時的なサービスにトラフィックをミラーリングしてデバッグできます。このトラブルシューティング方法は、実行中のサービスには影響しません。

ユーザー行動のログ記録

サンプルとデータは、レコメンデーション システム アルゴリズムにとって重要です。アルゴリズム依存アプリケーションの従来の自動テストの最大の課題は、現実世界のユーザー行動データの不足です。トラフィックミラーリングを使用すると、ユーザー行動データをログに保存できます。ログ データは、レコメンデーション システム アルゴリズムを構築するためのシミュレーション テストで使用できます。また、ユーザー プロファイル分析のためのビッグ データ ソースとしても使用できます。

トラフィックミラーリングを使用するためのサンプル コード

次の YAML ファイルの例は、Istio でトラフィックミラーリングを使用する方法を示しています。この例では、VirtualService はすべてのトラフィックを v1 サブセットにルーティングし、トラフィックを v1-mirroring サブセットにミラーリングします。リクエストが v1 サブセットに送信されると、リクエストがコピーされ、v1-mirroring サブセットに送信されます。

v1-mirroring サブセットがアプリケーションの v1 バージョンにリクエストを送信した後、アプリケーション ログを表示できます。アプリケーションが呼び出されると、レスポンスは v1 サブセットからのものであることがわかります。また、リクエストが v1-mirroring サブセットにミラーリングされていることもわかります。

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: myapp-traffic-mirroring
spec:
  hosts:
    - myapp
  http:
    - route:
        - destination:
            host: myapp.default.svc.cluster.local
            port:
              number: 8000
            subset: v1
          weight: 100
      mirror:
        host: myapp.default.svc.cluster.local
        port:
          number: 8000
        subset: v1-mirroring

クラスターをまたいでトラフィックミラーリングを有効にする

サービスメッシュ層でのトラフィックミラーリングは、主に、本番トラフィックをリリースされる環境にミラーリングする必要があるシナリオで使用されます。したがって、クロス クラスター トラフィック ミラーリングは一般的です。この例では、クラスター A は本番環境、クラスター B はテスト環境です。リクエストはクラスター A に送信され、クラスター A のイングレス ゲートウェイはトラフィックをクラスター B にミラーリングします。基于集群内服务层使用流量镜像

手順 1: クラスター B にサンプル アプリケーション サービスをデプロイする

  1. 次の内容を含む httpbin.yaml ファイルを作成します。

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: httpbin
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: httpbin
      labels:
        app: httpbin
        service: httpbin
    spec:
      ports:
      - name: http
        port: 8000
        targetPort: 80
      selector:
        app: httpbin
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: httpbin-v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: httpbin
          version: v1
      template:
        metadata:
          labels:
            app: httpbin
            version: v1
        spec:
          serviceAccountName: httpbin
          containers:
          - image: docker.io/kennethreitz/httpbin
            imagePullPolicy: IfNotPresent
            name: httpbin
            ports:
            - containerPort: 80
    ---
  2. 次のコマンドを実行して、v1 バージョンの httpbin アプリケーション サービスをデプロイします。

    kubectl apply -f httpbin.yaml

手順 2: クラスター B のイングレス ゲートウェイのルーティング ルールを構成する

  1. 次の内容を含む httpbin-gateway.yaml ファイルを作成します。

    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
      name: httpbin-gateway
    spec:
      selector:
        istio: ingressgateway
      servers:
      - port:
          number: 80
          name: http
          protocol: HTTP
        hosts:
        - "*"
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: httpbin
    spec:
      hosts:
      - "*"
      gateways:
      - httpbin-gateway
      http:
      - match:
        - uri:
            prefix: /headers
        route:
        - destination:
            host: httpbin
            port:
              number: 8000
  2. 次のコマンドを実行して、ルーティング ルールをデプロイします。

    kubectl apply -f httpbin-gateway.yaml
  3. 次のコマンドを実行して、クラスター B のイングレス ゲートウェイにアクセスし、サービスが期待どおりに動作するかどうかを確認します。

    curl http://{クラスター B のイングレス ゲートウェイの IP アドレス}/headers

    出力例:

    {
      "headers": {
        "Accept": "*/*",
        "Host": "47.99.XX.XX",
        "User-Agent": "curl/7.79.1",
        "X-Envoy-Attempt-Count": "1",
        "X-Envoy-External-Address": "120.244.XXX.XXX",
        "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/default/sa/httpbin;Hash=158e4ef69876550c34d10e3bfbd8d43f5ab481b16ba0e90b4e38a2d53ac****;Subject=\"\";URI=spiffe://cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account"
      }
    }

    上記の結果が返された場合、サービスは期待どおりに動作しています。

手順 3: クラスター A のサービスメッシュで外部アクセス ルールを構成する

ミラーリングされたサービスのホストは、外部ドメイン名を使用します。ホストの DNS 解決方法を指定するために、サービス エントリを作成する必要があります。

  1. 次の内容を含む httpbin-cluster-b.yaml ファイルを作成します。

    apiVersion: networking.istio.io/v1alpha3
    kind: ServiceEntry
    metadata:
      name: httpbin-cluster-b
    spec:
      hosts:
      - httpbin.mirror.cluster-b
      location: MESH_EXTERNAL
      ports:
      - number: 80   # クラスター B のイングレス ゲートウェイのポートを指定します。
        name: http
        protocol: HTTP
      resolution: STATIC
      endpoints:
      - address: 47.95.XX.XX # クラスター B のイングレス ゲートウェイの IP アドレスを指定します。
  2. 次のコマンドを実行して、サービス エントリを作成します。

    kubectl apply -f httpbin-cluster-b.yaml
  3. 次の内容を含む httpbin-gateway.yaml ファイルを作成します。

    YAML 構成は、すべてのトラフィックをクラスター A の httpbin サービスの v1 バージョンにルーティングし、トラフィックをクラスター B の httpbin サービスにミラーリングします。httpbin.mirror.cluster-b は、外部サービスにアクセスするために使用されるアドレスです。

    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
      name: httpbin-gateway
    spec:
      selector:
        istio: ingressgateway
      servers:
      - port:
          number: 80
          name: http
          protocol: HTTP
        hosts:
        - "*"
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: httpbin
    spec:
      gateways:
        - httpbin-gateway
      hosts:
        - '*'
      http:
        - match:
            - uri:
                prefix: /headers
          mirror:
            host: httpbin.mirror.cluster-b
            port:
              number: 80
          mirrorPercentage:
            value: 50
          route:
            - destination:
                host: httpbin
                port:
                  number: 8000
                subset: v1

    注: httpbin.mirror.cluster-b 宛てのトラフィックは、元の宛先へのトラフィックと同じです。唯一の違いは、Host/Authority ヘッダーに -shadow が追加されていることです。上記の YAML 構成では、ミラーリングされたトラフィックの Host/Authority ヘッダーは httpbin.mirror.cluster-b ではなく、-shadow サフィックスが付いた元の要求ヘッダーです。mirror セクションの host フィールドは、トラフィックの転送先アドレスを見つけるためだけに使用され、元の Host ヘッダーは変更しません。

  4. 次のコマンドを実行して、ルーティング ルールをデプロイします。

    kubectl apply -f httpbin-gateway.yaml
  5. クラスター A のイングレス ゲートウェイ ポッドの Envoy config dump を表示します。

    "routes": [
             {
              "match": {
               "prefix": "/headers",
               "case_sensitive": true
              },
              "route": {
               "cluster": "outbound|8000|v1|httpbin.default.svc.cluster.local",
               "timeout": "0s",
               "retry_policy": {
                "retry_on": "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes",
                "num_retries": 2,
                "retry_host_predicate": [
                 {
                  "name": "envoy.retry_host_predicates.previous_hosts",
                  "typed_config": {
                   "@type": "type.googleapis.com/envoy.extensions.retry.host.previous_hosts.v3.PreviousHostsPredicate"
                  }
                 }
                ],
                "host_selection_retry_max_attempts": "5",
                "retriable_status_codes": [
                 503
                ]
               },
               "request_mirror_policies": [
                {
                 "cluster": "outbound|80||httpbin.mirror.cluster-b",
                 "runtime_fraction": {
                  "default_value": {
                   "numerator": 500000,
                   "denominator": "MILLION"
                  }
                 },
                 "trace_sampled": false
                }
               ],

    上記のサンプル コードでは、request_mirror_policies フィールドはリクエスト トラフィック ミラーリングのポリシーを指定し、cluster フィールドはミラーリングされたトラフィックの送信先サービスを指定し、runtime_fraction フィールドはミラーリングされるトラフィックの比率を指定します。numerator フィールドは 500000 に設定され、denominator フィールドは MILLION に設定されており、これは 50% を示します。