排查 Traffic Director 部署问题

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

Envoy 日志位置

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

在 Google Kubernetes Engine 中,Envoy 代理随应用 Pod 一起运行,因此您可以按 istio-proxy 容器进行过滤来查看应用 Pod 日志中的任何错误。如果集群启用了工作负载日志记录,则您可以在 Cloud Logging 中查看这些错误。

以下是可能的过滤条件:

resource.type="k8s_container"
resource.labels.project_id="PROJECT-NAME"
resource.labels.location="CLUSTER-ZONE"
resource.labels.cluster_name="CLUSTER-NAME"
resource.labels.namespace_name="WORKLOAD-NAMESPACE"
labels.k8s-pod/app="WORKLOAD-NAME"
resource.labels.container_name="istio-proxy"

如果集群未启用工作负载日志记录,则您可以使用如下所示的命令查看错误:

kubectl logs $(kubectl get po -l app=WORKLOAD-NAME -o=jsonpath='{.items[0].metadata.name}') -c istio-proxy --tail 50 #NOTE: This assumes the default namespace.

您还可以使用以下过滤条件查看所有集群中运行的所有 Envoy 日志以及任何工作负载的日志:

resource.type="k8s_container"
resource.labels.container_name="istio-proxy"

通过 Compute Engine 和手动部署,在运行设置指南中的 run.sh 脚本之前定义 LOG_DIR

例如 LOG_DIR='/var/log/envoy/'

默认情况下,错误会显示在 /var/log/envoy/envoy.err.log 中。

如果用户没有执行其他配置以将其导出到 Logging,则只有在您通过 SSH 连接到实例并获取此文件后,这些错误才会显示。

如果您使用自动 Envoy 部署,则可以通过 SSH 连接到实例来获取日志文件。文件路径可能与上述路径相同。

代理未连接到 Traffic Director

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

  • 检查 Envoy 代理日志中是否存在关于连接到 trafficdirector.googleapis.com 的任何错误。
  • 如果您已(通过 iptables)设置了 netfilter 以将所有流量重定向到 Envoy 代理,请确保您以其身份运行代理的用户 (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 访问日志记录时无法访问服务

如果您使用 TRAFFICDIRECTOR_ACCESS_LOG_PATH 配置 Envoy 访问日志(如为 Sidecar 代理配置其他特性中所述),请确保运行 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 日志中指示配置问题的错误消息

如果您在 Traffic Director 配置方面遇到问题,则可能会在 Envoy 日志中看到以下任一错误消息:

  • warning envoy config StreamAggregatedResources gRPC config stream closed: 5, Traffic Director configuration was not found for network "VPC_NAME" in project "PROJECT_NUMBER".
  • warning envoy upstream StreamLoadStats gRPC config stream closed: 5, Traffic Director 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.
  • Traffic Director configuration was not found.

此错误消息通常表示 Envoy 正在从 Traffic Director 请求配置,但无法找到匹配的配置。当 Envoy 连接到 Traffic Director 时,它会显示 VPC 网络名称(例如 my-network)。然后,Traffic Director 会查找符合以下条件的转发规则:(1) 具有 INTERNAL_SELF_MANAGED 负载平衡方案;(2) 引用相同的网络名称(例如 my-network)。

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

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

  3. 如果您将 Traffic Director 用于 Compute Engine 上的手动 Envoy 部署,请检查 Envoy 引导文件:

    1. 请检查 TRAFFICDIRECTOR_NETWORK_NAME 变量的值并确保其值与转发规则的网络名称匹配。
    2. 请确保在 Envoy 引导文件的 TRAFFICDIRECTOR_GCP_PROJECT_NUMBER 变量中设置项目编号。
  4. 如果您要在 GKE 上进行部署并且使用的是自动注入器,请确保根据通过自动 Envoy 注入为 Google Kubernetes Engine Pod 设置 Traffic Director 中的说明,正确配置项目编号和网络名称。

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

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

用于问题排查的通信渠道

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

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

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

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

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

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

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

无法从通过启用了服务代理的实例模板创建的虚拟机访问 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 下的侦听器配置中。

后续步骤