1.10. トラフィック管理

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

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

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

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

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

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

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

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

1.10.1.2.1. ホスト

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

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

spec:
  hosts:
  - reviews
1.10.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

宛先

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.10.1.2.3. 宛先ルール

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

1.10.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.10.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.10.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.10.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/*"