排查 Envoy 部署问题

本指南提供的信息可帮助您解决使用 Google API 运行 Cloud Service Mesh 时 Envoy 客户端的配置问题。如需了解如何使用 Client Status Discovery Service (CSDS) API 来帮助您调查 Cloud Service Mesh 问题,请参阅了解 Cloud Service Mesh 客户端状态

确定虚拟机上安装的 Envoy 版本

使用以下说明来验证在虚拟机 (VM) 实例上运行哪个 Envoy 版本。

如需验证或检查 Envoy 版本,您可以执行以下任一操作:

检查 gce-service-proxy/proxy-version 路径下的虚拟机客机特性:

  gcloud compute --project cloud-vm-mesh-monitoring instances get-guest-attributes INSTANCE_NAME 
--zone ZONEc --query-path=gce-service-proxy/proxy-version

NAMESPACE KEY VALUE gce-service-proxy proxy-version dc78069b10cc94fa07bb974b7101dd1b42e2e7bf/1.15.1-dev/Clean/RELEASE/BoringSSL

您可以使用如下查询在 Google Cloud Console 的“虚拟机实例详情 Logging”页面中检查 Cloud Logging 实例日志:

  resource.type="gce_instance"
  resource.labels.instance_id="3633122484352464042"
  jsonPayload.message:"Envoy version"
  

您将收到如下响应:

  {
    "insertId": "9zy0btf94961a",
    "jsonPayload": {
      "message": "Envoy Version: dc78069b10cc94fa07bb974b7101dd1b42e2e7bf/1.15.1-dev/Clean/RELEASE/BoringSSL",
      "localTimestamp": "2021-01-12T11:39:14.3991Z"
    },
    "resource": {
      "type": "gce_instance",
      "labels": {
        "zone": "asia-southeast1-b",
        "instance_id": "3633122484352464042",
        "project_id": "cloud-vm-mesh-monitoring"
      }
    },
    "timestamp": "2021-01-12T11:39:14.399200504Z",
    "severity": "INFO",
    "logName": "projects/cloud-vm-mesh-monitoring/logs/service-proxy-agent",
    "receiveTimestamp": "2021-01-12T11:39:15.407023427Z"
  }
  

使用 SSH 连接到虚拟机并检查二进制文件版本:

  YOUR_USER_NAME@backend-mig-5f5651e1-517a-4269-b457-f6bdcf3d98bc-m3wt:~$ /usr/local/bin/envoy --version

/usr/local/bin/envoy version: dc78069b10cc94fa07bb974b7101dd1b42e2e7bf/1.15.1-dev/Clean/RELEASE/BoringSSL

使用 SSH 以 root 用户身份连接到虚拟机和管理界面:

  root@backend-mig-5f5651e1-517a-4269-b457-f6bdcf3d98bc-m3wt:~# curl localhost:15000/server_info
  {
   "version": "dc78069b10cc94fa07bb974b7101dd1b42e2e7bf/1.15.1-dev/Clean/RELEASE/BoringSSL",
   "state": "LIVE",
   "hot_restart_version": "disabled",
   ...
  }
  

Envoy 日志位置

如需排查某些问题,您需要检查 Envoy 代理日志。

您可以使用 SSH 连接到虚拟机实例,以获取日志文件。路径可能如下所示。

  /var/log/envoy/envoy.err.log
  

代理不连接到 Cloud Service Mesh

如果您的代理未连接到 Cloud Service Mesh,请执行以下操作:

  • 检查 Envoy 代理日志中是否存在关于连接到 trafficdirector.googleapis.com 的任何错误。

  • 如果您已(通过使用 iptables)设置了 netfilter 以将所有流量重定向到 Envoy 代理,请确保您以其身份运行代理的用户 (UID) 不会被重定向。否则,这会导致流量不断回送至代理。

  • 确保您已为项目启用了 Cloud Service Mesh API。在项目的 API 和服务下,查找 Cloud Service Mesh API 的错误。

  • 在创建虚拟机时指定以下内容,以确认该虚拟机的 API 访问权限范围已设置为授予对 Google Cloud API 的完整访问权限:

    --scopes=https://www.googleapis.com/auth/cloud-platform
    
  • 确认服务账号具有正确的权限。如需了解详情,请参阅允许服务账号访问 Traffic Director API

  • 确认您可以通过虚拟机访问 trafficdirector.googleapis.com:443。如果此访问存在问题,可能的原因是防火墙阻止了通过 TCP 端口 443 访问 trafficdirector.googleapis.com,或是 trafficdirector.googleapis.com 主机名存在 DNS 解析问题。

  • 如果您要为边车代理使用 Envoy,请确认 Envoy 版本为 1.24.9 或更高版本。

无法访问通过 Cloud Service Mesh 配置的服务

