排查无代理 gRPC 部署问题

本文档提供的信息可帮助您解决使用 Cloud Service Mesh 部署无代理 gRPC 服务时遇到的配置问题。如需了解如何使用 Client Status Discovery Service (CSDS) API 来帮助您调查 Cloud Service Mesh 问题,请参阅了解 Cloud Service Mesh 客户端状态

gRPC 应用中的 RPC 失败问题排查

您可以通过以下两种常见方法进行 gRPC 应用中的远程过程调用 (RPC) 失败问题排查:

  1. 查看 RPC 失败时返回的状态。通常,该状态包含足够的信息,ke 帮助您了解 RPC 失败的原因。

  2. 在 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。如需查看更详细的日志记录,请将级别设置为 FINERFINEST

    • Go 版 gRPC:通过设置环境变量来开启日志记录功能。

      GRPC_GO_LOG_VERBOSITY_LEVEL=99 GRPC_GO_LOG_SEVERITY_LEVEL=info
      
    • C++ 版 gRPC:如需在 C++ 中启用 gRPC 的日志记录,请参阅排查 gRPC 问题中的说明。如需启用特定于 xDS 模块的日志记录,请使用 xds_clientxds_resolvercds_lbeds_lbpriority_lbweighted_target_lblrs_lbGRPC_TRACE 环境变量来启用以下跟踪器。

    • Node.js 版 gRPC:如需在 Node.js 中启用 gRPC 的日志记录,请参阅 排查 gRPC-JS 问题中的说明。如需启用特定于 xDS 模块的日志记录,请使用 xds_clientxds_resolvercds_balancereds_balancerpriorityweighted_targetGRPC_TRACE 环境变量启用以下跟踪器。

根据 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 中的错误。
  • 确认服务账号具有正确的权限。在虚拟机或 pod 中运行的 gRPC 应用使用 Compute Engine 虚拟机主机或 Google Kubernetes Engine (GKE) 节点实例的服务账号。
  • 确认 Compute Engine 虚拟机或 GKE 集群的 API 访问权限范围已设置为允许对 Compute Engine API 进行全面访问。为此,请在创建虚拟机或集群时指定以下内容:

    --scopes=https://www.googleapis.com/auth/cloud-platform
    
  • 确认您可以通过虚拟机访问 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 通道的主机名和端口与配置中使用的网址映射中的主机规则完全匹配。
  • 确保未在多个网址映射中配置同一主机规则。
  • 确保未使用通配符。包含 * 通配符的主机规则将被忽略。

RPC 因服务不可用而失败

要排查服务不可用时的 RPC 失败问题,请尝试以下操作:

  • Google Cloud 控制台中查看 Cloud Service Mesh 的整体状态以及后端服务的状态:

    • 关联的路由映射列中,确保正确的网址映射引用后端服务。点击该列并确认主机匹配规则中指定的后端服务正确无误。
    • 后端列中,检查与后端服务关联的后端运行状况是否良好。
    • 如果后端健康状况不佳,请点击相应的后端服务并确保配置了正确的健康检查。如果防火墙规则不正确或缺失,或者虚拟机和防火墙规则中指定的标记不匹配,健康检查通常会失败。如需了解详情,请参阅创建健康检查
  • 要使 gRPC 健康检查正常运行,gRPC 后端必须实现 gRPC 健康检查协议。如果未实现此协议,请改用 TCP 健康检查。请勿将 HTTP、HTTPS 或 HTTP/2 健康检查与 gRPC 服务搭配使用。

  • 使用实例组时,确保实例组中指定的已命名端口与健康检查中使用的端口相匹配。使用网络端点组 (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 功能

安全配置未按预期生成

如果您要配置服务安全,并且安全配置未按预期生成,请检查部署中的端点政策。

Cloud Service Mesh 不支持存在两个或多个端点政策资源与端点同等匹配的场景,例如,两个或两个以上具有相同标签和端口的政策,或者两个或多个具有不同标签的政策与端点的标签相同。如需详细了解端点政策如何与端点标签匹配,请参阅 EndpointPolicy.EndpointMatcher.MetadataLabelMatcher 的 API。在这种情况下,Cloud Service Mesh 不会根据任何有冲突的政策生成安全配置。

排查服务网格的健康状况

本指南提供的信息可帮助您解决 Cloud Service Mesh 配置问题。

大多数端点运行状况不佳时的 Cloud Service Mesh 行为

为了提高可靠性,当 99% 的端点运行状况不佳时,Cloud Service Mesh 会将数据平面配置为忽略端点的运行状况。相反,数据平面会平衡所有端点之间的流量,因为服务端口可能仍然正常运行。

不健康的后端导致流量分配不理想

Cloud Service Mesh 使用附加到后端服务的 HealthCheck 资源中的信息来评估后端的健康状况。Cloud Service Mesh 使用此运行状况将流量路由到运行状况良好的最近后端。如果某些后端的健康状况不佳,则可能会继续处理流量,但分配会欠佳。例如,流量可能流向仍存在运行状况良好后端但距离客户端较远的区域,从而导致延迟。如需识别和监控后端的运行状况,请尝试以下步骤:

后续步骤