あるサービスバージョンが利用できなくなると、そのバージョンへのリクエストは HTTP 503 エラーを返します。フォールバックルーティングは、プロキシレベルでリクエストを代替のサービスバージョンに自動的にリダイレクトすることで、この問題を解決します。Service Mesh (ASM) は、Istio の VirtualService リソースを拡張し、この代替ルートを定義する fallback フィールドを提供します。
このトピックでは、Bookinfo サンプルアプリケーションを使用して、フォールバックルーティングについて説明します。具体的には、以下の内容を扱います。
すべてのトラフィックを特定のサービスバージョンにルーティングする
プライマリバージョンが到達不能になった場合にトラフィックを受信するフォールバックターゲットを定義する
高度なシナリオのためにフォールバックと加重ルーティングを組み合わせる
カスタムアクセスログを通じてフォールバックの動作を検証する
フォールバックとリトライ、サーキットブレーカーの違い
ASM は、いくつかの回復性メカニズムを提供します。対応する必要がある障害モードに基づいて、適切なものを選択してください。
| メカニズム | 障害モード | 動作 | 使用するケース |
|---|---|---|---|
| フォールバック | サブセット内のすべてのエンドポイントが到達不能 | 代替サブセットへのリダイレクト | バックアップバージョンまたはデプロイメントがリクエストを処理できる場合 |
| リトライ | 一時的なエラー (タイムアウト、5xx) | 同じサブセットへのリクエストの再送信 | エラーが断続的で、リトライによって成功する可能性が高い場合 |
| サーキットブレーカー | 持続的な高エラー率 | 異常なエンドポイントへのトラフィック送信の停止 | カスケード障害からダウンストリームサービスを保護する場合 |
フォールバックはルーティングレベルで動作します。サイドカープロキシは、リクエストを転送する前に、ターゲットサブセットに正常なエンドポイントがあるかどうかを確認します。正常なエンドポイントが存在しない場合、代わりにフォールバックターゲットにルーティングします。
前提条件
| 要件 | 詳細 |
|---|---|
| ASM インスタンス | Enterprise Edition または Ultimate Edition、バージョン 1.17.2.22 以降 |
| Kubernetes クラスター | ASM インスタンスに追加された Container Service for Kubernetes (ACK) クラスター。詳細は、ASM インスタンスへのクラスターの追加をご参照ください。 |
| サンプルアプリケーション | クラスターにデプロイされた Bookinfo。詳細は、ASM インスタンスでのアプリケーションのデプロイをご参照ください。 |
| サイドカープロキシのバージョン | 1.17 以降 すべてのデータプレーン Pod で |
ご利用の ASM インスタンスのバージョンが 1.17 より前の場合は、1.17.2.22 以降に更新してください。詳細は、ASM インスタンスの更新をご参照ください。または、チケットを送信してテクニカルサポートを依頼してください。
Bookinfo の reviews サービスのバージョン
Bookinfo の reviews サービスには 3 つのバージョンがあり、それぞれ製品ページの星評価で識別できます。
| バージョン | 星評価 |
|---|---|
| v1 | 星なし |
| v2 | 黒い星 |
| v3 | 赤い星 |
productpage サービスは reviews を呼び出します。VirtualService はすべてのトラフィックを reviews-v3 にルーティングします。v3 が利用できなくなった場合、フォールバックルールは 503 エラーを返す代わりに、リクエストを reviews-v2 にリダイレクトします。
ステップ 1:reviews サービスの宛先ルールの作成
reviews サービスの各バージョンに対応するサブセットを持つ DestinationRule を定義します。
reviews.yamlという名前のファイルを作成し、次の内容を記述します。apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: reviews spec: host: reviews subsets: - name: v1 labels: version: v1 - name: v2 labels: version: v2 - name: v3 labels: version: v3kubectl と KubeConfig ファイルを使用して ASM インスタンスに接続し、ルールを適用します。
kubectl apply -f reviews.yamlいずれかの方法でイングレスゲートウェイの IP アドレスを取得します。
次のコマンドを実行します。
kubectl get svc -n istio-system istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}'ASM コンソールの [イングレスゲートウェイ] ページで IP を確認します。詳細は、ASM インスタンスのイングレスゲートウェイの IP アドレスの照会をご参照ください。
ブラウザで
http://<gateway-ip>/productpageを開きます。Reviews served by フィールドと星評価によって、各リクエストを処理しているバージョンがわかります。ページを数回リフレッシュすると、リクエストは v1、v2、v3 に分散されます。例えば、reviews-v2は黒い星を表示します。
ステップ 2:基本的なフォールバックルールの設定
すべてのトラフィックを reviews-v3 にルーティングし、reviews-v2 をフォールバックターゲットとして設定します。
reviews-route-fallback-sample1.yamlという名前のファイルを作成します。fallback.targetフィールドは、reviews-v3が到達不能な場合にリクエストをreviews-v2に転送するようサイドカープロキシに指示します。apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: reviews-route namespace: default spec: hosts: - reviews http: - route: - destination: host: reviews subset: v3 fallback: target: host: reviews subset: v2VirtualService を適用します。
kubectl apply -f reviews-route-fallback-sample1.yamlhttp://<gateway-ip>/productpageを開いてリフレッシュします。すべてのリクエストが v3 (赤い星) にルーティングされるようになります。
v3 のデプロイメントを 0 レプリカにスケーリングして、v3 の障害をシミュレートします。
kubectl scale deployment reviews-v3 --replicas=0ページをリフレッシュします。リクエストは v2 (黒い星) にフォールバックされるようになります。
ステップ 3:フォールバックと加重ルーティングの組み合わせ
フォールバックルールは加重ルーティングと連携して機能します。このシナリオでは、トラフィックは v3 と v2 の間で 50/50 に分割され、各バージョンには独自のフォールバックターゲットがあります。
v3 を復元します。
kubectl scale deployment reviews-v3 --replicas=1reviews-route-fallback-sample2.yamlという名前のファイルを作成します。2 つの独立したフォールバックチェーンが定義されています。テスト中にフォールバックの動作をリトライの動作から分離するため、リトライは無効 (attempts: 0) になっています。v3 トラフィック (50%):v3 が利用できない場合、v2 にフォールバックします
v2 トラフィック (50%):v2 が利用できない場合、v1 にフォールバックします
apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: reviews-route namespace: default spec: hosts: - reviews http: - route: - destination: host: reviews subset: v3 fallback: target: host: reviews subset: v2 weight: 50 - destination: host: reviews subset: v2 fallback: target: host: reviews subset: v1 weight: 50 retries: attempts: 0更新された VirtualService を適用します。
kubectl apply -f reviews-route-fallback-sample2.yaml製品ページをリフレッシュします。リクエストは v3 (赤い星) と v2 (黒い星) の間で均等に分散されます。
v3 がダウンした場合のフォールバックのテスト
v3 をゼロにスケーリングします。ページをリフレッシュします。すべてのリクエストが v2 に到達するようになります。元々 v3 をターゲットとしていた 50% は v2 にフォールバックし、残りの 50% は直接 v2 にルーティングされます。
kubectl scale deployment reviews-v3 --replicas=0
v3 と v2 の両方がダウンした場合のフォールバックのテスト
v2 をゼロにスケーリングします。ページをリフレッシュします。2 つの動作が交互に発生します。