如果无法访问通过 Cloud Service Mesh 配置的服务,请确认边车代理正在运行并且能够连接到 Cloud Service Mesh。

如果使用 Envoy 作为边车代理,则可以通过运行以下命令进行确认:

  1. 在命令行中,确认 Envoy 进程是否正在运行:

    ps aux | grep envoy
    
  2. 检查 Envoy 的运行时配置,以确认 Cloud Service Mesh 配置了动态资源。要查看配置,请运行以下命令:

    curl http://localhost:15000/config_dump
    
  3. 确保已正确设置边车代理的流量拦截功能。 对于使用 iptables 进行的重定向设置,请运行 iptables 命令,然后 grep 输出以确保您的规则发挥作用:

    sudo iptables -t nat -S | grep ISTIO
    

    以下输出示例是 iptables 拦截虚拟 IP 地址 (VIP) 10.0.0.1/32 并将其转发到在端口 15001 上运行的 Envoy 代理 (UID1006):

    -N ISTIO_IN_REDIRECT
    -N ISTIO_OUTPUT
    -N ISTIO_REDIRECT
    -A OUTPUT -p tcp -j ISTIO_OUTPUT
    -A ISTIO_IN_REDIRECT -p tcp -j REDIRECT --to-ports 15001
    -A ISTIO_OUTPUT -m owner --uid-owner 1006 -j RETURN
    -A ISTIO_OUTPUT -d 127.0.0.1/32 -j RETURN
    -A ISTIO_OUTPUT -d 10.0.0.1/32 -j ISTIO_REDIRECT
    -A ISTIO_OUTPUT -j RETURN
    

如果虚拟机实例是通过 Google Cloud Console 创建的,则在重启之前,某些与 IPv6 相关的模块不会安装,而且无法使用。这会导致 iptables 因缺少依赖项而失败。在这种情况下,请重启虚拟机并重新执行设置过程,这样应该可以解决问题。使用 Google Cloud CLI 创建的 Compute Engine 虚拟机预计不会出现此问题。

配置 Envoy 访问日志记录时无法访问服务

如果您按照配置 Cloud Service Mesh 的 Envoy 引导属性中的说明使用了 TRAFFICDIRECTOR_ACCESS_LOG_PATH 配置 Envoy 访问日志,请确保运行 Envoy 代理的系统用户有权写入指定的访问日志位置。

如果未提供必要的权限,则系统将不会在代理上对侦听器进行编程;您可以通过在 Envoy 代理日志中检查以下错误消息来检测此情况:

gRPC config for type.googleapis.com/envoy.api.v2.Listener rejected:
Error adding/updating listener(s) TRAFFICDIRECTOR_INTERCEPTION_PORT:
unable to open file '/var/log/envoy.log': Permission denied

要解决该问题,请更改所选文件的权限,使 Envoy 用户可写入访问日志。

Envoy 日志中指示配置问题的错误消息

本部分适用于使用负载均衡 API 的部署。

如果您在 Cloud Service Mesh 配置方面遇到问题,可能会在 Envoy 日志中看到以下任何错误消息:

  • warning envoy config    StreamAggregatedResources gRPC config stream closed:
    5, Cloud Service Mesh configuration was not found for network "VPC_NAME" in
    project "PROJECT_NUMBER".
  • warning envoy upstream  StreamLoadStats gRPC config stream closed:
    5, Cloud Service Mesh configuration was not found for network "VPC_NAME" in
    project "PROJECT_NUMBER".
  • warning envoy config    StreamAggregatedResources gRPC config stream closed:
    5, Requested entity was not found.
  • warning envoy upstream  StreamLoadStats gRPC config stream closed:
    5, Requested entity was not found.
  • Cloud Service Mesh configuration was not found.

最后一条错误消息 (Traffic Director configuration was not found) 通常表示 Envoy 正在从 Cloud Service Mesh 请求配置,但找不到匹配的配置。当 Envoy 连接到 Cloud Service Mesh 时,它会显示一个 VPC 网络名称(例如 my-network)。然后,Cloud Service Mesh 会查找具有 INTERNAL_SELF_MANAGED 负载均衡方案并引用同一 VPC 网络名称的转发规则。

要消除此错误,请执行以下操作:

  1. 请确保您的网络中存在具有负载平衡方案 INTERNAL_SELF_MANAGED 的转发规则。请记下该转发规则的 VPC 网络名称。

  2. 如果您将 Cloud Service Mesh 与 Compute Engine 上的自动 Envoy 部署结合使用,请确保提供给 --service-proxy:network 标志的值与转发规则的 VPC 网络名称匹配。

  3. 如果您将 Cloud Service Mesh 与 Compute Engine 上的手动 Envoy 部署结合使用,请检查 Envoy 引导文件是否包含以下内容:

    1. 确保 TRAFFICDIRECTOR_NETWORK_NAME 变量的值与转发规则的 VPC 网络名称匹配。
    2. 请确保在 TRAFFICDIRECTOR_GCP_PROJECT_NUMBER 变量中设置项目编号。
  4. 如果您要在 GKE 上部署,并且使用自动注入器,请确保根据为 GKE Pod 设置自动 Envoy 注入的 Cloud Service Mesh 中的说明正确配置项目编号和 VPC 网络名称。

