TT Lab
はじめる
学ぶ 学習パス コース

Istioサービスメッシュ

ルーティング規則と復元力の設定を書く

TT Labで続きを見る

目標

VirtualServiceでリクエストを条件に応じて振り分け、DestinationRuleで対象の性質とレジリエンスを決める感覚を身につけます。

なぜ重要なのか

2つのリソースの役割分離は好みの問題ではなく、運用構造です。デプロイパイプラインが毎回触るのはルーティング(VirtualService)で、サービスの所有者が一度決めて長く置いておくのは対象の性質(DestinationRule)です。この境界があいまいになると、デプロイのたびにコネクションプールの設定まで一緒に揺らぎます。そしてマッチングの順序とsubsetのラベルの一致、この2つがメッシュのトラブルシューティングの半分です。条件のない既定経路を上に置くと下の規則が死に、subsetのラベルがPodのラベルとずれるとエンドポイントが空になって503(UH)になります。レジリエンスの設定も、勘で決めてはいけません。全体のタイムアウトが試行時間の合計より短いと、リトライは1回もできずに終わり、隔離の上限がないと、サーキットブレーカーが全面障害を引き起こします。

このラボ環境ではパケットが流れないため、採点はマニフェストの構造とistioctl analyzeの結果を見ます。

ステップ

