1.13. トラフィック管理

Red Hat OpenShift Service Mesh のサービス間のトラフィックのフローおよび API 呼び出しを制御できます。たとえば、サービスメッシュの一部のサービスはメッシュ内で通信する必要があり、他のサービスは非表示にする必要がある場合があります。トラフィックを管理して、特定のバックエンドサービスを非表示にし、サービスを公開し、テストまたはバージョン管理デプロイメントを作成し、または一連のサービスのセキュリティーの層を追加します。

本書では Bookinfo サンプルアプリケーションを参照して、サンプルアプリケーションでのルーティングの例を説明します。Bookinfo アプリケーション をインストールして、これらのルーティングのサンプルがどのように機能するかを確認します。

1.13.1. トラフィックのルーティングおよび管理

YAML ファイルのカスタムリソース定義を使用して、独自のトラフィック設定を Red Hat OpenShift Service Mesh に追加してサービスメッシュを設定します。

1.13.1.1. 仮想サービスの使用によるトラフィック管理

仮想サービスを使用して、Red Hat OpenShift Service Mesh で複数バージョンのマイクロサービスに要求を動的にルーティングできます。仮想サービスを使用すると、以下が可能になります。

  • 単一の仮想サービスで複数のアプリケーションサービスに対応する。メッシュが Kubernetes を使用する場合などに、仮想サービスを特定の namespace のすべてのサービスを処理するように設定できます。単一の仮想サービスを数多くのサービスにマッピングすることは、モノリシックなアプリケーションの、別個のマイクロサービスから構築される複合サービスへの移行を容易にするために役立ちます。この際、サービスのコンシューマーには移行に伴う適応が必要となりません。
  • ingress および egress トラフィックを制御できるようにゲートウェイと組み合わせてトラフィックルールを設定する。
1.13.1.1.1. 仮想サービスの設定

要求は、仮想サービスを使用してサービスメッシュ内のサービスにルーティングされます。それぞれの仮想サービスは、順番に評価される一連のルーティングルールで構成されます。Red Hat OpenShift Service Mesh は、仮想サービスへのそれぞれの指定された要求をメッシュ内の特定の実際の宛先に一致させます。

仮想サービスがない場合、Red Hat OpenShift Service Mesh はすべてのサービスインスタンス間のラウンドロビン負荷分散を使用してトラフィックを分散します。仮想サービスを使用すると、1 つ以上のホスト名のトラフィック動作を指定できます。仮想サービスのルーティングルールでは、仮想サービスのトラフィックを適切な宛先に送信する方法を Red Hat OpenShift Service Mesh に指示します。ルートの宛先は、同じサービスのバージョンまたは全く異なるサービスにすることができます。

以下の例では、どのユーザーがアプリケーションに接続するかに応じて、異なるバージョンのサービスに要求をルーティングします。このコマンドを使用して、このサンプル YAML ファイル、または各自が作成する YAML ファイルを適用します。

$ oc apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v3
EOF

1.13.1.2. 仮想ホストの設定

以下のセクションでは、YAML ファイルの各フィールド、および仮想サービスで仮想ホストを作成する方法について説明します。

1.13.1.2.1. ホスト

hosts フィールドには、これらのルーティングルールが適用される仮想サービスのユーザーのアドレス指定可能な宛先が一覧表示されます。これは、要求をサービスに送信する際にクライアントが使用する 1 つ以上のアドレスです。

仮想サービスのホスト名は、IP アドレス、DNS 名、またはプラットフォームによっては、完全修飾ドメイン名に解決される短縮名になります。

spec:
  hosts:
  - reviews
1.13.1.2.2. ルーティングルール

http セクションには、ホストフィールドで指定された宛先に送信される HTTP/1.1、HTTP2、および gRPC トラフィックのルーティングの一致条件とアクションを記述する仮想サービスのルーティングルールが含まれます。ルーティングルールは、トラフィックの宛先と、ユースケースに応じてゼロまたは 1 つ以上の一致条件で構成されます。

一致条件

