プロキシレス gRPC デプロイのトラブルシューティング
このドキュメントでは、Cloud Service Mesh を使用してプロキシレス gRPC サービスをデプロイする場合に、構成の問題を解決するために役立つ情報を提供します。Cloud Service Mesh に関する問題の調査に Client Status Discovery Service(CSDS)API を使用する方法については、Cloud Service Mesh のクライアント ステータスについてをご覧ください。
gRPC アプリケーションでの RPC エラーのトラブルシューティング
gRPC アプリケーションでリモート プロシージャ コール(RPC)エラーのトラブルシューティングを行うには、次の 2 つの方法があります。
- RPC が失敗したときに返されたステータスを確認する。通常、ステータスには、RPC の失敗の原因を把握するのに十分な情報が含まれています。 - gRPC のステータス エラーの処理については、gRPC のエラー処理のドキュメントをご覧ください。 
- gRPC-Java のステータス エラー処理の例。例外によっては、原因として他の例外があり、追加情報が得られる場合もあります。 
 
- gRPC ランタイムでロギングを有効にする。場合によっては、gRPC ランタイムログを調べて、RPC 戻りステータスに反映されていない可能性があるエラーを把握する必要があります。たとえば、期限超過を示すステータスで RPC がエラーになった場合は、ログを活用すると期限超過の原因となった根本的エラーを特定できる可能性があります。 - gRPC を実装した言語によって、gRPC ランタイムでロギングを有効にする方法は異なります。 - Java の gRPC: gRPC はロギングに - java.util.loggingを使用します。- io.grpc.levelを- FINEレベルに設定して、十分な詳細ロギングを gRPC ランタイムで有効にします。Java でロギングを有効にする一般的な方法は、ロギング構成をファイルから読み込み、コマンドライン フラグを使用して、JVM にファイルの場所を指定することです。次に例を示します。- # Create a file called logging.properties with the following contents: handlers=java.util.logging.ConsoleHandler io.grpc.level=FINE io.grpc.xds.level=FINEST java.util.logging.ConsoleHandler.level=ALL java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter # Pass the location of the file to JVM by using this command-line flag: -Djava.util.logging.config.file=logging.properties - xDS モジュール固有のロギングを有効にするには、 - io.grpc.xds.levelを- FINEに設定します。より詳細なロギングを表示するには、レベルを- FINERまたは- FINESTに設定します。
- Go の gRPC: ロギングを有効にするには、環境変数を設定します。 - GRPC_GO_LOG_VERBOSITY_LEVEL=99 GRPC_GO_LOG_SEVERITY_LEVEL=info 
- C++ の gRPC: C++ で gRPC によるロギングを有効にする方法については、gRPC のトラブルシューティングをご覧ください。xDS モジュール固有のロギングを有効にするには、 - GRPC_TRACE環境変数を使用して、トレーサー(- xds_client、- xds_resolver、- cds_lb、- eds_lb、- priority_lb、- weighted_target_lb、- lrs_lb)を有効にします。
- Node.js の gRPC: Node.js で gRPC によるロギングを有効にする方法については、gRPC-JS のトラブルシューティングをご覧ください。xDS モジュール固有のロギングを有効にするには、 - GRPC_TRACE環境変数を使用して、トレーサー(- xds_client、- xds_resolver、- cds_balancer、- eds_balancer、- priority、- weighted_target)を有効にします。
 
