動的サブセット ロードバランシングを使用して、マイクロサービス ワークロードの詳細な管理と柔軟なルーティングを実装できます。複数のアプリケーションとバージョンがリリースされるシナリオでは、サービスメッシュ(ASM)はアプリケーションの特性に基づいてワークロードを動的サブセットに自動的に分割します。 O&M 担当者は手動で構成を行う必要はありません。 ASM は、リクエストの特定のヘッダーをサブセットの特性と照合して、より柔軟なリクエスト ルーティングを実装することもできます。
前提条件
Container Service for Kubernetes(ACK)クラスタが v1.18 以降の ASM インスタンスに追加されています。詳細については、「ASM インスタンスにクラスタを追加する」をご参照ください。
機能の説明
ASM では、デスティネーション ルールを使用してサービスのワークロードをタグによって異なるサブセットに分割し、仮想サービスを使用してルーティング ルールを宣言し、トラフィックを特定のサブセットにルーティングできます。この静的グループ化と静的ルーティングの方法は比較的単純であり、ほとんどの状況のニーズを満たすことができます。ただし、一部のシナリオでは、この方法は十分に便利ではない場合があります。たとえば、ワークロードがバージョンごとに異なるサブセットに分割されるシナリオでは、バージョンが進化している可能性があります。これにより、O&M 担当者は、後のバージョンがリリースされたとき、または以前のバージョンが段階的に廃止されたときに、デスティネーション ルールで対応するサブセット構成を追加または削除する必要があります。複数のアプリケーションとバージョンが頻繁にリリースされるシナリオでは、O&M 担当者がサブセット構成を更新するのは負担になります。
ユーザー エクスペリエンスを向上させるために、ASM は v1.18 以降、動的サブセット ロードバランシングをサポートしています。バージョンなどのディメンションを指定して、指定されたディメンションで同じ値を持つワークロードを同じ動的サブセットに動的に分割できます。前のシナリオで動的サブネットを使用する場合、O&M 担当者は新しいバージョンごとにサブセットを手動で構成する必要はありません。ワークロードをデプロイすると、ASM はアプリケーションの特性に基づいてワークロードを動的サブセットに自動的に分類します。さらに、ASM では、リクエストの特定のヘッダーをサブセットの特性と照合するように構成し、リクエストに含まれるヘッダーに基づいてリクエストを指定された動的サブセットにルーティングできます。
手順 1: アプリケーションをデプロイする
この例では、hashicorp/http-echo アプリケーションが使用され、開発環境と本番環境をそれぞれシミュレートするために 2 つの環境、dev と prod がデプロイされます。 dev 環境には v1、v2、v3 のバージョンがデプロイされ、prod 環境には v2 と v3 のバージョンのみがデプロイされます。各 helloworld アプリケーションはポート 5678 でリッスンし、リクエストを受信すると独自の環境とバージョンで応答します。 helloworld サービスは、ポート 8000 を公開するようにデプロイされます。さらに、helloworld サービスは、app タグの値が helloworld であるワークロードに関連付けられています。
kubeconfig ファイルの情報に基づいて、kubectl を使用して ACK クラスタに接続します。次に、次の YAML コードを使用して、dev 環境に helloworld アプリケーションの v1、v2、v3 バージョン、prod 環境に helloworld アプリケーションの v2 と v3 バージョン、helloworld サービス、およびテストの開始に使用される sleep アプリケーションをデプロイします。アプリケーションのデプロイ方法の詳細については、「ASM インスタンスに追加された ACK クラスタにアプリケーションをデプロイする」をご参照ください。
手順 2: 特定環境の特定バージョンにアクセスする
デスティネーション ルールと仮想サービスを作成します。
次のコンテンツを使用して、helloworld サービスのデスティネーション ルールを作成します。詳細については、「デスティネーション ルールの管理」をご参照ください。
helloworld アプリケーションがデプロイされると、helloworld サービスにアクセスするリクエストは、デフォルトで Kubernetes のロードバランシング機能によって helloworld アプリケーションの任意のポッドに割り当てられます。この例では、helloworld アプリケーション用に 2 つの環境と複数のバージョンがデプロイされています。 dev 環境には v1、v2、v3 バージョン、prod 環境には v2 と v3 バージョンがあります。特定の環境とバージョンにアクセスするには、helloworld サービスのデスティネーション ルールを構成する必要があります。
apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: helloworld namespace: default spec: host: helloworld.default.svc.cluster.local trafficPolicy: loadBalancer: dynamicSubset: subsetSelectors: - keys: - stage - version上記のデスティネーション ルールは、stage タグと version タグによって helloworld サービスのワークロードをグループ化します。この例では、デプロイされたワークロードはこのルールによって次のサブセットに分割されます。
サブセット
ポッド
IP アドレス
stage = dev
version = v1
helloworld-dev-v1-67b6876778-nf7pz
192.168.0.5
stage = dev
version = v2
helloworld-dev-v2-68f65bbc99-v957l
192.168.0.1
stage = dev
version = v3
helloworld-dev-v3-7f6978bc56-hqzgg
192.168.0.252
stage = prod
version = v2
helloworld-prod-v2-b5745b949-p8rc4
192.168.0.103
stage = prod
version = v3
helloworld-prod-v3-6768bf56f8-6bd6h
192.168.0.104
helloworld-prod-v3-6768bf56f8-6bd6h
192.168.0.6
次のコンテンツを使用して、helloworld サービスの仮想サービスを作成し、リクエストと
key値で指定された動的サブネット間のマッピングを確立します。詳細については、「仮想サービスの管理」をご参照ください。上記の仮想サービスは、次の操作を指定します。
リクエスト内の
x-versionという名前のヘッダーを、versionという名前のサブネット キーにマップします。リクエストにx-versionという名前のヘッダーが含まれていない場合は、デフォルト値v3が使用されます。リクエスト内の
x-stageという名前のヘッダーを、stageという名前のサブネット キーにマップします。リクエストにx-stageという名前のヘッダーが含まれていない場合は、デフォルト値prodが使用されます。
kubeconfig ファイルの情報に基づいて、kubectl を使用して ACK クラスタに接続します。次に、次のコマンドを実行して、sleep アプリケーションが dev 環境の helloworld アプリケーションの v1 バージョンにアクセスできるようにします。
kubectl を使用してクラスタを管理する方法の詳細については、「クラスタの kubeconfig ファイルを取得し、kubectl を使用してクラスタに接続する」をご参照ください。
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: dev' -H 'x-version: v1' helloworld:8000予期される出力:
Welcome to helloworld stage: dev, version: v1, ip: 192.168.0.5出力は、リクエストが
stageがdevでversionがv1のポッドにルーティングされていることを示しており、これは予期されたとおりです。
手順 3: サブネットのフォールバック ポリシーを構成する
v1 バージョンは prod 環境にデプロイされていません。 prod 環境の v1 バージョンにアクセスしようとすると、サブネットが存在しないためエラーが報告されます。
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: prod' -H 'x-version: v1' helloworld:8000
予期される出力:
no healthy upstream # サブネットが存在しないためエラーが報告されます。サブネットが存在しない場合のアクセスエラーを回避するために、動的グループ化ルールにフォールバック ポリシーを構成できます。次のセクションでは、ASM 動的グループ化でサポートされている 3 つのフォールバック ポリシーについて説明します: NO_FALLBACK、ANY_ENDPOINT、DEFAULT_SUBSET。
NO_FALLBACK
このフォールバック ポリシーが動的グループ化ルールに適用される場合、一致するサブネットがないリクエストに対して no healthy upstream エラーが報告されます。
次のデスティネーション ルールを使用して、
stageとversionで指定されたグループ化ルールのfallbackPolicyをNO_FALLBACKに設定します。詳細については、「デスティネーション ルールの管理」をご参照ください。apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: helloworld namespace: default spec: host: helloworld.default.svc.cluster.local trafficPolicy: loadBalancer: dynamicSubset: subsetSelectors: - fallbackPolicy: NO_FALLBACK keys: - stage - version次のコマンドを実行して、
stageがprodでversionがv1の helloworld アプリケーションにアクセスします。kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: prod' -H 'x-version: v1' helloworld:8000予期される出力:
no healthy upstream # サブネットが存在しないためエラーが報告されます。
ANY_ENDPOINT
このフォールバック ポリシーが動的グループ化ルールに適用される場合、一致するサブネットがないリクエストはサービスの任意のエンドポイントにルーティングされます。
次のデスティネーション ルールを使用して、
stageとversionで指定されたグループ化ルールのfallbackPolicyをANY_ENDPOINTに設定します。詳細については、「デスティネーション ルールの管理」をご参照ください。apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: helloworld namespace: default spec: host: helloworld.default.svc.cluster.local trafficPolicy: loadBalancer: dynamicSubset: subsetSelectors: - fallbackPolicy: ANY_ENDPOINT keys: - stage - version次のコマンドを実行して、
stageがprodでversionがv1の helloworld アプリケーションにアクセスします。最初のアクセス:
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: prod' helloworld:8000予期される出力:
Welcome to helloworld stage: prod, version: v2, ip: 192.168.0.103 # 最初のアクセスは、prod 環境の v2 バージョンの helloworld アプリケーションにルーティングされます。2 番目のアクセス:
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: prod' -H 'x-version: v1' helloworld:8000予期される出力:
Welcome to helloworld stage: dev, version: v2, ip: 192.168.0.1 # 2 番目のアクセスは、dev 環境の v2 バージョンの helloworld アプリケーションにルーティングされます。出力は、リクエストが helloworld サービスのランダムなポッドにルーティングされていることを示しています。
DEFAULT_SUBSET
このフォールバック ポリシーが動的グループ化ルールに適用される場合、一致するサブネットがないリクエストは、defaultSubset フィールドで指定された keys の値と一致するサブネットにルーティングされます。
次のデスティネーション ルールを使用して、
stageとversionで指定されたグループ化ルールのfallbackPolicyをDEFAULT_SUBSETに設定し、defaultSubsetフィールドでkeysと値を構成します。詳細については、「デスティネーション ルールの管理」をご参照ください。key
値
stage
prod
version
v3
apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: helloworld namespace: default spec: host: helloworld.default.svc.cluster.local trafficPolicy: loadBalancer: dynamicSubset: defaultSubset: stage: prod version: v3 subsetSelectors: - fallbackPolicy: DEFAULT_SUBSET keys: - stage - version次のコマンドを実行して、
stageがprodでversionがv1のサブネットにアクセスします。最初のアクセス:
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: prod' -H 'x-version: v1' helloworld:8000予期される出力:
Welcome to helloworld stage: prod, version: v3, ip: 192.168.0.62 番目のアクセス:
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-stage: prod' -H 'x-version: v1' helloworld:8000予期される出力:
Welcome to helloworld stage: prod, version: v3, ip: 192.168.0.104出力は予期されたとおりです。一致するサブネットはありません。したがって、フォールバックがトリガーされ、リクエストは
stageがprodでversionがv3のサブネットにルーティングされます。
手順 4: 特定のポッドにアクセスする
特定のポッドにアクセスする場合は、ASM 動的グループ化の keys を %ip% に設定することで、ポッドを独立したサブネットに分割できます。
次のデスティネーション ルールを使用して、IP アドレスでポッドをグループ化するグループ化ルールを作成します。詳細については、「デスティネーション ルールの管理」をご参照ください。
apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: helloworld namespace: default spec: host: helloworld.default.svc.cluster.local trafficPolicy: loadBalancer: dynamicSubset: defaultSubset: stage: prod version: v3 subsetSelectors: - keys: - '%ip%'次の仮想サービスを使用して、リクエストの
x-ipヘッダーを%ip%で指定されたサブセットにマップします。これにより、リクエストはx-ipで指定された IP アドレスを持つポッドにアクセスできます。詳細については、「仮想サービスの管理」をご参照ください。apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: helloworld namespace: default spec: hosts: - helloworld.default.svc.cluster.local http: - headerToDynamicSubsetKey: - header: x-ip key: '%ip%' name: default route: - destination: host: helloworld.default.svc.cluster.local port: number: 8000IP アドレスが
192.168.0.6のポッド helloworld-prod-v3-6768bf56f8-6bd6h にアクセスする次のコマンドを実行します。アクセス操作を複数回実行します。最初のアクセス:
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-ip: 192.168.0.6' helloworld:8000予期される出力:
Welcome to helloworld stage: prod, version: v3, ip: 192.168.0.62 番目のアクセス:
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-ip: 192.168.0.6' helloworld:8000予期される出力:
Welcome to helloworld stage: prod, version: v3, ip: 192.168.0.63 番目のアクセス:
kubectl exec -it deploy/sleep -c sleep -- curl -H 'x-ip: 192.168.0.6' helloworld:8000予期される出力:
Welcome to helloworld stage: prod, version: v3, ip: 192.168.0.6出力は、リクエストが指定された IP アドレス
192.168.0.6を持つポッドにルーティングされていることを示しており、これは予期されたとおりです。
CRD フィールドの説明
VirtualService
HTTPRoute
headerToDynamicSubsetKey フィールドは、ASM の HTTPRoute リソースに追加されます。
フィールド
タイプ
説明
headerToDynamicSubsetKey
リクエスト ヘッダーと動的サブセット キーのマッピングを構成するために使用されます。配列内の各要素は、ヘッダーをキーにマップします。
HeaderToMetadataSubsetKey
HeaderToMetadataSubsetKey は、リクエスト ヘッダーから動的サブセット キーへのマッピング、およびリクエストに指定されたヘッダーが含まれていない場合に使用されるデフォルト値を指定します。
フィールド
タイプ
説明
header
string
リクエスト ヘッダーの名前。
key
string
動的サブセット キーの名前。パーセント記号(%)で囲まれた部分は、ワークロードの組み込み属性を定義します。
defaultValue
string
このデフォルト値は、リクエストにキーにマッピングするヘッダーが含まれていない場合に使用されます。デフォルト値を指定せず、リクエストにキーにマッピングするヘッダーが含まれていない場合、システムはヘッダーがないと見なし、ヘッダーの観点からは照合を実行しません。
DestinationRule
ASM では、dynamicSubset フィールドが trafficPolicy 構造に追加されます。
TrafficPolicy
フィールド
タイプ
説明
dynamicSubset
動的グループ化ルールを構成するために使用されます。
DynamicSubsetLB
フィールド
タイプ
説明
defaultSubset
map[string]string
デフォルト サブセットを構成するために使用されます。リクエストがどの動的サブセットにも一致せず、フォールバック ポリシーが DEFAULT_SUBSET の場合、このフィールドで宣言されたサブセットが選択されます。
subsetSelectors
動的グループ化ルールを構成するために使用されます。配列内の各要素は、個別のグループ化ルールを示します。
fallbackPolicy
動的サブセットが一致しない場合に使用されるフォールバック ポリシーを指定します。このフィールドを指定しない場合、デフォルト値は NO_FALLBACK です。
SubsetSelector
フィールド
タイプ
説明
keys
string[]
グループ化ディメンションのリスト。値はワークロード タグにマップされます。たとえば、値 version は、ワークロードの version という名前のタグがグループ化ディメンションとして使用されることを示します。タグに加えて、ワークロードの組み込み属性もディメンションとして使用できます。詳細については、「ワークロードの組み込み属性」をご参照ください。
fallbackPolicy
一致する動的サブセットがない場合に使用されるフォールバック ポリシーを指定します。このフィールドが指定されていない場合は、DynamicSubsetLB で指定されたフォールバック ポリシーが使用されます。
DynamicSubsetLB_FallbackPolicy
DynamicSubsetLB_FallbackPolicy は、動的サブセット ロードバランシングのフォールバック ポリシーの列挙値を指定します。次の表は、サポートされている値を示しています。
値
説明
NO_FALLBACK
フォールバックは実行されません。
ANY_ENDPOINT
一致するサブネットがないリクエストは、サービスの任意のエンドポイントにルーティングされます。
DEFAULT_SUBSET
一致するサブネットがないリクエストは、デフォルト サブセットにルーティングされます。
ワークロードの組み込み属性
属性 | タイプ | 説明 |
%ip% | string | ワークロードが実行されているポッドの IP アドレス。 |
関連情報
コントロールプレーン ログ収集とログベースのアラートを有効にして、潜在的なリスクをタイムリーに検出して解決できます。詳細については、「コントロールプレーン ログ収集とログベースのアラートを有効にする」をご参照ください。
asmctl 診断ツールをインストールして、ASM の潜在的な構成の問題を検出できます。詳細については、「ASMインスタンスの診断」をご参照ください。
仮想サービスやデスティネーション ルールなどの ASM リソースの変更に対する監査アラートを追加できます。これにより、重要なリソースが変更されたときに、アラートがアラート連絡先にタイムリーに送信されます。詳細については、「ASM リソースに対する操作の監査アラートを構成する」をご参照ください。
トラフィック管理ルール(仮想サービスやデスティネーション ルールなど)を構成して、アプリケーションのバージョン、または特定の特性を持つアプリケーションを、レーンと呼ばれる独立したランタイム環境に分離できます。さらに、トラフィック シフトを構成できます。これは、デスティネーションのバージョンまたはアプリケーションが使用できない場合に、トラフィックをベースライン バージョンまたは特定の特性を持つアプリケーションにルーティングします。詳細については、「トラフィック ルールを使用してトラフィック レーンとトラフィック シフトを構成する」をご参照ください。
サービス呼び出しのレイテンシを最小限に抑える場合は、ゾーン認識ルーティング機能を使用して、クライアントが同じゾーンにデプロイされたデスティネーション サービスを最初に呼び出すようにすることができます。詳細については、「ASM インスタンスのトポロジでゾーン認識ルーティング機能を確認する」をご参照ください。