この例の最初のルーティングルールには条件があり、match フィールドで始まります。この例では、このルーティングはユーザー jason からの要求すべてに適用されます。headersend-user、および exact フィールドを追加し、適切な要求を選択します。

spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
      end-user:
        exact: jason

Destination

route セクションの destination フィールドは、この条件に一致するトラフィックの実際の宛先を指定します。仮想サービスのホストとは異なり、宛先のホストは Red Hat OpenShift Service Mesh サービスレジストリーに存在する実際の宛先でなければなりません。これは、プロキシーが含まれるメッシュサービス、またはサービスエントリーを使用して追加されたメッシュ以外のサービスである可能性があります。この例では、ホスト名は Kubernetes サービス名です。

spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
      end-user:
        exact: jason
    route:
    - destination:
      host: reviews
      subset: v2
1.13.1.2.3. 宛先ルール

宛先ルールは仮想サービスのルーティングルールが評価された後に適用されるため、それらはトラフィックの実際の宛先に適用されます。仮想サービスはトラフィックを宛先にルーティングします。宛先ルールでは、その宛先のトラフィックに生じる内容を設定します。

1.13.1.2.3.1. 負荷分散オプション

デフォルトで、Red Hat OpenShift Service Mesh はラウンドロビンの負荷分散ポリシーを使用します。このポリシーでは、インスタンスプールの各サービスインスタンスが順番に要求を取得します。Red Hat OpenShift Service Mesh は以下のモデルもサポートします。このモデルは、特定のサービスまたはサービスサブセットへの要求の宛先ルールに指定できます。

  • Random: 要求はプール内のインスタンスにランダムに転送されます。
  • Weighted: 要求は特定のパーセンテージに応じてプールのインスタンスに転送されます。
  • Least requests: 要求は要求の数が最も少ないインスタンスに転送されます。

宛先ルールの例

以下の宛先ルールの例では、異なる負荷分散ポリシーで my-svc 宛先サービスに 3 つの異なるサブセットを設定します。

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: my-destination-rule
spec:
  host: my-svc
  trafficPolicy:
    loadBalancer:
      simple: RANDOM
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
    trafficPolicy:
      loadBalancer:
        simple: ROUND_ROBIN
  - name: v3
    labels:
      version: v3
1.13.1.2.4. ゲートウェイ

ゲートウェイを使用してメッシュの受信トラフィックおよび送信トラフィックを管理することで、メッシュに入るか、またはメッシュを出るトラフィックを指定できます。ゲートウェイ設定は、サービスワークロードと共に実行されるサイドカー Envoy プロキシーではなく、メッシュのエッジで実行されているスタンドアロンの Envoy プロキシーに適用されます。

Kubernetes Ingress API などのシステムに入るトラフィックを制御する他のメカニズムとは異なり、Red Hat OpenShift Service Mesh ゲートウェイではトラフィックのルーティングの機能および柔軟性を最大限に利用できます。Red Hat OpenShift Service Mesh ゲートウェイリソースは、公開するポート、Red Hat OpenShift Service Mesh TLS 設定などの 4-6 の負荷分散プロパティーを階層化できます。アプリケーション層のトラフィックルーティング (L7) を同じ API リソースに追加する代わりに、通常の Red Hat OpenShift Service Mesh 仮想サービスをゲートウェイにバインドし、サービスメッシュ内の他のデータプレーントラフィックのようにゲートウェイトラフィックを管理することができます。

ゲートウェイは ingress トラフィックの管理に主に使用されますが、egress ゲートウェイを設定することもできます。egress ゲートウェイを使用すると、メッシュから出るトラフィックの専用の出口ノードを設定し、外部ネットワークにアクセスできるサービスを制限したり、egress トラフィックのセキュアな制御を有効にしてメッシュにセキュリティーを追加することなどが可能になります。また、ゲートウェイを使用して完全に内部のプロキシーを設定することもできます。

ゲートウェイの例

