訳しながら理解していくIstio_Traffic Management編

# はじめに
Istioのドキュメントって英語だし、英検3級レベルで英語力のない私にはつらい・・・
そして、一回(google翻訳を使って)訳しながら読んでまた忘れてまた(google翻訳を使って)訳すを繰り返すのをやめたい。
調べるときは全文を見ずに、必要な部分だけを見てたりするので、公式ドキュメントを訳しながら全体を理解していこうと思う。

英語読むのめんどくせーーーとなっている人の助けになればと思い公開した

今回は [Traffic Management](https://istio.io/docs/concepts/traffic-management/)


## 注意事項
* 基本的にGoogle翻訳のまんまです。
* 一応、意味が分かるようには訳してるつもりですが、ちょいちょい意味分からない部分もあります。  
誤訳がある可能性があるので、最後はちゃんと公式ドキュメントを読みましょう
* 私の知りたい部分からやるので、訳す部分はバラバラになります。
* 公式ドキュメントに記載されていない部分(自分で調べた部分とか)は_italic_で記載しています。
* 1.0でのドキュメントを記載

## Traffic Management
このページでは、トラフィック管理の原則を含め、Istioでのトラフィック管理の仕組みの概要を説明します。それはあなたがすでに[What is Istio?](https://istio.io/docs/concepts/what-is-istio/)を読んだこと、Istioの高水準アーキテクチャに精通していることを前提としています。

Istioのトラフィック管理モデルを使用すると、トラフィックフローとインフラストラクチャのスケーリングが基本的に切り離され、Pilot経由で特定のPods/VMsがトラフィックを受信するのではなく、トラフィックに従うルールを指定できるようになります。PilotとインテリジェントなEnvoyプロキシは残りの部分を見てください。たとえば、特定のサービスのトラフィックの5％をカナリーデプロイメントのサイズに関係なくカナリーバージョンに移動したり、要求の内容に応じて特定のバージョンにトラフィックを送信したりすることをPilot経由で指定できます。

![スクリーンショット 2018-08-05 21.42.14.png](https://qiita-image-store.s3.amazonaws.com/0/33101/56804a70-f6c8-da4c-a14a-f694fc09215a.png)

トラフィックフローをインフラストラクチャのスケールから切り離すことで、Istioはアプリケーションコード外に存在するさまざまなトラフィック管理機能を提供できます。A/Bテスト、段階的なロールアウト、およびカナリー・リリースの動的[リクエスト・ルーティング](https://istio.io/docs/concepts/traffic-management/#request-routing)だけでなく、タイムアウト、再試行、サーキット・ブレーカ、および[障害インジェクション](https://istio.io/docs/concepts/traffic-management/#fault-injection)を使用した[障害回復](https://istio.io/docs/concepts/traffic-management/#handling-failures)も処理し、サービス間の障害回復ポリシーの互換性をテストします。これらの機能はすべて、サービスメッシュ全体に配備されたEnvoyサイドカー/プロキシを通じて実現されます。

## Pilot and Envoy
Istioのトラフィック管理に使用されるコアコンポーネントは、特定のIstioサービスメッシュに配置されたすべてのEnvoyプロキシインスタンスを管理および設定する**Pilot**です。Pilotでは、Envoyプロキシ間でトラフィックをルーティングし、タイムアウト、再試行、サーキットブレーカーなどの障害回復機能を構成するために使用するルールを指定できます。また、メッシュ内のすべてのサービスの標準モデルを維持し、このモデルを使用してEnvoyインスタンスに検出サービスを介してメッシュ内の他のEnvoyインスタンスを知らせる。

各Envoyインスタンスは、パイロットから取得した情報に基づいて[ロードバランシング情報](https://istio.io/docs/concepts/traffic-management/#discovery-and-load-balancing)を維持し、ロードバランシングプール内の他のインスタンスの定期的なヘルスチェックを実行して、指定されたルーティングルールに従い宛先インスタンス間でトラフィックをインテリジェントに配信します。

Pilotは、Istioサービスメッシュに配置されたEnvoyインスタンスのライフサイクルを担当します。

<img width="1243" alt="スクリーンショット 2018-08-06 12.42.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/33101/b885fc77-e624-8a0c-8a91-90e52fe79a3c.png">

上記の図に示すように、Pilotは、基本プラットフォームとは独立したメッシュ内のサービスの標準的な表現を維持します。Pilotのプラットフォーム固有のアダプタは、この標準モデルを適切に配置する責任があります。たとえば、PilotのKubernetesアダプタは、必要なコントローラを実装して、ポッド登録情報、Ingressリソース、およびトラフィック管理ルールを格納するサードパーティのリソースの変更についてKubernetes APIサーバーを監視します。このデータは正準表現(canonical representation)に変換されます。Envoy固有の構成は、正準表現(canonical representation)に基づいて生成されます。

Pilotを使用すると、[service discovery](https://www.envoyproxy.io/docs/envoy/latest/api-v1/cluster_manager/sds)、[load balancing pools](https://www.envoyproxy.io/docs/envoy/latest/configuration/cluster_manager/cds)および[routing tables](https://www.envoyproxy.io/docs/envoy/latest/configuration/http_conn_man/rds)の動的更新が可能になります。

[パイロットのルール設定](https://istio.io/docs/reference/config/istio.networking.v1alpha3/)を使用して、高度なトラフィック管理ルールを指定できます。これらのルールは、低レベルの設定に変換され、Envoyインスタンスに配布されます。

## Request routing
上述したように、メッシュ内のサービスの正準表現はパイロットによって維持される。サービスのIstioモデルは、基礎となるプラットフォーム（Kubernetes、Mesos、Cloud Foundryなど）で表現される方法とは独立しています。プラットフォーム固有のアダプターは、プラットフォーム内のメタデータからさまざまなフィールドを使用して内部モデル表現を生成します。

Istioは、バージョン（v1、v2）または環境（staging,prod）によってサービスインスタンスを細分化する、`service version`の概念を導入しています。これらのバリアントは必ずしも異なるAPIバージョンである必要はなく、同じサービスへの反復的な変更、異なる環境（prod、staging、devなど）での展開が可能です。これが使用される一般的なシナリオには、A/Bテストまたはカナリアロールアウトが含まれます。Istioの[トラフィックルーティングルール](https://istio.io/docs/concepts/traffic-management/#rule-configuration)はサービスバージョンを参照して、サービス間のトラフィックをさらに制御できます。

### Communication between services
<img width="922" alt="スクリーンショット 2018-08-06 22.48.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/33101/ac3d1537-e68e-48f0-6176-30f3c597197a.png">

上記の図に示されているように、サービスのクライアントは、サービスの異なるバージョンを認識していません。サービスのホスト名/IPアドレスを使用して、サービスに引き続きアクセスできます。Envoyサイドカー/プロキシは、クライアントとサービス間のすべての要求/応答を傍受して転送します。

Envoyは、Pilotを使用して指定したルーティングルールに基づいて、サービスバージョンの実際の選択を動的に決定します。このモデルにより、アプリケーションコードは依存サービスの進化から切り離すことができますが、他のメリットもあります（「[Mixer](https://istio.io/docs/concepts/policies-and-telemetry/)」を参照）。ルーティングルールにより、Envoyはヘッダー、source/destinationに関連付けられたタグ、and/or 各バージョンに割り当てられた重みなどの条件に基づいてバージョンを選択できます。

Istioは同じサービスバージョンの複数のインスタンスへのトラフィックのロードバランシングも提供します。詳細については、「[検出と負荷分散](https://istio.io/docs/concepts/traffic-management/#discovery-and-load-balancing)」を参照してください。

IstioはDNSを提供しません。アプリケーションは、基盤となるプラットフォーム（kube-dns、mesos-dnsなど）に存在するDNSサービスを使用してFQDNを解決しようと試みることができます。

### Ingress and egress
Istioは、サービスメッシュに出入りするすべてのトラフィックがEnvoyプロキシを通過すると仮定します。Envoyプロキシをサービスの前に配置することにより、ユーザー向けサービスのためのA/Bテストの実施、カナリーサービスの展開などが可能です。同様に、Envoyサイドカーを介してトラフィックを外部Webサービスにルーティングすることにより（マップAPIやビデオサービスAPIにアクセスするなど）、タイムアウト、再試行、サーキットブレーカなどの障害回復機能を追加し、これらのサービスへの接続に関する詳細なメトリックを取得できます。

<img width="1420" alt="スクリーンショット 2018-08-06 23.03.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/33101/80ad066b-8373-9402-79c7-41371afeaf0d.png">

## Discovery and load balancing
Istioは、サービスメッシュ内のサービスインスタンス間でトラフィックの負荷を分散します。

Istioは、アプリケーション内のサービスのPods/VMsを追跡するサービスレジストリの存在を前提としています。また、サービスの新しいインスタンスが自動的にサービスレジストリに登録され、不健全なインスタンスが自動的に削除されることを前提としています。KubernetesやMesosなどのプラットフォームは、既にコンテナベースのアプリケーションにこのような機能を提供しており、VMベースのアプリケーションには多くのソリューションが存在します。

Pilotは、サービスレジストリから情報を消費し、プラットフォームに依存しないサービスディスカバリインターフェイスを提供します。メッシュ内のEnvoyインスタンスは、サービスの検出を実行し、それに応じて負荷分散プールを動的に更新します。

<img width="886" alt="スクリーンショット 2018-08-07 8.57.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/33101/0e174f65-5dc8-a89d-28ae-00648efbf954.png">

上記の図に示すように、メッシュ内のサービスはそれぞれのDNS名を使用して相互にアクセスします。サービスにバインドされたすべてのHTTPトラフィックは、Envoyを経由して自動的に再ルーティングされます。Envoyは、負荷分散プール内のインスタンス間でトラフィックを分散します。Envoyはいくつかの[洗練されたロードバランシングアルゴリズム](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/load_balancing)をサポートしていますが、現在、Istioではラウンドロビン、ランダム、および加重最小要求(weighted least request)という3つのロードバランシングモードが可能です。

負荷分散に加えて、Envoyはプール内の各インスタンスの正常性を定期的にチェックします。Envoyは、ヘルスチェックAPI呼び出しの失敗率に基づいて、インスタンスを不健全または健全なものとして分類するために、サーキットブレーカーのパターンに従います。 つまり、特定のインスタンスのヘルスチェック失敗の数があらかじめ指定されたしきい値を超えると、負荷分散プールから排出されます。同様に、通過したヘルスチェックの数があらかじめ指定されたしきい値を超えた場合、そのインスタンスは負荷分散プールに戻されます。Envoyの障害処理機能の詳細については、[障害処理](https://istio.io/docs/concepts/traffic-management/#handling-failures)を参照してください。

サービスは、HTTP 503でヘルスチェックに応答することで、積極的に負荷を軽減することができます。このような場合、サービスインスタンスは、呼び出し元のロードバランシングプールから即座に削除されます。

## Handling failures
Envoyは、アプリケーション内のサービスによって利用可能なオプトインのopt-in障害回復機能を提供します。機能は次のとおりです。

1. タイムアウト
2. タイムアウト・バジェットとリトライ間の可変ジッタによる制限付き再試行
3. 同時接続数とアップストリームサービスへのリクエスト数の制限
4. ロードバランシングプールの各メンバに対するアクティブ（定期的な）ヘルスチェック
5. Fine-graindサーキットブレーカー（パッシブヘルスチェック） - 負荷分散プールのインスタンスごとに適用

これらの機能は、[Istioのトラフィック管理ルール](https://istio.io/docs/concepts/traffic-management/#rule-configuration)によって、実行時に動的に設定することができます。

再試行間のジッタは、オーバーロードされたアップストリームサービスに対する再試行の影響を最小限に抑え、タイムアウトバジェットは、呼び出し元のサービスが予測可能な時間枠内で応答（成功/失敗）を得ることを保証します。

アクティブヘルスチェックとパッシブヘルスチェックの組み合わせ（上記の4と5）は、ロードバランシングプールで不健全なインスタンスにアクセスする可能性を最小限に抑えます。プラットフォームレベルのヘルスチェック（KubernetesやMesosでサポートされているものなど）と組み合わせると、アプリケーションは、不健全なポッド/コンテナ/VMをサービスメッシュから迅速に排出し、要求の失敗や待ち時間の影響を最小限に抑えることができます。

これらの機能により、サービスメッシュは障害の発生したノードにも耐えられ、局在した障害が不安定なカスケードから他のノードにカスケードすることを防ぎます。

### Fine tuning
Istioのトラフィック管理ルールでは、サービス/バージョンごとの障害回復のグローバルなデフォルトを設定できます。ただし、サービスのコンシューマは、特別なHTTPヘッダーを使用してリクエストレベルのオーバーライドを提供することによって、[タイムアウト](https://istio.io/docs/reference/config/istio.networking.v1alpha3/#HTTPRoute-timeout)および[再試行](https://istio.io/docs/reference/config/istio.networking.v1alpha3/#HTTPRoute-retries)のデフォルトを上書きすることもできます。Envoyプロキシの実装では、ヘッダーはそれぞれx-envoy-upstream-rq-timeout-msとx-envoy-max-retriesです。

### Failure handling FAQ
Q：Istioで動作しているときにアプリケーションがまだ障害を処理しますか？

はい。 Istioは、メッシュ内のサービスの信頼性と可用性を向上させます。ただし、**アプリケーションはfailure（エラー）を処理し、適切なフォールバックアクションを実行する必要があります。**たとえば、負荷分散プール内のすべてのインスタンスが失敗した場合、EnvoyはHTTP 503を返します。アップストリームサービスからHTTP 503エラーコードを処理するために必要なフォールバックロジックを実装するのは、アプリケーションの責任です。

Q：Envoyの障害回復機能は、すでにフォールトトレランスライブラリ（[Hystrix](https://github.com/Netflix/Hystrix)など）を使用しているアプリケーションを中断しますか？

Envoyはアプリケーションに対して完全に透過的です。Envoyから返された失敗応答は、呼び出しが行われた上流のサービスから返された失敗応答と区別できません。

Q：アプリケーションレベルのライブラリとEnvoyを同時に使用すると、どのようにして障害が処理されますか？

同じ宛先サービスに対する2つの障害回復ポリシーが与えられると、**障害が発生したときに2つのうちのより制限的なものがトリガーされます。**たとえば、2つのタイムアウトがあります.1つはEnvoyに設定され、もう1つはアプリケーションのライブラリに設定されます。この例では、Envoyで10秒のタイムアウトを設定していたときに、アプリケーションがAPI呼び出しのタイムアウトを5秒に設定した場合、アプリケーションのタイムアウトが最初に発生します。同様に、Envoyのサーキットブレーカがアプリケーションのサーキットブレーカの前にトリガされた場合、サービスへのAPI呼び出しはEnvoyから503になります。

## Fault injection
Envoyのサイドカー/プロキシはIstio上で動作するサービスに多数の[障害回復メカニズム](https://istio.io/docs/concepts/traffic-management/#handling-failures)を提供しますが、アプリケーション全体のエンドツーエンドの障害回復機能をテストすることは必須です。誤って構成された障害回復ポリシー（サービスコール間のタイムアウトなどの互換性のない/制限付きのタイムアウトなど）により、アプリケーションで重大なサービスが継続して使用できなくなり、ユーザーエクスペリエンスが低下する可能性があります。

Istioを使用すると、ポッドを強制終了するか、TCPレイヤーでパケットを遅延または破損させるのではなく、ネットワークにプロトコル固有のフォルトインジェクションを有効にすることができます。その根拠は、ネットワーク層の障害に関係なく、アプリケーション層で観測された障害は同じであり、アプリケーションの復元力を発揮するためには、アプリケーション層（たとえばHTTPエラーコード）でより意味のある障害を注入できることです。

特定の条件に一致する要求にインジェクションするフォールトを構成できます。障害の対象となる要求の割合をさらに制限することができます。2つのタイプの障害、すなわち遅延および異常終了を注入することができる。遅延は、タイミング障害、ネットワーク遅延の増加、またはオーバーロードされたアップストリームサービスの模倣です。異常終了は、上流のサービスの失敗を模倣したクラッシュの失敗です。異常終了は、通常、HTTPエラーコードまたはTCP接続エラーの形で現れます。

## Rule configuration
Istioは、アプリケーションのデプロイメントにおけるさまざまなサービス間のAPI呼び出しとレイヤー4トラフィックの流れを制御するためのシンプルな構成モデルを提供します。構成モデルを使用すると、回路ブレーカー、タイムアウト、再試行などのサービスレベルのプロパティを構成したり、カナリーロールアウト、A / Bテスト、％ベースのトラフィック分割による段階的な展開などの一般的な継続的な展開タスクを設定できます。 

Istioには、VirtualService、DestinationRule、ServiceEntry、およびGatewayの4つのトラフィック管理設定リソースがあります。

* [VirtualService](https://istio.io/docs/reference/config/istio.networking.v1alpha3/#VirtualService)はサービス要求がIstioサービスメッシュ内でどのようにルーティングされるかを制御するルールを定義します。
* [DestinationRule](https://istio.io/docs/reference/config/istio.networking.v1alpha3/#DestinationRule)は、VirtualServiceルーティングが発生した後に要求に適用される一連のポリシーを構成します。
* [ServiceEntry](https://istio.io/docs/reference/config/istio.networking.v1alpha3/#ServiceEntry)は、通常、Istioサービスメッシュ外のサービスへの要求を有効にするために使用されます。
* [Gateway](https://istio.io/docs/reference/config/istio.networking.v1alpha3/#Gateway)はHTTP / TCPトラフィック用のロードバランサを構成します。最も一般的にはメッシュのエッジで動作し、アプリケーションの入力トラフィックを有効にします。

たとえば、次のようにVirtualService構成を使用して、レビューサービスの着信トラフィックをバージョン "v1"に100％送信する簡単なルールを実装できます。

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
```

この設定では、（hostsフィールドで指定された）レreviewsサービスに送信されたトラフィックを、基礎となるreviewsサービスインスタンスのv1サブセットにルーティングする必要があります。ルートsubsetは、対応する宛先ルール設定で定義されたサブセットの名前を指定します。

サブセットは、バージョン固有のインスタンスを識別する1つ以上のラベルを指定します。たとえば、IstioのKubernetes deploymentでは、「version：v1」というラベルは、「version：v1」というラベルを含むポッドのみがトラフィックを受信することを示します。

DestinationRuleでは、追加のポリシーを追加できます。たとえば、次の定義では、ランダムな負荷分散モードを使用するように指定しています。

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews
  trafficPolicy:
    loadBalancer:
      simple: RANDOM
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
```

ルールは、kubectlコマンドを使用して設定できます。例については、[要求ルーティングの構成タスク](https://istio.io/docs/tasks/traffic-management/request-routing/)を参照してください。

以下のセクションでは、トラフィック管理の設定リソースの基本的な概要について説明します。詳細については、[ネットワーキングリファレンス](https://istio.io/docs/reference/config/istio.networking.v1alpha3/)を参照してください。

### Virtual Services
[VirtualService](https://istio.io/docs/reference/config/istio.networking.v1alpha3/#VirtualService)は、サービス要求がIstioサービスメッシュ内でどのようにルーティングされるかを制御するルールを定義します。たとえば、仮想サービスは要求を、異なるバージョンのサービスまたは要求とはまったく異なるサービスにルーティングできます。要求は、要求元と宛先、HTTPパスとヘッダーフィールド、および個々のサービスバージョンに関連付けられた重みに基づいてルーティングできます。

#### Rule destinations
ルーティング規則は、VirtualService構成で指定された1つ以上の要求宛先ホストに対応します。これらのホストは、実際の宛先ワークロードと同じであってもなくてもよく、メッシュ内の実際のルーティング可能なサービスには対応していない場合もあります。たとえば、内部メッシュ名のレビューやホストbookinfo.comを使用してreviewsサービスへのリクエストのルーティングルールを定義する場合、VirtualServiceはhostsフィールドを次のように設定できます。

```yaml
hosts:
  - reviews
  - bookinfo.com
```

hostsフィールドは、1つ以上の完全修飾ドメイン名（FQDN）を暗黙的または明示的に指定します。上記の短い名前のreviewsは、実装固有のFQDNに暗黙的に拡張されます。たとえば、Kubernetes環境では、フルネームはVirtualSeviceのクラスタと名前空間から導出されます（たとえば、reviews.default.svc.cluster.local）。

#### Splitting traffic between versions
各ルートルールは、ルールがアクティブ化されたときに呼び出す1つ以上の重み付きバックエンドを識別します。各バックエンドは、バージョンをlabelを使用して表すことができる宛先サービスの特定のバージョンに対応しています。指定されたラベルを持つ複数の登録済みインスタンスがある場合、それらのインスタンスは、サービス用に構成されたロードバランシングポリシーまたはデフォルトでラウンドロビンに基づいてルーティングされます。

たとえば、次のルールは、reviewsサービスのトラフィックの25％を「v2」ラベルのあるインスタンスに、残りの75％のトラフィックを「v1」にルーティングします。

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
      weight: 75
    - destination:
        host: reviews
        subset: v2
      weight: 25

```

#### Timeouts and retries
デフォルトでは、HTTP要求のタイムアウトは15秒ですが、次のようにルートルールで上書きできます。

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
    - ratings
  http:
  - route:
    - destination:
        host: ratings
        subset: v1
    timeout: 10s
```

ルートルールでHTTPリクエストの再試行回数を指定することもできます。再試行の最大回数、またはデフォルトまたはオーバーライドされたタイムアウト時間内に可能な試行回数は、次のように設定できます。

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
    - ratings
  http:
  - route:
    - destination:
        host: ratings
        subset: v1
    retries:
      attempts: 3
      perTryTimeout: 2s
```

要求タイムアウトと再試行は、[要求ごとにオーバーライド](https://istio.io/docs/concepts/traffic-management/#fine-tuning)することもできます。

タイムアウト制御の例については、[要求タイムアウト](https://istio.io/docs/tasks/traffic-management/request-timeouts/)タスクを参照してください。

#### Injecting faults
ルートルールは、HTTPリクエストをルールの対応するリクエスト先に転送する際に注入する1つ以上のフォールトを指定できます。障害は、遅延または異常終了のいずれかになります。

次の例では、評価(ratings)マイクロサービスの「v1」バージョンに対する要求の10％で5秒の遅延を導入しています。

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - fault:
      delay:
        percent: 10
        fixedDelay: 5s
    route:
    - destination:
        host: ratings
        subset: v1
```

他の種類のフォルト（アボート）を使用して、リクエストを早期に終了することができます。たとえば、障害をシミュレートする。

次の例では、評価(ratings)サービス "v1"へのリクエストの10％に対してHTTP 400エラーコードが返されます。

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - fault:
      abort:
        percent: 10
        httpStatus: 400
    route:
    - destination:
        host: ratings
        subset: v1
```

遅延とアボートの障害が一緒に使用されることがあります。たとえば、次のルールは、reviewsサービス「v2」からレーティングサービス「v1」へのすべてのリクエストを5秒遅延させ、次にその10％を打ち切ります。

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - match:
    - sourceLabels:
        app: reviews
        version: v2
    fault:
      delay:
        fixedDelay: 5s
      abort:
        percent: 10
        httpStatus: 400
    route:
    - destination:
        host: ratings
        subset: v1
```

障害インジェクションの動作を確認するには、[障害インジェクションタスク](https://istio.io/docs/tasks/traffic-management/fault-injection/)を参照してください。

#### Conditional rules
ルールは、オプションで、次のような特定の条件に一致するリクエストにのみ適用されるように修飾することができます。

1.workload labelsを使用して特定のclient workloadに制限する。たとえば、レビューサービスを実装しているワークロード（ポッド）からの呼び出しにのみ適用されるルールを示すことができます。

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - match:
      sourceLabels:
        app: reviews
    ...
```

sourceLabelsの値は、サービスの実装によって異なります。たとえば、Kubernetesでは、対応するKubernetesサービスのポッドセレクタで使用されるのと同じラベルが使用されている可能性があります。

上記の例は、レビューサービスのバージョン "v2"からの呼び出しにのみ適用されるようにさらに洗練されています。

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - match:
    - sourceLabels:
        app: reviews
        version: v2
    ...
```

2.HTTPヘッダーに基づいてルールを選択します。たとえば、次のルールは、文字列 "jason"を含むカスタム "エンドユーザー"ヘッダーが含まれている場合にのみ、着信要求に適用されます。

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    ...
```

ルールに複数のヘッダーが指定されている場合は、対応するヘッダーのすべてが一致する必要があります。

3.リクエストURIに基づいてルールを選択します。たとえば、URIパスが/api/v1で始まる場合、次のルールは要求にのみ適用されます。

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: productpage
spec:
  hosts:
    - productpage
  http:
  - match:
    - uri:
        prefix: /api/v1
    ...
```

#### Multiple match conditions
複数の一致条件を同時に設定できます。このような場合、入れ子に応じて、ANDまたはORセマンティクスが適用されます。

複数の条件が1つのmatch句にネストされている場合、条件はANDされます。たとえば、次のルールは、クライアントワークロードが「reviews：v2」で、「jason」を含むカスタム「エンドユーザー」ヘッダーが要求に含まれている場合にのみ適用されます。

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - match:
    - sourceLabels:
        app: reviews
        version: v2
      headers:
        end-user:
          exact: jason
    ...
```

代わりに、条件が別の一致句で表示される場合は、条件の1つのみが適用されます（ORセマンティクス）。

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - match:
    - sourceLabels:
        app: reviews
        version: v2
    - headers:
        end-user:
          exact: jason
    ...
```

このルールは、クライアントのワークロードが「reviews：v2」または「jason」を含むカスタム「エンドユーザー」ヘッダーがリクエスト内に存在する場合に適用されます。

#### Precedence
特定の宛先に複数のルールがある場合、それらはVirtualServiceに表示される順番で評価されます。つまり、リストの最初のルールが最優先されます。

なぜ優先順位が重要なのですか？特定のサービスのルーティングストーリーが純粋にウェイトベースである場合は常に、それを単一のルールで指定することができます。一方、トラフィックをルーティングするために他の条件（特定のユーザからの要求など）が使用されている場合は、ルーティングを指定するために複数のルールが必要になります。これは、ルールが正しい順序で評価されるように、ルールの優先順位を慎重に検討する必要がある場所です。

一般化された経路指定の一般的なパターンは、様々な条件に合致する1つ以上のより高い優先度のルールを提供し、最後に一致条件のない単一の重み付けルールを提供して、他のすべての場合にトラフィックの重み付け分布を提供できます。

たとえば、次のVirtualServiceには、 「Foo」という名前のヘッダが値「bar」のレビューサービスのすべての要求が「v2」インスタンスに送信されるように指定し、2つのルールが含まれるようにします。残りのリクエストはすべて「v1」に送信されます。

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
        Foo:
          exact: bar
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v1
```

ヘッダーベースのルールの方が優先度が高いことに注意してください。一致した "Foo"ヘッダーが含まれているリクエストであっても、特定の一致条件がないウェイトベースのルールが最初に評価され、 "v1"にすべてのトラフィックがルーティングされるため、これらのルールは期待通りに機能しません。着信要求に適用されるルールが見つかると、それが実行され、ルール評価プロセスは終了します。そのため、ルールが複数ある場合は、各ルールの優先順位を慎重に検討することが非常に重要です。

### Destination rules
DestinationRuleは、VirtualServiceルーティングが発生した後に要求に適用される一連のポリシーを構成します。サービスブローカー、ロードバランサ設定、TLS設定、およびその他の設定について説明する、サービスオーナーが作成することを意図しています。

DestinationRuleは、対応する宛先ホストのアドレス指定可能なサブセット（名前付きバージョンを意味する）も定義します。これらのサブセットは、特定のバージョンのサービスにトラフィックを送信するときにVirtualServiceルート仕様で使用されます。

次のDestinationRuleは、レビューサービスのポリシーとサブセットを設定します。

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews
  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
```

この例では、デフォルトおよびv2固有の複数のポリシーを1つのDestinationRule設定で指定できます。


#### Circuit breakers
簡単なcircuit breakerは、接続や要求の制限などの条件の数に基づいて設定できます。

たとえば、次のDestinationRuleは、レビューサービスバージョン "v1"バックエンドへの接続数を100に制限します。

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews
  subsets:
  - name: v1
    labels:
      version: v1
    trafficPolicy:
      connectionPool:
        tcp:
          maxConnections: 100
```

サーキットブレーカーコントロールのデモンストレーションについては、[サーキットブレーカーのタスク](https://istio.io/docs/tasks/traffic-management/circuit-breaking/)を参照してください。

#### Rule evaluation
ルートルールと同様に、DestinationRuleで定義されたポリシーは特定のホストに関連付けられています。ただし、それらがサブセット固有のものである場合、アクティベーションはルートルール評価結果に依存します。

ルール評価プロセスの最初のステップでは、要求されたホストに対応するVirtualService内のルートルールがある場合は評価し、現在の要求がルーティングされる宛先サービスのサブセット（特定のバージョンを意味します）を判断します。次に、選択されたサブセットに対応する1組のポリシーが評価され、適用されるかどうかが判定される。

NOTE: アルゴリズムの1つの微妙な点は、特定のサブセットに対して定義されたポリシーは、対応するサブセットが明示的にルーティングされる場合にのみ適用されることです。たとえば、レビューサービスに定義された唯一のルールとして、対応するVirtualService定義にルートルールがないことを意味する次の設定を考えます。

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews
  subsets:
  - name: v1
    labels:
      version: v1
    trafficPolicy:
      connectionPool:
        tcp:
          maxConnections: 100
```

レビューサービスに特定のルートルールが定義されていないため、デフォルトのラウンドロビンルーティング動作が適用されます。おそらく "v1"が唯一の実行中のバージョンである場合もあります。それにもかかわらず、デフォルトのルーティングがより低いレベルで行われるので、上記のポリシーは決して呼び出されません。ルール評価エンジンは最終的な宛先を認識しないため、サブセットポリシーを要求に一致させることができません。

上記の例は、次の2つの方法のいずれかで修正できます。トラフィックポリシーをDestinationRuleのレベルまで移動すると、任意のバージョンに適用されます。

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 100
  subsets:
  - name: v1
    labels:
      version: v1
```

または、より良い方法では、VirtualService定義でサービスの適切なルートルールを定義することをお勧めします。たとえば、「レビュー：v1」の簡単なルートルールを追加します。

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
```

既定のIstioの動作では、規則を設定せずに任意の送信元から送信先サービスのすべてのバージョンにトラフィックを送信しますが、バージョンの差別化が必要になるとすぐにルールが必要になります。したがって、最初からすべてのサービスのデフォルトルールを設定することは、一般にIstioのベストプラクティスとみなされます。

### Service entries
ServiceEntryは、Istioが内部的に維持する追加のエントリをサービスレジストリに追加するために使用されます。これは、Istioサービスメッシュ外のサービスへの要求を有効にするために最も一般的に使用されます。たとえば、次のServiceEntryを使用して、* .foo.comドメインの下でホストされているサービスへの外部呼び出しを許可できます。

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: foo-ext-svc
spec:
  hosts:
  - *.foo.com
  ports:
  - number: 80
    name: http
    protocol: HTTP
  - number: 443
    name: https
    protocol: HTTPS
```

ServiceEntryの宛先は、「hosts」フィールドを使用して指定します。「hosts」フィールドは、完全修飾ドメイン名またはワイルドカード名のいずれかです。これは、メッシュ内のサービスがアクセスできる1つ以上のサービスのホワイトリストのセットを表します。

ServiceEntryは、外部サービスの構成に限定されません。それはmesh-internalかmesh-externalの2種類があります。Mesh-internalエントリは他のすべての内部サービスと同様ですが、メッシュにサービスを明示的に追加するために使用されます。これらは、サービスメッシュを拡張してアンマネージドインフラストラクチャ（たとえば、Kubernetesベースのサービスメッシュに追加されたVM）を含むようにサービスを追加するために使用できます。Mesh-externalエントリは、メッシュ外部のサービスを表します。それらに対して、相互TLS認証は無効にされ、ポリシー適用は、内部サービス要求の場合のようにサーバー側ではなく、クライアント側で実行されます。

ServiceEntryは、一致するhostsを使用するサービスを参照する限り、仮想サービスおよび宛先ルールと連携して機能します。たとえば、次のルールを上記のServiceEntryルールと組み合わせて使用​​して、bar.foo.comの外部サービスへのコールに10秒のタイムアウトを設定できます。

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bar-foo-ext-svc
spec:
  hosts:
    - bar.foo.com
  http:
  - route:
    - destination:
        host: bar.foo.com
    timeout: 10s
```

トラフィックをリダイレクトおよび転送するルール、再試行、タイムアウト、および障害インジェクションポリシーを定義するルールは、すべて外部宛先でサポートされています。しかし、複数のバージョンの外部サービスの概念がないため、重み付け（バージョンベース）ルーティングは不可能です。

外部サービスへのアクセスの詳細については、[出力タスク(egress task)](https://istio.io/docs/tasks/traffic-management/egress/)を参照してください。

### Gateways
[ゲートウェイ](https://istio.io/docs/reference/config/istio.networking.v1alpha3/#Gateway)はHTTP / TCPトラフィック用のロードバランサを構成します。最も一般的にはメッシュのエッジで動作し、アプリケーションの入力トラフィックを有効にします。

Kubernetes Ingressとは異なり、Istio GatewayはL4-L6機能（ポートの公開、TLS設定など）のみを設定します。ユーザーは、標準のIstioルールを使用して、HTTPリクエストと、VirtualServiceをバインドしてGatewayに入るTCPトラフィックを制御できます。

たとえば、次の単純なGatewayは、ホストbookinfo.comの外部HTTPSトラフィックをメッシュに入れるためのロードバランサを設定します。

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: bookinfo-gateway
spec:
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    hosts:
    - bookinfo.com
    tls:
      mode: SIMPLE
      serverCertificate: /tmp/tls.crt
      privateKey: /tmp/tls.key
```

対応するルートを設定するには、コンフィグレーションのgatewayフィールドを使用して、同じホストに対してVirtualServiceを定義し、ゲートウェイにバインドする必要があります。

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
    - bookinfo.com
  gateways:
  - bookinfo-gateway # <---- bind to gateway
  http:
  - match:
    - uri:
        prefix: /reviews
    route:
    ...
```

完全なingress gatewayの例については、[ingress task](https://istio.io/docs/tasks/traffic-management/ingress/)を参照してください。

主に入力トラフィックの管理に使用されますが、Gatewayを使用して純粋に内部または出口のプロキシをモデル化することもできます。場所に関係なく、すべてのゲートウェイを同じ方法で設定および制御できます。詳細については、[ゲートウェイリファレンス](https://istio.io/docs/reference/config/istio.networking.v1alpha3/#Gateway)を参照してください。