RPC ステータスまたはランタイムログ内のエラーによっては、問題が次のいずれかのカテゴリに分類される可能性があります。
Cloud Service Mesh に接続できない
接続の問題を解決するには、次のことをお試しください。
- ブートストラップ ファイルの server_uri の値が、trafficdirector.googleapis.com:443であることを確認します。
- 環境変数 GRPC_XDS_BOOTSTRAPが定義され、ブートストラップ ファイルを指していることを確認します。
- gRPC チャネルを作成するときに URI で xdsスキームを使用していることを確認してください。
- コンピューティング インスタンスの作成とプロジェクト内のネットワークの変更に必要な IAM 権限が付与されていることを確認してください。
- Traffic Director API にアクセスするためのサービス アカウントを有効化していることを確認してください。Google Cloud コンソールの、プロジェクトの [API とサービス] で、Traffic Director API のエラーを探します。
- サービス アカウントに正しい権限が付与されていることを確認します。VM または Pod で実行されている gRPC アプリケーションは、Compute Engine VM ホストか Google Kubernetes Engine(GKE)ノード インスタンスのサービス アカウントを使用します。
- Compute Engine の VM または GKE クラスタの API アクセス スコープが、Compute Engine API へのフルアクセスを許可するように設定されていることを確認します。これを行うには、VM またはクラスタの作成時に以下を指定します。 - --scopes=https://www.googleapis.com/auth/cloud-platform 
- VM から - trafficdirector.googleapis.com:443にアクセスできることを確認します。アクセスに問題がある場合は、ファイアウォールで TCP ポート- 443経由の- trafficdirector.googleapis.comへのアクセスがブロックされている可能性があります。また、- trafficdirector.googleapis.comホスト名の DNS 解決に問題がある可能性があります。
URI に指定されたホスト名を解決できない
ログに、次のようなエラー メッセージが表示されることがあります。
[Channel<1>: (xds:///my-service:12400)] Failed to resolve name. status=Status{code=UNAVAILABLE, description=NameResolver returned no usable address. addrs=[], attrs={}
ホスト名解決の問題をトラブルシューティングするには、次のことをお試しください。
- サポートされている gRPC バージョンと言語を使用していることを確認します。
- URI に含まれる、gRPC チャネルの作成に使用されるポートが、構成で使用される転送ルールのポート値と一致していることを確認します。URI にポートが指定されていない場合は、値 80が転送ルールの照合に使用されます。
- URI に含まれている、gRPC チャネルの作成に使用されるホスト名とポートが、構成で使用される URL マップのホストルールと完全に一致することを確認します。
- 同じホストルールを複数の URL マップで構成していないことを確認します。
- ワイルドカードが使用されていないことを確認します。*ワイルドカード文字を含むホストルールは無視されます。
サービスが利用できないため、RPC が失敗した
サービスが利用できない場合に RPC エラーのトラブルシューティングを行うには、以下を試します。
- Google Cloud コンソールで、Cloud Service Mesh の全体的なステータスとバックエンド サービスのステータスを確認します。 - [関連付けられているルーティング ルール マップ] 列で、正しい URL マップがバックエンド サービスを参照していることを確認します。列をクリックして、ホスト マッチング ルールで指定されたバックエンド サービスが正しいことを確認します。
- [バックエンド] 列で、バックエンド サービスに関連付けられたバックエンドが正常であることを確認します。
- バックエンドが異常な状態である場合は、対応するバックエンド サービスをクリックし、適切なヘルスチェックが構成されていることを確認します。一般に、ヘルスチェックでエラーになるのは、ファイアウォール ルールが正しくないか存在しない場合、あるいは VM とファイアウォール ルールで指定されたタグが一致しない場合です。詳細については、ヘルスチェックの作成をご覧ください。
 
- gRPC ヘルスチェックが正常に機能するには、gRPC バックエンドで gRPC ヘルスチェック プロトコルを実装する必要があります。このプロトコルが実装されていない場合は、代わりに TCP ヘルスチェックを使用します。gRPC サービスでは、HTTP、HTTPS、HTTP/2 のヘルスチェックは使用しないでください。 
- インスタンス グループを使用する場合は、インスタンス グループで指定された名前付きポートがヘルスチェックで使用されているポートと一致していることを確認します。ネットワーク エンドポイント グループ(NEG)を使用する場合は、GKE サービス仕様の NEG アノテーションが正しく、ヘルスチェックが NEG の処理ポートを使用するように構成されていることを確認します。 
- エンドポイント プロトコルが - GRPCとして構成されていることを確認します。
ロード バランシング ポリシーがサポートされていないため、RPC が失敗した
ログに、次のいずれかに似たエラー メッセージが表示されることがあります。
error parsing "CDS" response: resource "cloud-internal-istio:cloud_mp_248715": unexpected lbPolicy RING_HASH in response
error={"description":"errors parsing CDS response",
"file":"external/com_github_grpc_grpc/src/core/ext/xds/xds_api.cc", "file_line":3304,
"referenced_errors":[{"description":"cloud-internal-istio:cloud_mp_248715: LB policy is not supported."
WARNING: RPC failed: Status{code=INTERNAL, description=Panic! This is a bug!, cause=java.lang.NullPointerException: provider
at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:910)
at io.grpc.internal.ServiceConfigUtil$PolicySelection.<init>(ServiceConfigUtil.java:418)
at io.grpc.xds.CdsLoadBalancer2$CdsLbState.handleClusterDiscovered(CdsLoadBalancer2.java:190)
これは、使用されているクライアントの特定の言語とバージョンで RING_HASH がサポートされていないことが原因です。この問題を解決するには、サポートされているロード バランシング ポリシーのみを使用するようにバックエンド サービスの構成を更新するか、サポートされているバージョンにクライアントをアップグレードします。サポートされているクライアントのバージョンについては、gRPC の xDS の機能をご覧ください。
セキュリティ構成が想定どおりに生成されない
サービス セキュリティの構成中、セキュリティ構成が想定どおりに生成されない場合は、Deployment のエンドポイント ポリシーを調べます。
Cloud Service Mesh は、1 つのエンドポイントに同等に一致する 2 つ以上のエンドポイント ポリシー リソースがあるシナリオをサポートしていません。たとえば、同じラベルとポート向けの 2 つのポリシーや、1 つのエンドポイントのラベルに同等に一致する異なるラベル向けの 2 つ以上のポリシーです。エンドポイント ポリシーを 1 つのエンドポイントのラベルと一致させる方法については、EndpointPolicy.EndpointMatcher.MetadataLabelMatcher の API をご覧ください。このような状況では、Cloud Service Mesh はいかなる競合するポリシーからもセキュリティ構成を生成しません。
サービス メッシュの状態のトラブルシューティング
このガイドでは、Cloud Service Mesh の構成に関する問題を解決するための情報をご案内します。
大部分のエンドポイントが正常でない場合の Cloud Service Mesh の挙動
信頼性を高めるために、99% のエンドポイントが異常な状態になると、Cloud Service Mesh はエンドポイントのヘルス ステータスを無視するようにデータプレーンを構成します。データプレーンは、サービスポートが引き続き機能している可能性があることから、すべてのエンドポイントでトラフィックを分散します。
正常でないバックエンドが原因でトラフィックが最適に分散されない
Cloud Service Mesh では、バックエンド サービスに接続されている HealthCheck リソースの情報を使用して、バックエンドの状態が評価され、このヘルス ステータスを使って、最も近い正常なバックエンドにトラフィックがルーティングされます。バックエンドの一部が正常でない場合でも、トラフィックは引き続き処理できますが、分散が最適化されません。たとえば、正常なバックエンドがまだ存在するリージョンにトラフィックが流れたとしても、そのリージョンはクライアントから非常に遠く、レイテンシが発生する可能性があります。バックエンドのヘルス ステータスを特定してモニタリングするには、次の手順を試してください。
-  Google Cloud コンソールでバックエンド サービスのヘルス ステータスを確認します。
 Cloud Service Mesh サービスに移動
- HealthCheckリソースでロギングが有効になっていることを確認します。
- ヘルスチェックが最近失敗するようになった場合は、HealthCheckの構成に変更が加えられていないか、Cloud Audit Logs を確認します。
次のステップ
- Cloud Service Mesh の仕組みについては、Cloud Service Mesh の概要をご覧ください。
- Cloud Service Mesh がプロキシレス gRPC サービスと連携する仕組みについては、プロキシレス gRPC サービスを備えた Cloud Service Mesh の概要をご覧ください。
- Cloud Service Mesh の一般的なトラブルシューティングについては、Envoy を使用したデプロイのトラブルシューティングをご覧ください。
- Cloud Service Mesh の使用に関するその他のサポートについては、サポートの利用をご覧ください。