以下の例は、外部 HTTPS Ingress トラフィックの予想されるゲートウェイ設定を示しています。

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: ext-host-gwy
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
    number: 443
    name: https
    protocol: HTTPS
    hosts:
    - ext-host.example.com
    tls:
      mode: SIMPLE
      serverCertificate: /tmp/tls.crt
      privateKey: /tmp/tls.key

このゲートウェイ設定により、ポート 443 での ext-host.example.com からメッシュへの HTTPS トラフィックが可能になりますが、トラフィックのルーティングは指定されません。

ルーティングを指定し、ゲートウェイが意図される通りに機能するには、ゲートウェイを仮想サービスにバインドする必要もあります。これは、以下の例のように、仮想サービスのゲートウェイフィールドを使用して実行します。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: virtual-svc
spec:
  hosts:
  - ext-host.example.com
  gateways:
    - ext-host-gwy

次に、仮想サービスを外部トラフィックのルーティングルールを使用して設定できます。

1.13.1.2.5. サービスエントリー

サービスエントリーは、Red Hat OpenShift Service Mesh が内部で維持するサービスレジストリーにエントリーを追加します。サービスエントリーの追加後、Envoy プロキシーはメッシュ内のサービスであるかのようにトラフィックをサービスに送信できます。サービスエントリーを設定すると、(以下のタスクを含め) メッシュの外部で実行されているサービスのトラフィックを管理できます。

  • Web から消費される API やレガシーインフラストラクチャーのサービスへのトラフィックなど、外部宛先のトラフィックをリダイレクトし、転送します。
  • 外部宛先の再試行、タイムアウト、およびフォールトインジェクションポリシーを定義します。
  • 仮想マシンをメッシュに追加して、仮想マシン (VM) でメッシュサービスを実行します。
  • 別のクラスターからメッシュにサービスを論理的に追加し、Kubernetes でマルチクラスター Red Hat OpenShift Service Mesh メッシュを設定します。
  • メッシュサービスが使用するすべての外部サービスのサービスエントリーを追加する必要はありません。Red Hat OpenShift Service Mesh はデフォルトで、Envoy プロキシーを不明なサービスへの要求をパススルーするように設定します。ただし、Red Hat OpenShift Service Mesh 機能を使用して、メッシュに登録されていない宛先へのトラフィックを制御することはできません。

サービスエントリーの例

以下の mesh-external サービスエントリーの例では、 ext-resource の外部依存関係を Red Hat OpenShift Service Mesh サービスレジストリーに追加します。

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: svc-entry
spec:
  hosts:
  - ext-svc.example.com
  ports:
  - number: 443
    name: https
    protocol: HTTPS
  location: MESH_EXTERNAL
  resolution: DNS

hosts フィールドを使用して外部リソースを指定します。これを完全に修飾することも、ワイルドカードのプレフィックスが付けられたドメイン名を使用することもできます。

仮想サービスおよび宛先ルールを設定して、メッシュ内の他のサービスのトラフィックを設定するのと同じように、サービスエントリーへのトラフィックを制御できます。たとえば、以下の宛先ルールでは、トラフィックルートを、サービスエントリーを使用して設定される ext-svc.example.com 外部サービスへの接続のセキュリティーを保護するために相互 TLS を使用するように設定します。

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: ext-res-dr
spec:
  host: ext-svc.example.com
  trafficPolicy:
    tls:
      mode: MUTUAL
      clientCertificate: /etc/certs/myclientcert.pem
      privateKey: /etc/certs/client_private_key.pem
      caCertificates: /etc/certs/rootcacerts.pem
1.13.1.2.6. サイドカー

デフォルトで、Red Hat OpenShift Service Mesh は、すべての Envoy プロキシーを、トラフィックの転送時にすべてのポートで関連付けられたワークロードについてのトラフィックを受け入れ、メッシュ内のすべてのワークロードに到達するように設定します。サイドカー設定を使用して以下を実行できます。

  • Envoy プロキシーが受け入れるポートとプロトコルのセットを微調整します。
  • Envoy プロキシーが到達できるサービスのセットを制限します。
  • より大規模なアプリケーションではこのようなサイドカーの到達可能性を制限する必要がある場合があります。この場合、すべてのプロキシーがメッシュ内の他のすべてのサービスに到達するように設定されると、メモリー使用率が高くなるためにメッシュのパフォーマンスに影響する可能性があります。