リクエストの 50% が成功:これらは元々 v2 にルーティングされたリクエストで、v1 (星なし) にフォールバックします。
リクエストの 50% が 503 エラーで失敗:これらは元々 v3 にルーティングされたリクエストです。プロキシは v2 へのフォールバックを試みますが、v2 もダウンしているため、フォールバックチェーンは v1 には及びません。
kubectl scale deployment reviews-v2 --replicas=0ログでこれを確認します。失敗したフォールバックは、次のようなログエントリを生成します。失敗したフォールバックログの主要なフィールドは次のとおりです。
response_code:503はリクエストが処理されなかったことを示します。response_flags:UH(Upstream Host Unhealthy)。fallback_result:"fallback cluster is unhealthy"は、フォールバックターゲット (v2) も利用できなかったことを示します。upstream_cluster:依然として v3 クラスターを示しており、元のルーティング先を確認できます。
kubectl logs -f deployment/productpage-v1 -c istio-proxy --tail=10{ "authority": "reviews:9080", "authority_for": "reviews:9080", "bytes_received": "0", "bytes_sent": "19", "downstream_local_address": "192.168.255.46:9080", "downstream_remote_address": "172.16.0.252:47738", "duration": "0", "fallback_path": "outbound|9080|v3|reviews.default.svc.cluster.local:outbound|9080|v2|reviews.default.svc.cluster.local", "fallback_final_cluster_name": "-", "fallback_result": "fallback cluster is unhealthy", "istio_policy_status": "-", "method": "GET", "path": "/reviews/0", "protocol": "HTTP/1.1", "request_id": "b207a764-b6d7-4ef8-bc71-59f264c3****", "requested_server_name": "-", "response_code": "503", "response_flags": "UH", "route_name": "-", "start_time": "2023-05-30T07:32:08.999Z", "trace_id": "a40c32a7b2cf****", "upstream_cluster": "outbound|9080|v3|reviews.default.svc.cluster.local", "upstream_host": "-", "upstream_local_address": "-", "upstream_service_time": "-", "upstream_transport_failure_reason": "-", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.X.X Safari/537.36", "x_forwarded_for": "-" }
本番環境でのフォールバックの使用
フォールバックルーティングはサービスの障害をマスクするため、可用性にとっては価値がありますが、本番環境では慎重な計画が必要です。
フォールバック頻度の監視
持続的に高いフォールバック率は、プライマリサービスバージョンに根本的な問題があることを示します。サイレントフェイルオーバーとして依存するのではなく、fallback_result アクセスログフィールドにアラートを設定して、フォールバックが繰り返しトリガーされるタイミングを検出してください。
キャパシティプランニング
フォールバックがトリガーされると、フォールバックターゲットは通常の負荷を超える追加のトラフィックを受け取ります。フォールバックサービスバージョンが、通常のトラフィックとリダイレクトされたトラフィックの両方を処理するのに十分なキャパシティを持っていることを確認してください。ステップ 3 の加重ルーティングのシナリオでは、v3 がダウンした場合、v2 は総トラフィックの最大 100% を処理できなければなりません。
フォールバックチェーンの深さ
フォールバックは、複数のホップにわたって自動的にカスケードされません。加重ルーティングの例では、v3 が v2 にフォールバックし、v2 もダウンしている場合、リクエストは 503 で失敗し、v1 には続きません。各ルートエントリは、独自の独立したフォールバックターゲットを維持します。これに応じてフォールバックチェーンを計画してください。