Compute Engine 问题排查

本部分介绍如何对 Compute Engine 的 Envoy 部署进行问题排查。

Envoy 和虚拟机引导过程和进一步的生命周期管理操作可能因多种原因而失败,包括临时连接问题、代码库损坏、引导脚本和虚拟机代理中的 Bug 以及意外用户操作。

用于问题排查的通信渠道

Google Cloud 提供了通信渠道,可帮助您了解虚拟机上的组件的引导过程和当前状态。

虚拟串行端口输出日志记录

虚拟机的操作系统、BIOS 和其他系统级实体通常会将输出写入串行端口。此输出对于排查系统崩溃、启动失败、启动问题和关机问题非常有用。

Compute Engine 引导代理会将所有已执行的操作记录到串行端口 1。这包括系统事件,从基本软件包安装(从实例的元数据服务器获取数据)、iptables 配置和 Envoy 安装状态开始。

虚拟机上的代理会记录 Envoy 进程健康状况、新发现的 Cloud Service Mesh 服务,以及在调查虚拟机问题时可能有用的任何其他信息。

Cloud Monitoring 日志记录

串行端口输出公开的数据也会记录到 Monitoring 中,Monitoring 使用 Golang 库并将日志导出到单独的日志以减少噪声。由于此日志是实例级日志,您可以在与其他实例日志相同的页面上找到服务代理日志。

虚拟机客机特性

客机特性是指应用在实例上运行期间可写入的特定类型的自定义元数据。实例上的任何应用或用户都可以对这些客机特性元数据值执行数据读写操作。

Compute Engine Envoy 引导脚本和虚拟机代理公开特性,其中包含 Envoy 引导过程和当前状态的相关信息。所有客机特性都公开在 gce-service-proxy 命名空间中:

gcloud compute instances get-guest-attributes INSTANCE_NAME  \
    --query-path=gce-service-proxy/ \
    --zone=ZONE

如果您发现任何问题,我们建议您检查客机特性 bootstrap-statusbootstrap-last-failure 的值。除 FINISHED 以外的任何 bootstrap-status 值都表示 Envoy 环境尚未配置。bookstrap-last-failure 的值可指明问题。

无法从使用启用了服务代理的实例模板创建的虚拟机访问 Cloud Service Mesh 服务