サイドカーの例

サイドカー設定を特定の namespace のすべてのワークロードに適用するように指定するか、または workloadsSelector を使用して特定のワークロードを選択することができます。たとえば、以下のサイドカー設定では bookinfo namespace 内のすべてのサービスを、同じ namespace および Red Hat OpenShift Service Mesh コントロールプレーン(現時点では Red Hat OpenShift Service Mesh ポリシーおよび Telemetry 機能を使用するために必要) で実行されるサービスのみに到達するように設定します。

apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
  name: default
  namespace: bookinfo
spec:
  egress:
  - hosts:
    - "./*"
    - "istio-system/*"

1.13.2. Ingress トラフィックの管理

Red Hat OpenShift Service Mesh では、Ingress Gateway は、モニタリング、セキュリティー、ルートルールなどのサービスメッシュ機能をクラスターに入るトラフィックに適用できるようにします。サービスメッシュを、サービスメッシュゲートウェイを使用してサービスメッシュ外のサービスを公開するように設定します。

1.13.2.1. Ingress IP およびポートの判別

以下のコマンドを実行して、Kubernetes クラスターが外部ロードバランサーをサポートする環境で実行されているかどうかを判別します。

$ oc get svc istio-ingressgateway -n istio-system

このコマンドは、namespace のそれぞれの項目の NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)、および AGE を返します。

EXTERNAL-IP 値が設定されている場合には、環境には Ingress ゲートウェイに使用できる外部ロードバランサーがあります。

EXTERNAL-IP の値が <none> または永続的に <pending> の場合、環境は Ingress ゲートウェイの外部ロードバランサーを提供しません。サービスの ノードポート を使用してゲートウェイにアクセスできます。

環境の手順を選択します。

ロードバランサーを使用したルーティングの設定

お使いの環境に外部ロードバランサーがある場合には、以下の手順に従います。

Ingress IP およびポートを設定します。

$ export INGRESS_HOST=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
$ export INGRESS_PORT=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
$ export SECURE_INGRESS_PORT=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].port}')

一部の環境では、ロードバランサーは IP アドレスの代わりにホスト名を使用して公開される場合があります。この場合、Ingress ゲートウェイの EXTERNAL-IP 値は IP アドレスではありません。これはホスト名であり、直前のコマンドは INGRESS_HOST 環境変数の設定に失敗します。

以下のコマンドを使用して INGRESS_HOST 値を修正します。

$ export INGRESS_HOST=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')

ロードバランサーを使用しないルーティングの設定

お使いの環境に外部のロードバランサーがない場合は、以下の手順に従います。ノードポートを代わりに使用する必要があります。

Ingress ポートを設定します。