開始前の準備: ラボのPodはラボごとに新しく起動するため、前のラボでインストールしたメッシュ設定は残っていません。kubectl get crd virtualservices.networking.istio.ioの結果が空なら、まずistioctl manifest generate --set profile=minimal > /root/istio/manifest.yamlでマニフェストを作成し、kubectl apply -f /root/istio/manifest.yamlを2回実行してください(CRDが先に登録されたあとで、残りが適用されます)。そのあと、kubectl create ns mesh-lab && kubectl label ns mesh-lab istio-injection=enabledでネームスペースを準備します。

  1. /opt/lab/fixtures/istio/workload-v1v2.yamlをmesh-labネームスペースに適用してください。Service reviewsの最初のポート名はhttpである必要があり、Deployment reviews-v1・reviews-v2のPodラベルは、それぞれapp: reviewsとversion: v1/version: v2である必要があります。
  2. mesh-labにDestinationRule reviewsを作成してください。spec.hostはreviewsで、spec.subsetsに、名前がv1(labels: {version: v1})とv2(labels: {version: v2})であるsubsetを2つ置いてください。
  3. mesh-labにVirtualService reviewsを作成してください。spec.hostsにreviewsを置き、spec.httpの最後の項目にはmatchを入れず、destinationをhost: reviews、subset: v1にしてください。
  4. 同じVirtualServiceの前のほうに、条件付きルートを追加してください。条件はヘッダーend-userがちょうどlabhub-testerである場合で、宛先はsubset: v2です。このルートは、最後の既定経路より上にある必要があります。
  5. mesh-labにratingsワークロードを作成してください。Service ratings(ポート名http、ポート9080)とDeployment ratings-v1(Podラベルapp: ratings、version: v1)です。そのあと、VirtualService ratingsを作成して、matchのuri.prefixを/api/ratingsに、rewrite.uriを/ratingsにし、destinationはhost: ratingsにしてください。
  6. 同じVirtualService ratingsのルートに、timeout: 3sとretriesを付けてください。attempts: 3、perTryTimeout: 1sにし、retryOnには5xx、connect-failureを含めてください。そして/root/istio/traffic/out/retry-note.txtに、冪等でないリクエスト(POSTなど)をリトライするとなぜ危険なのかを書いてください。
  7. mesh-labにDestinationRule ratingsを作成し、trafficPolicy.outlierDetectionにconsecutive5xxErrors: 5、interval: 10s、baseEjectionTime: 30s、maxEjectionPercent: 50を入れてください。また、VirtualService ratingsにfault.delayを追加して、percentage.value: 10、fixedDelay: 2sにしてください。
  8. istioctl analyze -n mesh-labの結果を/root/istio/traffic/out/analyze.txtに保存してください(Error [が残っていてはいけません)。そして/root/istio/traffic/out/routes.jsonを作成してください。routes配列の長さは、実際のVirtualService reviewsのspec.httpの項目数と同じである必要があり、配列の最後の要素にはmatchキーを入れないでください。default_subsetキーの値はv1です。mesh-labにはVirtualServiceが2つ以上ある必要があります。

参考

対象ワークロードとバージョンラベルの立ち上げ

/opt/lab/fixtures/istio/workload-v1v2.yamlをmesh-labネームスペースに適用してください。Service reviewsの最初のポート名はhttpである必要があり、Deployment reviews-v1・reviews-v2のPodラベルは、それぞれapp: reviewsとversion: v1/version: v2である必要があります。

フィクスチャをそのまま適用すれば済みます。ただし、Serviceのポートに名前があるか、Podテンプレートにappとversionのラベルが両方あるかを確認してください。メッシュはポート名でプロトコルを判断します。

バージョン別subsetの定義

mesh-labにDestinationRule reviewsを作成してください。spec.hostはreviewsで、spec.subsetsに、名前がv1(labels: {version: v1})とv2(labels: {version: v2})であるsubsetを2つ置いてください。

subsetは名前だけではPodを選びません。各subsetに、どのラベルでPodを選ぶかを書く必要があり、そのラベルは実際のPodラベルと同じでなければなりません。

既定経路のv1への振り分け

mesh-labにVirtualService reviewsを作成してください。spec.hostsにreviewsを置き、spec.httpの最後の項目にはmatchを入れず、destinationをhost: reviews、subset: v1にしてください。

条件のないルートが1つないと、マッチングに失敗したリクエストの行き先がなくなります。そのルートは配列の一番最後に置いてください。

ヘッダー条件によるv2への振り分け

同じVirtualServiceの前のほうに、条件付きルートを追加してください。条件はヘッダーend-userがちょうどlabhub-testerである場合で、宛先はsubset: v2です。このルートは、最後の既定経路より上にある必要があります。

マッチングは上から下へ進み、最初に当てはまるものを使います。条件付きルートが既定経路より下にあると、永遠に実行されません。

パスのプレフィックスマッチングと書き換え

mesh-labにratingsワークロードを作成してください。Service ratings(ポート名http、ポート9080)とDeployment ratings-v1(Podラベルapp: ratings、version: v1)です。そのあと、VirtualService ratingsを作成して、matchのuri.prefixを/api/ratingsに、rewrite.uriを/ratingsにし、destinationはhost: ratingsにしてください。

外部に公開するパスと、後段が知っているパスが異なるときに使います。対象のサービスがクラスターにないと、静的分析がエラーを出すので、ワークロードも一緒に作成してください。

タイムアウトとリトライの追加

同じVirtualService ratingsのルートに、timeout: 3sとretriesを付けてください。attempts: 3、perTryTimeout: 1sにし、retryOnには5xx、connect-failureを含めてください。そして/root/istio/traffic/out/retry-note.txtに、冪等でないリクエスト(POSTなど)をリトライするとなぜ危険なのかを書いてください。

リトライが意味を持つには、全体のタイムアウトの中に試行が収まる必要があります。そして、リトライしても安全なリクエストかどうかを、まず検討してください。

外れ値検出と障害注入

mesh-labにDestinationRule ratingsを作成し、trafficPolicy.outlierDetectionにconsecutive5xxErrors: 5、interval: 10s、baseEjectionTime: 30s、maxEjectionPercent: 50を入れてください。また、VirtualService ratingsにfault.delayを追加して、percentage.value: 10、fixedDelay: 2sにしてください。

隔離には必ず上限を設けます。全部外してしまうと、サービスがまるごと止まります。障害注入も、割合を指定して初めて実験になります。

設定の検証とルート順序の整理

istioctl analyze -n mesh-labの結果を/root/istio/traffic/out/analyze.txtに保存してください(Error [が残っていてはいけません)。そして/root/istio/traffic/out/routes.jsonを作成してください。routes配列の長さは、実際のVirtualService reviewsのspec.httpの項目数と同じである必要があり、配列の最後の要素にはmatchキーを入れないでください。default_subsetキーの値はv1です。mesh-labにはVirtualServiceが2つ以上ある必要があります。

ルート数は手で数えず、実際のリソースから取り出してください。既定経路には条件がないという事実が、整理ファイルにも表れている必要があります。