排查 Traffic Director 部署问题

本指南提供的信息可帮助您解决 Traffic Director 配置问题。

代理未连接到 Traffic Director

如果 Sidecar 代理未连接到 Traffic Director,请执行以下操作:

  • 检查 Sidecar 代理日志中是否存在关于连接 trafficdirector.googleapis.com 的任何错误。
  • 如果您已通过 iptables 设置 netfilter 以将所有流量重定向到 Sidecar 代理,请确保您用来运行代理的用户身份 (UID) 不会被重定向。否则,这会导致流量不断回送至代理。
  • 确保已为项目启用 Traffic Director API。在项目的“API 和服务”下,查找 Traffic Director API 的错误。
    转到“API 库”页面
  • 确认虚拟机的 API 访问权限范围已设置为授予对 GCP 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 作为 Sidecar 代理,请确认 Envoy 版本是 1.9.1 或更高版本。

无法访问通过 Traffic Director 配置的服务

如果无法访问通过 Traffic Director 配置的服务,请确认 Sidecar 代理是否正在运行且能够连接到 Traffic Director。

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

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

    ps aux | grep envoy
    
  2. 检查 Envoy 的运行时配置,以确认动态资源是否由 Traffic Director 配置。您可以通过运行以下命令来查看配置:

    curl http://localhost:15000/config_dump
    
  3. 确保已正确设置 Sidecar 代理的流量拦截功能。

对于使用 iptables 进行的重定向设置,请运行 iptables 命令,然后 grep 输出以确保您的规则发挥作用:

sudo iptables -t nat -S | grep ISTIO

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

-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

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

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

如果按照为 Sidecar 代理配置其他属性中所述,使用 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_LISTENER:
unable to open file '/var/log/envoy.log': Permission denied

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

应用无法连接到未在 Traffic Director 中配置的服务

请确保仅为 Traffic Director 中配置的服务的 IP 地址设置了流量拦截。如果所有流量都被拦截,则 Sidecar 代理将以静默方式舍弃与 Traffic Director 中未配置的服务的连接。

流量在节点内循环或节点崩溃

如果已将 netfilter (iptables) 设置为拦截所有流量,请确保用于运行 Sidecar 代理的用户 (UID) 不会被拦截。否则,Sidecar 代理发送的流量将无限期地回送至代理。Sidecar 代理进程可能会因此崩溃。在参考配置中,netfilter 规则不会拦截来自代理用户的流量。

大多数端点运行状况不佳时的 Traffic Director 行为

当 99% 的端点运行状况不佳时,为了提高可靠性,Traffic Director 会配置数据平面以忽略端点的运行状况状态,并平衡所有端点之间的流量,因为服务端口可能仍然有效。

对自动 Envoy 部署进行问题排查

本部分介绍如何对自动 Envoy 部署进行问题排查。

用于问题排查的通信通道

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

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

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

虚拟机的操作系统、BIOS 以及其他系统级实体通常将输出写入串行端口,输出有助于排查系统崩溃、启动失败、启动问题和关停问题部分。

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

虚拟机上的代理记录 Envoy 流程运行状况状态,新发现的 Traffic Director 服务以及在调查虚拟机问题时可能有用的任何其他信息。

Cloud 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 的值可指明问题。

无法从通过启用了服务代理的实例模板创建的虚拟机访问 Traffic Director 服务

请按照以下步骤纠正此问题。

  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. 对于基于 Traffic Director 的服务,虚拟机上的流量拦截未正确配置。

    登录虚拟机并检查 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。如果 VIP 没有条目,则从 Traffic Director 填充 Envoy 代理配置时出现问题,或者虚拟机代理失败。

  3. Envoy 代理尚未从 Traffic Director 收到配置。

    登录到虚拟机检查 Envoy 代理配置:

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

    检查从 Traffic Director 收到的侦听器配置。例如:

    "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 是 Traffic Director 服务的 VIP。它指向名为 td-routing-rule-1 的网址映射。检查您要连接的服务已包含在监听器配置中。

  4. 虚拟机上的代理未运行。

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

    要验证虚拟机代理的状态,请运行以下命令:

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

  6. agent-last-failure 属性会显示代理中发生的最后一个错误。这可能是一个暂时性问题,可在代理下次检查时解决,例如,如果错误为 Cannot reach the Traffic Director 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 代理未从 Traffic Director 收到入站端口的配置。

    登录到虚拟机检查 Envoy 代理配置:

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

    查找从 Traffic Director 收到的入站侦听器配置:

    "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 下的侦听器配置中。

后续步骤