Service Mesh (ASM) では、ヘッダーのキーと値に一致条件を設定できます。これにより、ASM はリクエストヘッダーに基づいてトラフィックを動的にリダイレクトできます。このトピックでは、ヘッダーに基づいて ASM のアプリケーションのトラフィックをリダイレクトする方法について説明します。
gRPC サーバーとクライアントでヘッダーを取得する
GRPC サーバーでヘッダーを取得する
基本的なメソッド
Java を使用して、gRPC サーバーでヘッダーを取得する基本的なメソッドを実装します。
ServerInterceptor操作のinterceptCall(ServerCall<ReqT, RespT> call,final Metadata m,ServerCallHandler<ReqT, RespT> h)メソッドを実装します。次に、String v = m.get(k)コマンドを実行して、サーバーでヘッダーを取得します。get()メソッドの入力パラメーターのタイプはMetadata.Key<String>です。Go を使用して、gRPC サーバーでヘッダーを取得する基本的なメソッドを実装します。
metadata.FromIncomingContext(ctx)(md MD, ok bool)メソッドを実装します。MD のフォーマットはmap[string][]stringです。Node.js を使用して、gRPC サーバーでヘッダーを取得する基本的なメソッドを実装します。
call.metadata.getmap()メソッドを実装します。戻り値のタイプは[key: string]: MetadataValueです。MetadataValueのタイプはstring/Bufferです。Python を使用して、gRPC サーバーでヘッダーを取得する基本的なメソッドを実装します。
context.invocation_metadata()メソッドを実装します。戻り値は('k','v')のフォーマットの 2 タプル配列です。キーと値のペアはm.key, m.valueから取得できます。
単項 RPC
Java を使用して、サーバーでヘッダーを取得する単項リモートプロシージャコール (RPC) メソッドを実装します。
ヘッダーはインターセプトされます。
Go を使用して、サーバーでヘッダーを取得する単項 RPC メソッドを実装します。
メソッドで
metadata.FromIncomingContext(ctx)を呼び出します。ctx パラメーターの値は、Talk メソッドの入力パラメーターから取得されます。Node.js を使用して、サーバーでヘッダーを取得する単項 RPC メソッドを実装します。
メソッドで
call.metadata.getMap()を呼び出します。Python を使用して、サーバーでヘッダーを取得する単項 RPC メソッドを実装します。
メソッドで
context.invocation_metadata()を呼び出します。
サーバー ストリーミング RPC
Java を使用して、サーバーでヘッダーを取得するサーバー ストリーミング RPC メソッドを実装します。
ヘッダーはインターセプトされます。
Go を使用して、サーバーでヘッダーを取得するサーバー ストリーミング RPC メソッドを実装します。
メソッドで
metadata.FromIncomingContext(ctx)を呼び出します。stream.Context()メソッドを呼び出して、TalkOneAnswerMore メソッドの入力パラメーターstreamからctxパラメーターの値を取得できます。Node.js を使用して、サーバーでヘッダーを取得するサーバー ストリーミング RPC メソッドを実装します。
メソッドで
call.metadata.getMap()を呼び出します。Python を使用して、サーバーでヘッダーを取得するサーバー ストリーミング RPC メソッドを実装します。
メソッドで
context.invocation_metadata()を呼び出します。
クライアント ストリーミング RPC
Java を使用して、サーバーでヘッダーを取得するクライアント ストリーミング RPC メソッドを実装します。
ヘッダーはインターセプトされます。
Go を使用して、サーバーでヘッダーを取得するクライアント ストリーミング RPC メソッドを実装します。
メソッドで
metadata.FromIncomingContext(ctx)を呼び出します。stream.Context()メソッドを呼び出して、TalkMoreAnswerOne メソッドの入力パラメーターstreamからctxパラメーターの値を取得できます。Node.js を使用して、サーバーでヘッダーを取得するクライアント ストリーミング RPC メソッドを実装します。
メソッドで
call.metadata.getMap()を呼び出します。Python を使用して、サーバーでヘッダーを取得するクライアント ストリーミング RPC メソッドを実装します。
メソッドで
context.invocation_metadata()を呼び出します。
双方向ストリーミング RPC
Java を使用して、サーバーでヘッダーを取得する双方向ストリーミング RPC メソッドを実装します。
ヘッダーはインターセプトされます。
Go を使用して、サーバーでヘッダーを取得する双方向ストリーミング RPC メソッドを実装します。
メソッドで
metadata.FromIncomingContext(ctx)を呼び出します。stream.Context()メソッドを呼び出して、TalkBidirectional メソッドの入力パラメーターstreamからctxパラメーターの値を取得できます。Node.js を使用して、サーバーでヘッダーを取得する双方向ストリーミング RPC メソッドを実装します。
メソッドで
call.metadata.getMap()を呼び出します。Python を使用して、サーバーでヘッダーを取得する双方向ストリーミング RPC メソッドを実装します。
メソッドで
context.invocation_metadata()を呼び出します。
クライアントからヘッダーを送信する
基本的なメソッド
Java を使用して、クライアントからヘッダーを送信する基本的なメソッドを実装します。
ClientInterceptor操作のinterceptCall(MethodDescriptor<ReqT, RespT> m, CallOptions o, Channel c)メソッドを実装します。ClientCall<ReqT, RespT>タイプのstart((Listener<RespT> l, Metadata h))メソッドを実装します。次に、h.put(k, v)を実行して、クライアントでヘッダーを送信します。putの入力パラメーターkのタイプはMetadata.Key<String>で、入力パラメーターvのタイプはStringです。Go を使用して、クライアントからヘッダーを送信する基本的なメソッドを実装します。
metadata.AppendToOutgoingContext(ctx,kv ...) context.ContextNode.js を使用して、クライアントからヘッダーを送信する基本的なメソッドを実装します。
metadata=call.metadata.getMap()metadata.add(key, headers[key])Python を使用して、クライアントからヘッダーを送信する基本的なメソッドを実装します。
metadata_dict = {}コマンドで変数を次のフォーマットで設定します:metadata_dict[c.key] = c.value。list(metadata_dict.items())を使用して、metadata_dict 配列のデータのタイプをlist tupleに変換します。
単項 RPC
Java を使用して、クライアントからヘッダーを送信する単項 RPC メソッドを実装します。
ヘッダーはインターセプトされます。
Go を使用して、クライアントでヘッダーを送信する単項 RPC メソッドを実装します。
メソッドで
metadata.AppendToOutgoingContext(ctx,kv)を呼び出します。Node.js を使用して、クライアントからヘッダーを送信する単項 RPC メソッドを実装します。
基本的なメソッドを呼び出します。
Python を使用して、クライアントからヘッダーを送信する単項 RPC メソッドを実装します。
基本的なメソッドを呼び出します。
サーバー ストリーミング RPC
Java を使用して、クライアントからヘッダーを送信するサーバー ストリーミング RPC メソッドを実装します。
ヘッダーはインターセプトされます。
Go を使用して、クライアントからヘッダーを送信するサーバー ストリーミング RPC メソッドを実装します。
メソッドで
metadata.AppendToOutgoingContext(ctx,kv)を呼び出します。Node.js を使用して、クライアントからヘッダーを送信するサーバー ストリーミング RPC メソッドを実装します。
基本的なメソッドを呼び出します。
Python を使用して、クライアントからヘッダーを送信するサーバー ストリーミング RPC メソッドを実装します。
基本的なメソッドを呼び出します。
クライアント ストリーミング RPC
Java を使用して、クライアントからヘッダーを送信するクライアント ストリーミング RPC メソッドを実装します。
ヘッダーはインターセプトされます。
Go を使用して、クライアントからヘッダーを送信するクライアント ストリーミング RPC メソッドを実装します。
メソッドで
metadata.AppendToOutgoingContext(ctx,kv)を呼び出します。Node.js を使用して、クライアントからヘッダーを送信するクライアント ストリーミング RPC メソッドを実装します。
基本的なメソッドを呼び出します。
Python を使用して、クライアントからヘッダーを送信するクライアント ストリーミング RPC メソッドを実装します。
基本的なメソッドを呼び出します。
双方向ストリーミング RPC
Java を使用して、クライアントからヘッダーを送信する双方向ストリーミング RPC メソッドを実装します。
ヘッダーはインターセプトされます。
Go を使用して、クライアントからヘッダーを送信する双方向ストリーミング RPC メソッドを実装します。
メソッドで
metadata.AppendToOutgoingContext(ctx,kv)を呼び出します。Node.js を使用して、クライアントからヘッダーを送信する双方向ストリーミング RPC メソッドを実装します。
基本的なメソッドを呼び出します。
Python を使用して、クライアントからヘッダーを送信する双方向ストリーミング RPC メソッドを実装します。
基本的なメソッドを呼び出します。
プロパガンダヘッダー
トレース分析では、トレースの完全な情報を取得するために、アップストリームリンクのメタデータをダウンストリームに渡す必要があります。したがって、サーバーで取得されたトレース関連のヘッダー情報は、ダウンストリームにリクエストを送信するクライアントに渡す必要があります。
Go、Node.js、および Python を使用して実装される通信モデルの操作は、ヘッダーを受信できます。したがって、4 つの通信モデルの操作を使用して、次の 3 つのアクションを順番に実装できます。まず、サーバーがヘッダーを読み取ります。次に、サーバーがヘッダーを渡します。最後に、クライアントがヘッダーを送信します。
Java を使用して実装された通信モデルの操作は、順序付けられたプロセスでヘッダーを伝播するために使用することはできません。これは、Java が 2 つのインターセプタを使用してヘッダーを読み書きするためです。読み取りインターセプタのみがトレースの一意の ID を取得します。さらに、gRPC サービスは同時にリクエストを受信および送信する場合があります。その結果、2 つのインターセプタは、トレースを表示するための最も直感的な方法であるキャッシングを使用して接続することはできません。
Java は、メタデータコンテキスト伝播を使用してヘッダーをトレースします。
サーバーインターセプタがヘッダーを読み取るとき、headers は ctx.withValue(key, metadata) を使用してコンテキストに書き込まれます。key パラメーターのタイプは Context.Key<String> です。次に、クライアントインターセプタは key.get() を使用してコンテキストから headers を読み取ります。デフォルトでは、get メソッドは Context.current() を使用します。これにより、ヘッダーが読み書きされるときに同じコンテキストが使用されることが保証されます。
ヘッダーが伝播できる場合、gRPC クライアントとサーバー間のリクエストと応答メッセージをトレースできます。
ASM インスタンスのトポロジーをデプロイして検証する
トラフィックをリダイレクトする前に、アプリケーションが存在する ASM インスタンスのトポロジーをデプロイして検証する必要があります。ASM インスタンスのトポロジーが期待どおりに機能することを確認してください。
サンプルプロジェクトの tracing フォルダには、Java、Go、Node.js、および Python のデプロイメントスクリプトが含まれています。この例では、Go デプロイメントスクリプトを使用して、ASM インスタンスのトポロジーをデプロイおよび検証します。
cd go
# ASM インスタンスのトポロジーをデプロイします。
sh apply.sh
# ASM インスタンスのトポロジーを検証します。
sh test.sh例外が発生しない場合、ASM インスタンスのトポロジーは期待どおりに機能します。
次の図は、デプロイされた ASM インスタンスのトポロジーを示しています。
トラフィックのリダイレクト
ASM で仮想サービスを作成して、ヘッダーのキーと値に一致条件を設定できます。これにより、ASM はリクエストヘッダーに基づいてトラフィックを動的にリダイレクトできます。さらに、gRPC バージョンと gRPC API 操作に基づいて、アプリケーションのトラフィックをきめ細かくシェーピングできます。詳細については、「gRPC サーバーへのトラフィックのシェーピング」をご参照ください。次の例では、ヘッダーに server-version=go が含まれるすべてのリクエストを Go ベースの gRPC サーバーに転送する仮想サービスを作成する方法を示します。
ASM コンソールにログインします。
左側のナビゲーションウィンドウで、 を選択します。
[メッシュ管理] ページで、設定する ASM インスタンスを見つけます。ASM インスタンスの名前をクリックするか、[アクション] 列の [管理] をクリックします。
ASM インスタンスの詳細ページで、左側のナビゲーションウィンドウから を選択します。表示されたページで、[YAML から作成] をクリックします。
[作成] ページで、必要に応じて名前空間を選択し、次の内容をコードエディタにコピーしてから、[作成] をクリックします。
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: namespace: grpc-best name: grpc-server-vs spec: hosts: - "*" gateways: - grpc-gateway http: - match: - headers: server-version: exact: go route: - destination: host: grpc-server-svc subset: v2 weight: 100