安定したベースラインや 1 つ以上のカナリアデプロイメントなど、サービスの複数のバージョンが並行して実行されている場合、各リクエストを正しいバージョンに送信する方法が必要です。Service Mesh (ASM) は、トラフィックラベルを使用してこの問題を解決します。トラフィックラベルは、TrafficLabel カスタムリソース定義 (CRD) がリクエストにアタッチするカスタム HTTP ヘッダーです。これらのヘッダーに一致するルーティングルールを定義し、対応するワークロードバージョンにトラフィックを転送します。
ラベルベースルーティングは、連携して動作する 2 つの Istio リソースに依存します。
DestinationRule:ワークロードインスタンスを名前付きのサブセットにグループ化します。各サブセットは、Kubernetes ラベル (通常は
versionラベル) によって Pod を選択します。このリソースは、トラフィックの送信先 (where) を定義します。VirtualService:ルーティングルールを上から下に評価し、各リクエストを最初に一致したサブセットに送信します。最後にキャッチオールルートを配置し、一致しないトラフィックを処理します。このリソースは、どのトラフィック (which) をどこに (where) 送信するかを定義します。
ルーティングルールは上から下に順次評価されます。リクエストに最初に一致したルールが適用され、後続のルールはスキップされます。一致しないトラフィックを捕捉するために、常に最後にデフォルトルートを配置してください。
基本的な例
以下の最小構成では、ヘッダーが asm-labels-test: test1 のリクエストを test1 サブセットにルーティングし、その他すべてのリクエストを base サブセットに送信します。
# DestinationRule: サブセットを定義
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: dr-productpage
spec:
host: productpage
subsets:
- name: test1
labels:
version: test1
- name: base
labels:
version: base
---
# VirtualService: ヘッダー値でルーティング
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: vs-productpage
spec:
hosts:
- productpage
http:
- match:
- headers:
asm-labels-test:
exact: test1
route:
- destination:
host: productpage
subset: test1
- route:
- destination:
host: productpage
subset: base両方のリソースを適用します。
kubectl apply -f dr-productpage.yaml
kubectl apply -f vs-productpage.yamlルーティングを検証します。
# ラベルヘッダー付きのリクエストは test1 サブセットに送信されます
curl -H "asm-labels-test: test1" http://<productpage-url>
# ヘッダーなしのリクエストは base サブセットに送信されます
curl http://<productpage-url>より多くのサブセットや詳細設定については、以降のセクションをご参照ください。
前提条件
開始する前に、以下の条件を満たしていることを確認してください。
TrafficLabel CRD を介してトラフィックラベルが設定されていること。詳細については、「トラフィックのラベリング」をご参照ください。
DestinationRule の作成
DestinationRule は、サービスで利用可能なサブセットを定義します。各サブセットは、Kubernetes ラベルによって識別される Pod のグループにマッピングされます。
次の内容で
dr-productpage.yamlという名前のファイルを作成します。この例では、
productpageサービスに対して、サブセットtest1、test2、test3、およびbaseを定義します。各サブセットは、versionラベルがサブセット名と一致する Pod を選択します。apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: dr-productpage spec: host: productpage subsets: - name: test1 labels: version: test1 - name: test2 labels: version: test2 - name: test3 labels: version: test3 ... - name: testn labels: version: testn - name: base labels: version: base宛先ルールを適用します。
kubectl apply -f dr-productpage.yaml
VirtualService の作成
VirtualService はルーティングロジックを定義します。各ルールはヘッダー値によってリクエストを照合し、対応するサブセットにルーティングします。ルールは上から下に評価され、最初に一致したものが適用されます。
次の内容で
vs-productpage.yamlという名前のファイルを作成します。この例では、
asm-labels-test: test1を持つリクエストはtest1サブセットに、test2を持つリクエストはtest2サブセットに、というようにルーティングされます。matchブロックのない最後のルートは、残りのすべてのリクエストを捕捉し、baseサブセットに送信します。apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: vs-productpage spec: hosts: - productpage http: - match: - headers: asm-labels-test: exact: test1 route: - destination: host: productpage subset: test1 - match: - headers: asm-labels-test: exact: test2 route: - destination: host: productpage subset: test2 - match: - headers: asm-labels-test: exact: test3 route: - destination: host: productpage subset: test3 - route: - destination: host: productpage subset: base次の表に、主要なフィールドを示します。
フィールド
説明
match.headers.asm-labels-test
照合対象のトラフィックラベル名
match.headers.exact
照合に必要なトラフィックラベルの完全一致値
route.destination.subset
一致したトラフィックを受信する宛先サブセット
VirtualService を適用します。
kubectl apply -f vs-productpage.yaml
ルーティングルールの検証
両方のリソースを適用した後、トラフィックが正しくルーティングされることを確認します。
# リソースが存在することを確認
kubectl get destinationrule dr-productpage
kubectl get virtualservice vs-productpage
# トラフィックラベルヘッダー付きのテストリクエストを送信
# <productpage-url> をご利用のサービス URL に置き換えてください
curl -H "asm-labels-test: test1" http://<productpage-url>asm-labels-test: test1 を持つリクエストは、test1 サブセット内の Pod に到達するはずです。他のヘッダー値 (test2、test3) でテストし、各サブセットが期待されるトラフィックを受信することを確認します。asm-labels-test ヘッダーのないリクエストは、base サブセットにフォールスルーします。
ヘッダーベースのルーティングは、呼び出しチェーン内の各サービスがトラフィックラベルヘッダーを転送することに依存します。中間サービスがヘッダーを削除すると、ダウンストリームのルーティングルールは通知なく失敗します。アプリケーションまたは ASM サイドカーが asm-labels-test ヘッダーをエンドツーエンドで伝播するようにしてください。
変数構文による VirtualService の簡素化
多くのワークロードバージョンが存在する場合、それぞれに match ブロックをリストすると VirtualService が冗長になります。明示的な一致を $asm-labels-test 変数構文に置き換えます。ASM はランタイムで変数を解決し、ヘッダー値と名前が一致するサブセットにトラフィックをルーティングします。ターゲットのサブセットが利用できない場合、トラフィックは他の利用可能なバージョンにシフトします。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: vs-productpage
spec:
hosts:
- productpage
http:
- route:
- destination:
host: productpage
subset: $asm-labels-testフォールバックルーティングの設定
ASM Enterprise Edition では、ターゲットのサブセットが利用できない場合 (たとえば、サブセットが定義されていない、または一致する Pod が存在しない場合)、トラフィックは自動的にバックアップサービスにフォールバックします。
route の下にある fallback フィールドでバックアップターゲットを指定します。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: vs-productpage
spec:
hosts:
- productpage
http:
- route:
- destination:
host: productpage
subset: $asm-labels-test
fallback:
target:
host: productpage
subset: base次の表に、フォールバックフィールドを示します。
フィールド | 説明 |
target.host | フォールバックトラフィックを受信するサービス |
target.subset | フォールバックトラフィックを受信するサブセット |
関連情報
トラフィックにラベルを付ける -- TrafficLabel CRD を使用してトラフィック ラベルを設定する