要解决此问题,请按以下步骤操作:

  1. 虚拟机上服务代理组件的安装可能尚未完成或可能失败。 使用以下命令来确定所有组件是否已正确安装:

    gcloud compute instances get-guest-attributes INSTANCE_NAME \
        --query-path=gce-service-proxy/ \
        --zone=ZONE
    

    bootstrap-status 客机特性设置为以下其中一项:

    • [none] 表示安装尚未开始。虚拟机可能仍在启动。请在几分钟后再次检查状态。
    • IN PROGRESS 表示服务代理组件的安装和配置尚未完成。重复对流程更新进行状态检查。
    • FAILED 表示组件的安装或配置失败。通过查询 gce-service-proxy/bootstrap-last-failure1 特性来检查错误消息。
    • FINISHED 表示安装和配置过程已完成并且没有任何错误。按照以下说明验证流量拦截功能和 Envoy 代理已正确配置。
  2. 没有为基于 Cloud Service Mesh 的服务正确配置虚拟机上的流量拦截功能。登录虚拟机并检查 iptables 配置:

    gcloud compute ssh INSTANCE_NAME \
        --zone=ZONE \
        sudo iptables -L -t nat
    

    SERVICE_PROXY_SERVICE_CIDRS 链中检查 SERVICE_PROXY_REDIRECT 条目,例如:

    Chain SERVICE_PROXY_SERVICE_CIDRS (1 references)
    target                   prot opt source         destination ...
    SERVICE_PROXY_REDIRECT   all  --  anywhere       10.7.240.0/20
    

    对于每项服务,destination 列中都应有匹配的 IP 地址或 CIDR。如果没有虚拟 IP 地址 (VIP) 的条目,则说明从 Cloud Service Mesh 填充 Envoy 代理配置时出现问题,或者虚拟机代理失败。

  3. Envoy 代理尚未从 Cloud Service Mesh 收到配置。登录虚拟机以检查 Envoy 代理配置:

    gcloud compute ssh INSTANCE_NAME \
        --zone=ZONE \
        sudo curl localhost:15000/config_dump
    

    检查从 Cloud Service Mesh 收到的监听器配置。例如:

    "dynamic_active_listeners": [
      ...
      "filter_chains": [{
        "filter_chain_match": {
          "prefix_ranges": [{
            "address_prefix": "10.7.240.20",
            "prefix_len": 32
          }],
          "destination_port": 80
        },
      ...
        "route_config_name": "URL_MAP/PROJECT_NUMBER.td-routing-rule-1"
      ...
    ]
    

    address_prefix 是 Cloud Service Mesh 服务的虚拟 IP 地址 (VIP)。它指向名为 td-routing-rule-1 的网址映射。检查您要连接的服务是否已包含在监听器配置中。

  4. 虚拟机上的代理未运行。 创建新的 Cloud Service Mesh 服务时,虚拟机上的代理会自动配置流量拦截。如果代理未运行,则新服务的所有流量将直接流向 VIP 地址,从而绕过 Envoy 代理和超时。

    1. 通过运行以下命令来验证虚拟机代理中的状态:

      gcloud compute instances get-guest-attributes INSTANCE_NAME \
         --query-path=gce-service-proxy/ \
         --zone=ZONE
      
    2. 检查虚拟机代理的特性。agent-heartbeat 特性的值包含代理上次执行操作或检查的时间。如果该值超过 5 分钟,则代理会卡住,您应该使用以下命令重新创建该虚拟机:

      gcloud compute instance-groups managed recreate-instance
      
    3. agent-last-failure 特性会显示代理中发生的最后一个错误。这可能是一个暂时性问题,可在代理下次检查时解决(例如,如果错误为 Cannot reach the Cloud Service Mesh API server)或可能是永久性错误。等待几分钟,然后重新检查错误。

入站流量拦截功能配置到工作负载端口,但无法从虚拟机外部连接到该端口

要解决此问题,请按以下步骤操作:

  1. 虚拟机上服务代理组件的安装可能尚未完成或可能失败。 使用以下命令来确定所有组件是否已正确安装:

    gcloud compute instances get-guest-attributes INSTANCE_NAME \
        --query-path=gce-service-proxy/ \
        --zone=ZONE
    

    bootstrap-status 客机特性设置为以下其中一项:

    • [none] 表示安装尚未开始。虚拟机可能仍在启动。请在几分钟后再次检查状态。
    • IN PROGRESS 表示服务代理组件的安装和配置尚未完成。重复对流程更新进行状态检查。
    • FAILED 表示组件的安装或配置失败。通过查询 gce-service-proxy/bootstrap-last-failure1 特性来检查错误消息。
    • FINISHED 表示安装和配置过程已完成并且没有任何错误。按照以下说明验证流量拦截功能和 Envoy 代理已正确配置。
  2. 虚拟机上的流量拦截功能未针对入站流量进行正确配置。 登录虚拟机并检查 iptables 配置:

    gcloud compute ssh INSTANCE_NAME \
        --zone=ZONE \
        sudo iptables -L -t nat
    

    SERVICE_PROXY_INBOUND 链中检查 SERVICE_PROXY_IN_REDIRECT 条目,例如:

    Chain SERVICE_PROXY_INBOUND (1 references)
    target                      prot opt source       destination ...
    SERVICE_PROXY_IN_REDIRECT   tcp  --  anywhere     anywhere  tcp dpt:mysql
    

    对于在 service-proxy:serving-ports 中定义的每个端口,destination 列中应该有一个匹配端口。如果端口没有条目,则所有入站流量都会绕过 Envoy 代理,直接进入此端口。

    验证是否没有其他规则会丢弃此端口或除某个特定端口之外的所有端口的流量。

  3. Envoy 代理尚未从 Cloud Service Mesh 收到入站端口的配置。登录虚拟机以检查 Envoy 代理配置:

    gcloud compute ssh INSTANCE_NAME \
        --zone=ZONE \
        sudo curl localhost:15000/config_dump
    

    查找从 Cloud Service Mesh 收到的inbound入站监听器配置:

    "dynamic_active_listeners": [
      ...
      "filter_chains": [{
        "filter_chain_match": {
          "prefix_ranges": [{
            "address_prefix": "10.0.0.1",
            "prefix_len": 32
          }],
          "destination_port": 80
        },
      ...
        "route_config_name": "inbound|default_inbound_config-80"
      ...
    ]
    

    inbound 开头的 route_config_name 表示为入站流量拦截目的而创建的特殊服务。检查您要连接的端口是否已包含在监听器配置中的 destination_port 下。

连接使用服务器优先协议时的问题

某些应用(如 MySQL)使用的协议规定,服务器发送第一个数据包。这意味着,初始连接时,服务器发送第一个字节。Cloud Service Mesh 不支持这些协议和应用。

排查服务网格的健康状况

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

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

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

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

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

后续步骤