$ export INGRESS_PORT=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
$ export SECURE_INGRESS_PORT=$(oc -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')

1.13.3. Bookinfo アプリケーションを使用したルーティングの例

Service Mesh Bookinfo サンプルアプリケーションは、それぞれが複数のバージョンを持つ 4 つの別個のマイクロサービスで構成されます。3 つの異なるバージョン (マイクロサービスの 1 つは reviews と呼ばれる) はデプロイされており、同時に実行されます。

前提条件:

  • 以下の例に合わせて Bookinfo サンプルアプリケーションをデプロイします。

このタスクについて

これによって生じる問題を確認するには、ブラウザーで bookinfo アプリの /product page にアクセスし、複数回更新を実行します。

書評の出力に星評価が含まれる場合や、含まれない場合があります。ルーティング先の明示的なデフォルトサービスバージョンがない場合、サービスメッシュは、利用可能なすべてのバージョンに要求をルーティングしていきます。

このチュートリアルは、すべてのトラフィックをマイクロサービスの v1 (バージョン 1) にルーティングするルールを適用するのに役立ちます。後に、HTTP 要求ヘッダーの値に基づいてトラフィックをルーティングするためのルールを適用できます。

1.13.3.1. 仮想サービスの適用

1 つのバージョンにのみルーティングするには、マイクるサービスのデフォルトバージョンを設定する仮想サービスを適用します。以下の例では、仮想サービスはすべてのトラフィックを各マイクロサービスの v1 にルーティングします。

  1. 以下のコマンドを実行して仮想サービスを適用します。

    $ oc apply -f https://raw.githubusercontent.com/Maistra/istio/maistra-1.1/samples/bookinfo/networking/virtual-service-all-v1.yaml
  2. コマンドが正常に実行されることをテストするには、以下のコマンドで定義されたルートを表示します。

    $ oc get virtualservices -o yaml

    このコマンドは以下の YAML ファイルを返します。

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: details
      ...
    spec:
      hosts:
      - details
      http:
      - route:
        - destination:
          host: details
          subset: v1
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: productpage
      ...
    spec:
      gateways:
      - bookinfo-gateway
      - mesh
      hosts:
      - productpage
      http:
      - route:
        - destination:
          host: productpage
          subset: v1
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: ratings
      ...
    spec:
      hosts:
      - ratings
      http:
      - route:
        - destination:
          host: ratings
          subset: v1
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: reviews
      ...
    spec:
      hosts:
      - reviews
      http:
      - route:
        - destination:
          host: reviews
          subset: v1

    サービスメッシュを Bookinfo マイクロサービスの v1 バージョン (最も重要な点として reviews サービスバージョン 1) にルーティングするように設定しています。

1.13.3.2. 新規ルーティング設定のテスト

Bookinfo アプリケーションの /productpage を再度更新すると、新しい設定を簡単にテストできます。

  1. ブラウザーで Bookinfo サイトを開きます。URL は http://$GATEWAY_URL/productpage です。ここで、$GATEWAY_URL は Ingress の外部 IP アドレスです。

    更新回数に関係なく、ページのレビュー部分は星評価なしに表示されます。これは、サービスメッシュを、reviews サービスのすべてのトラフィックをバージョン reviews:v1 にルーティングするように設定しているためであり、サービスのこのバージョンは星評価サービスにアクセスしません。

    サービスメッシュは、トラフィックを 1 つのバージョンのサービスにルーティングするようになりました。

1.13.3.3. ユーザーアイデンティティーに基づくルート

次に、ルート設定を変更して、特定のユーザーからのトラフィックすべてが特定のサービスバージョンにルーティングされるようにします。この場合、jason という名前のユーザーからのトラフィックはすべて、サービス reviews:v2 にルーティングされます。

サービスメッシュには、ユーザーアイデンティティーについての特別な組み込み情報がないことに注意してください。この例は、productpage サービスが reviews サービスへのすべてのアウトバウンド HTTP 要求にカスタム end-user ヘッダーを追加することで有効にされます。

  1. 以下のコマンドを実行してユーザーベースのルーティングを有効にします。

    $ oc apply -f https://raw.githubusercontent.com/Maistra/istio/maistra-1.1/samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
  2. ルールが作成されていることを確認します。

    $ oc get virtualservice reviews -o yaml

    このコマンドは以下の YAML ファイルを返します。

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: reviews
      ...
    spec:
      hosts:
      - reviews
      http:
      - match:
        - headers:
          end-user:
            exact: jason
        route:
        - destination:
          host: reviews
          subset: v2
      - route:
        - destination:
          host: reviews
          subset: v1
  3. Bookinfo アプリケーションの /productpage で、ユーザー jason としてログインします。ブラウザーを更新します。表示内容を確認してください。各レビューの横に星評価が表示されます。
  4. 別のユーザーとしてログインします(任意の名前を指定します)。ブラウザーを更新します。これで星がなくなりました。これは、Jason 以外のすべてのユーザーについてトラフィックが reviews:v1 にルーティングされるためです。

ユーザーアイデンティティーに基づいてトラフィックをルーティングするようにサービスメッシュが正常に設定されています。