排查使用内部 IP 地址的虚拟机之间的连接问题

概览

本文档针对位于同一 Virtual Private Cloud (VPC) 网络(共享 VPC 或独立 VPC)或位于与 VPC 网络对等互连连接的两个 VPC 网络中的 Compute Engine 虚拟机之间的连接问题提供了问题排查步骤。该文档假设虚拟机使用各自虚拟网络接口控制器 (vNIC) 的内部 IP 地址进行通信。

本指南中的步骤同时适用于 Compute Engine 虚拟机和 Google Kubernetes Engine 节点。

如果您希望查看其他特定问题排查场景,请点击页面底部的发送反馈链接,告知我们。

以下虚拟机和 VPC 配置适用于本指南:

  • 在单个 VPC 网络中使用内部 IP 地址的虚拟机之间的连接。
  • 在共享 VPC 网络中使用内部 IP 地址的虚拟机之间的连接。
  • 在通过 VPC 网络对等互连对等互连的不同 VPC 网络中使用内部 IP 地址的虚拟机之间的连接。

本指南中使用的命令适用于所有 Google 提供的操作系统映像。如果您使用的是自己的操作系统映像,则可能必须安装这些工具。

量化问题

完全连接失败问题排查

以下部分介绍了使用内部 IP 地址的虚拟机之间完全连接失败的问题排查步骤。如果您遇到延迟时间增加或间歇性连接超时问题,请跳转至导致吞吐量问题的网络延迟或丢失问题排查

确定连接值

首先,收集以下信息:

  • “虚拟机实例”页面中,收集两个虚拟机的以下信息:
    • 虚拟机名称
    • 虚拟机可用区
    • 进行通信的 vNIC 的内部 IP 地址
  • 从目标服务器软件的配置中,收集以下信息:

    • 第 4 层协议
    • 目标端口

    例如,如果您的目标是 HTTPS 服务器,则协议为 TCP,端口通常为 443,但您的特定配置可能会使用其他端口。

如果有多个虚拟机出现问题,请选择遇到问题的单个来源虚拟机和单个目标虚拟机,并使用这些值。通常,您不需要连接的来源端口。

获取此信息后,请继续调查底层 Google 网络的问题

调查底层 Google 网络的问题

如果您的设置是近期未更改的现有设置,则表示底层 Google 网络可能存在问题。查看 Network Intelligence Center 性能信息中心,了解虚拟机可用区之间的丢包率。如果在发生网络超时的时间范围内,可用区之间的丢包率增加,则可能表示虚拟网络底层的物理网络存在问题。在提交支持请求之前,请查看 Google Cloud 状态信息中心,以了解已知问题。

如果问题似乎与底层 Google 网络无关,请继续检查配置错误的 Google Cloud 防火墙规则

检查 Google Cloud 中配置错误的防火墙规则

Connectivity Tests 会分析两个虚拟机之间的 VPC 网络路径配置,并显示编程的配置是否应该允许流量。如果不允许流量,则结果会显示 Google Cloud 出站流量或入站防火墙规则是否阻止流量,或者路由是否不可用。

Connectivity Tests 还可以通过在虚拟机的管理程序之间发送数据包来动态测试路径。如果执行这些测试,则会显示这些测试的结果。

Connectivity Tests 仅会检查 VPC 网络的配置,不会测试虚拟机上的操作系统防火墙或操作系统路由或服务器软件。

以下过程从 Cloud Console 运行 Connectivity Tests。如需了解其他运行测试的方法,请参阅运行 Connectivity Tests

请按照以下步骤创建并运行测试:

  1. 转到 Google Cloud Console 中的“Connectivity Tests”页面。
    转到“连接测试”页面
  2. 在项目下拉菜单中,确认您位于正确的项目中或指定正确的项目。
  3. 点击创建连接测试
  4. 为测试指定名称。
  5. 指定下列内容:
    1. 协议
    2. 来源端点 IP 地址
    3. 来源项目和 VPC 网络
    4. 目的地端点 IP 地址
    5. 目标项目和 VPC 网络
    6. 目标端口
  6. 点击创建

测试立即运行。如需查看结果图表,请点击结果详情列中的查看

  • 如果结果显示连接被 Google Cloud 防火墙规则丢弃,请确定预期的安全设置是否应允许连接。您可能需要咨询安全或网络管理员以了解详情。如果应允许流量,请检查以下内容:
  • 如果正确配置的防火墙规则阻止了此流量,请咨询您的安全或网络管理员。如果您的组织的安全要求意味着虚拟机不应相互访问,则您可能需要重新设计设置。
  • 如果结果指示 VPC 连接路径没有问题,则问题可能属于以下某一种。
    • 客机操作系统配置存在问题,例如防火墙软件的问题。
    • 客户端或服务器应用存在问题,例如应用被冻结或配置为侦听错误的端口。

后续步骤将引导您检查每种可能性。继续从虚拟机内部测试 TCP 连接

从虚拟机内部测试 TCP 连接

如果虚拟机之间的连接测试未检测到 VPC 配置问题,请开始测试操作系统之间的连接。以下步骤可帮助您确定:

  • TCP 服务器是否正在侦听指示的端口
  • 如果服务器端防火墙软件允许从客户端虚拟机连接到该端口
  • 客户端防火墙软件是否允许连接到服务器上的该端口
  • 服务器端路由表是否正确配置为转发数据包
  • 客户端路由表是否正确配置为转发数据包

您可以在 Linux 或 Windows 2019 中使用 curl 或在 Windows PowerShell 中使用 New-Object System.Net.Sockets.TcpClient 命令来测试 TCP 握手。本部分中的工作流应会产生以下某种结果:连接成功、连接超时或连接重置。

  • 成功:如果 TCP 握手成功完成,则操作系统防火墙规则未阻止连接,操作系统正确转发数据包,且某种类型的服务器正在侦听目标端口。如果是这种情况,则问题可能在于应用本身。如需检查,请参阅检查服务器日志记录以了解服务器行为
  • 超时:如果您的连接超时,通常意味着以下其中一项:
    • 相应 IP 地址不存在机器
    • 某个位置的防火墙静默地舍弃了数据包
    • 操作系统数据包路由正在将数据包发送到无法处理它们的目标位置,或者非对称路由正在通过无效路径发送返回数据包
  • 重置:如果连接被重置,则表示目标 IP 正在接收数据包,但操作系统或应用拒绝了数据包。这可能意味着出现以下某种情况:

    • 数据包到达错误的机器,并且未配置为在相应端口上响应相应协议
    • 数据包到达正确的机器,但没有任何服务器侦听该端口
    • 数据包到达正确的机器和端口,但更高级别的协议(例如 SSL)没有完成握手
    • 防火墙正在重置连接。这比防火墙静默丢弃数据包的可能性要小,但可能会发生这种情况。

Linux

  1. 转到 Google Cloud Console 中的“防火墙”页面。
    转到“防火墙”页面
  2. 确保有一条防火墙规则允许通过 SSH 从 IAP 连接到虚拟机,或创建新的防火墙规则。
  3. 转到 Google Cloud Console 中的“虚拟机实例”页面。
    转到“虚拟机实例”页面
  4. 找到来源虚拟机。
  5. 在该虚拟机的连接列中,点击 SSH
  6. 在客户端机器命令行中,运行以下命令。将 DEST_IP:DEST_PORT 替换为您的目标 IP 地址和端口。

    curl -vso /dev/null --connect-timeout 5 DEST_IP:DEST_PORT
    

Windows

  1. 转到 Google Cloud Console 中的“虚拟机实例”页面。
    转到“虚拟机实例”页面
  2. 找到来源虚拟机。
  3. 使用连接到 Windows 虚拟机中所述的方法之一连接到您的虚拟机。
  4. 在客户端机器命令行中,运行以下命令:
    • Windows 2019:
      curl -vso /dev/null --connect-timeout 5 DEST_IP:DEST_PORT
      
    • Windows 2012 或 Windows 2016 Powershell:
      PS C:> New-Object System.Net.Sockets.TcpClient('DEST_IP',DEST_PORT)`
      

连接成功

以下结果表示 TCP 握手成功。如果 TCP 握手成功完成,则问题与 TCP 连接超时或重置无关。相反,超时问题发生在应用层内。如果连接成功,请继续检查服务器日志记录,了解服务器行为

Linux 和 Windows 2019

$ curl -vso /dev/null --connect-timeout 5 192.168.0.4:443

“Connected to”行表示 TCP 握手成功。

Expire in 0 ms for 6 (transfer 0x558b3289ffb0)
Expire in 5000 ms for 2 (transfer 0x558b3289ffb0)
  Trying 192.168.0.4...
TCP_NODELAY set
Expire in 200 ms for 4 (transfer 0x558b3289ffb0)
Connected to 192.168.0.4 (192.168.0.4) port 443 (#0)
> GET / HTTP/1.1
> Host: 192.168.0.4:443
> User-Agent: curl/7.64.0
> Accept: */*
>
Empty reply from server
Connection #0 to host 192.168.0.4 left intact

Windows 2012 和 2016

PS C:\> PS C:\> New-Object System.Net.Sockets.TcpClient('DEST_IP_ADDRESS', PORT)

结果连接成功。“Connected: True”行是相关的。

Available           : 0
Client              : System.Net.Sockets.Socket
Connected           : True
ExclusiveAddressUse : False
ReceiveBufferSize   : 131072
SendBufferSize      : 131072
ReceiveTimeout      : 0
SendTimeout         : 0
LingerState         : System.Net.Sockets.LingerOption
NoDelay             : False

连接超时

以下结果表明连接已超时。如果连接超时,请继续验证服务器 IP 地址和端口

Linux 和 Windows 2019

$ curl -vso /dev/null --connect-timeout 5 DEST_IP_ADDRESS:PORT

连接超时结果:

Trying 192.168.0.4:443...
Connection timed out after 5000 milliseconds
Closing connection 0

Windows 2012 和 2016

PS C:\> New-Object System.Net.Sockets.TcpClient('DEST_IP_ADDRESS', PORT)

连接超时结果:

New-Object: Exception calling ".ctor" with "2" argument(s): "A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. 192.168.0.4:443"

连接重置

重置是指设备将 RST 数据包发送回客户端,通知客户端连接已终止。连接可能由于以下原因之一重置:

  • 接收服务器未配置为在相应端口上接受相应协议的连接。这可能是因为数据包发送到了错误的服务器或错误的端口,或者服务器软件配置错误。
  • 防火墙软件拒绝了连接尝试

如果连接已重置,请继续验证您是否正在访问正确的 IP 地址和端口

Linux 和 Windows 2019

$ curl -vso /dev/null --connect-timeout 5 DEST_IP_ADDRESS:PORT

连接重置结果:

Trying 192.168.0.4:443...
connect to 192.168.0.4 port 443 failed: Connection refused
Failed to connect to 192.168.0.4 port 443: Connection refused
Closing connection 0

Windows 2012 和 2016

PS C:\> New-Object System.Net.Sockets.TcpClientt('DEST_IP_ADDRESS', PORT)

连接重置结果:

New-Object: Exception calling ".ctor" with "2" argument(s): "No connection could be made because the target machine actively refused it. 192.168.0.4:443"

验证服务器 IP 地址和端口

在服务器上运行以下命令之一。它们指示是否有服务器侦听必要的端口。

Linux

$ sudo netstat -ltuvnp

输出显示 TCP 服务器正在侦听端口 22 上的任何目标 IP 地址 (0.0.0.0),接受来自任何来源地址 (0.0.0.0) 和任何来源端口 (*) 的连接。PID/Program name 列指定绑定到套接字的可执行文件。

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      588/sshd
tcp6       0      0 :::22                   :::*                    LISTEN      588/sshd
udp        0      0 0.0.0.0:68              0.0.0.0:*                           334/dhclient
udp        0      0 127.0.0.1:323           0.0.0.0:*                           429/chronyd
udp6       0      0 ::1:323                 :::*                                429/chronyd

Windows

PS C:\> Get-NetTcpConnection -State "LISTEN" -LocalPort DEST_PORT

输出显示 DEST_PORT 设置为 443 时的命令运行结果。此输出显示 TCP 服务器正在侦听端口 0.0.0.0 上的任何地址 (443),接受来自任何来源地址 (0.0.0.0) 和任何来源端口 (0) 的连接。OwningProcess 列表示正在侦听套接字的进程的 ID。

LocalAddress LocalPort RemoteAddress RemotePort State  AppliedSetting OwningProcess
------------ --------- ------------- ---------- -----  -------------- -------------
::           443       ::            0          Listen                928
0.0.0.0      443       0.0.0.0       0          Listen                928

如果您发现服务器未绑定到正确的端口或 IP,或者远程前缀与您的客户端不匹配,请参阅服务器文档或供应商来解决问题。服务器必须绑定到特定接口的 IP 地址或 0.0.0.0,并且它必须接受来自正确客户端 IP 前缀或 0.0.0.0 的连接。

如果应用服务器已绑定到正确的 IP 地址和端口,则可能是因为客户端正在访问错误的端口,更高级别的协议(通常是 TLS)主动拒绝了连接,或者防火墙拒绝了连接。

检查客户端和服务器是否使用相同的 TLS 版本和加密格式。

检查您的客户端是否正在访问正确的端口。

如果上述步骤无法解决问题,请继续检查客户端和服务器上的防火墙是否舍弃数据包

检查客户端和服务器上的防火墙是否舍弃数据包

如果服务器无法从客户端虚拟机访问,但正在侦听正确的端口,则其中一个虚拟机可能正在运行防火墙软件,该软件正在舍弃与连接关联的数据包。使用以下命令检查客户端和服务器虚拟机上的防火墙。

如果规则阻止您的流量,您可以更新防火墙软件以允许流量。如果您确实更新了防火墙,请在准备和执行命令时谨慎操作,因为错误配置的防火墙可能会阻止意外流量。请考虑设置虚拟机串行控制台访问权限,然后再继续操作。

Linux iptables

检查为每个安装的 iptables 链和规则处理的数据包数量。通过将来源和目标 IP 地址和端口与 iptables 规则指定的前缀和端口进行比较,确定要匹配的 DROP 规则。

如果匹配的规则显示丢弃数量随着连接超时而增加,请参阅 iptables 文档以将正确的 allow 规则应用于适当的连接。

$ sudo iptables -L -n -v -x

此示例 INPUT 链显示从任何 IP 地址到使用目标 TCP 端口 5000 的任意 IP 地址的数据包将在防火墙处舍弃。pkts 列表示该规则已丢弃 10342 个数据包。作为测试,如果您创建此规则丢弃的连接,则会看到 pkts 计数器增加,并确认行为。

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts   bytes  target prot opt in  out  source      destination
10342 2078513    DROP  tcp  --  *  *    0.0.0.0/0   0.0.0.0/0 tcp dpt:5000

您可以使用以下命令向 iptables 添加入站或出站规则:

入站规则:

$ sudo iptables -A INPUT -p tcp -s SOURCE_IP_PREFIX --dport SERVER_PORT -j ACCEPT

出站规则:

$ sudo iptables -A OUTPUT -p tcp -d DEST_IP_PREFIX --dport DEST_PORT -j ACCEPT

Windows 防火墙

在“Windows 防火墙”中检查允许来自客户端的出站流量以及发送到服务器的入站流量。如果规则阻止您的流量,请在 Windows 防火墙中进行所需的更正以允许连接。您还可以启用 Windows 防火墙日志记录。

Windows 防火墙的默认 DENY 行为是静默地舍弃被拒绝的数据包,因而导致超时。

此命令会检查服务器。如需检查客户端虚拟机上的出站规则,请将 -match 值更改为 Outbound

PS C:\> Get-NetFirewallPortFilter | `
>>   Where-Object LocalPort -match  "PORT" | `
>>   Get-NetFirewallRule | `
>>   Where-Object {$_.Direction -match "Inbound" -and $_.Profile -match "Any"}
Name                  : {80D79988-C7A5-4391-902D-382369B4E4A3}
DisplayName           : iperf3 udp
Description           :
DisplayGroup          :
Group                 :
Enabled               : True
Profile               : Any
Platform              : {}
Direction             : Inbound
Action                : Allow
EdgeTraversalPolicy   : Block
LooseSourceMapping    : False
LocalOnlyMapping      : False
Owner                 :
PrimaryStatus         : OK
Status                : The rule was parsed successfully from the store. (65536)
EnforcementStatus     : NotApplicable
PolicyStoreSource     : PersistentStore
PolicyStoreSourceType : Local

您可以使用以下命令向 Windows 添加新的防火墙规则。

出站规则:

PS C:\> netsh advfirewall firewall add rule name="My Firewall Rule" dir=out action=allow protocol=TCP remoteport=DEST_PORT

入站规则:

PS C:\> netsh advfirewall firewall add rule name="My Firewall Rule" dir=in action=allow protocol=TCP localport=PORT

第三方软件

第三方应用防火墙或防病毒软件也可以丢弃或拒绝连接。请参阅供应商提供的文档。

如果您发现防火墙规则存在问题并进行了更正,请重新测试连接。如果防火墙规则似乎不存在问题,请继续检查操作系统路由的配置

检查操作系统路由配置

操作系统路由问题可能来自以下某种情况:

  • 由于额外的路由复杂性,路由问题在具有多个网络接口的虚拟机上最为常见
  • 在 Google Cloud 中创建的具有单个网络接口的虚拟机上,通常仅在有人手动修改了默认路由表时才会发生路由问题
  • 在从本地迁移的虚拟机上,该虚拟机可能会沿用本地所需的路由或 MTU 设置,但这些设置会造成 VPC 网络中出现问题

如果您使用的是具有多个网络接口的虚拟机,则必须将路由配置为出站到正确的 vNIC 和子网。例如,虚拟机可能配置了路由,以便用于内部子网的流量会发送到一个 vNIC,但在另一个具有外部 IP 地址或具有 Cloud NAT 的访问权限的 vNIC 上配置了默认网关(目的地 0.0.0.0/0)。

您可以逐个检查路由,也可以查看整个虚拟机路由表来审核路由。如果任一方法表明路由表存在问题,请参阅需要时更新路由表中的步骤,以了解相关说明。

审核所有路由

列出所有路由以了解虚拟机上已有的路由。

Linux

$ ip route show table all
default via 10.3.0.1 dev ens4
10.3.0.1 dev ens4 scope link
local 10.3.0.19 dev ens4 table local proto kernel scope host src 10.3.0.19
broadcast 10.3.0.19 dev ens4 table local proto kernel scope link src 10.3.0.19
broadcast 127.0.0.0 dev lo table local proto kernel scope link src 127.0.0.1
local 127.0.0.0/8 dev lo table local proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo table local proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo table local proto kernel scope link src 127.0.0.1
::1 dev lo proto kernel metric 256 pref medium
fe80::/64 dev ens4 proto kernel metric 256 pref medium
local ::1 dev lo table local proto kernel metric 0 pref medium
local fe80::4001:aff:fe03:13 dev ens4 table local proto kernel metric 0 pref medium
multicast ff00::/8 dev ens4 table local proto kernel metric 256 pref medium

Windows

PS C:\> Get-NetRoute
ifIndex DestinationPrefix             NextHop  RouteMetric ifMetric PolicyStore
------- -----------------             -------  ----------- -------- -----------
4       255.255.255.255/32            0.0.0.0          256 5        ActiveStore
1       255.255.255.255/32            0.0.0.0          256 75       ActiveStore
4       224.0.0.0/4                   0.0.0.0          256 5        ActiveStore
1       224.0.0.0/4                   0.0.0.0          256 75       ActiveStore
4       169.254.169.254/32            0.0.0.0            1 5        ActiveStore
1       127.255.255.255/32            0.0.0.0          256 75       ActiveStore
1       127.0.0.1/32                  0.0.0.0          256 75       ActiveStore
1       127.0.0.0/8                   0.0.0.0          256 75       ActiveStore
4       10.3.0.255/32                 0.0.0.0          256 5        ActiveStore
4       10.3.0.31/32                  0.0.0.0          256 5        ActiveStore
4       10.3.0.1/32                   0.0.0.0            1 5        ActiveStore
4       10.3.0.0/24                   0.0.0.0          256 5        ActiveStore
4       0.0.0.0/0                     10.3.0.1           0 5        ActiveStore
4       ff00::/8                      ::               256 5        ActiveStore
1       ff00::/8                      ::               256 75       ActiveStore
4       fe80::b991:6a71:ca62:f23f/128 ::               256 5        ActiveStore
4       fe80::/64                     ::               256 5        ActiveStore
1       ::1/128                       ::               256 75       ActiveStore

逐个检查路由

如果特定 IP 前缀似乎存在问题,请检查客户端和服务器虚拟机中的来源和目标 IP 地址是否存在正确的路由。

Linux

$ ip route get DEST_IP

良好的结果:

系统会显示有效路由。在这种情况下,数据包来自接口 ens4

10.3.0.34 via 10.3.0.1 dev ens4 src 10.3.0.26 uid 1000
   cache

不佳的结果:

此结果确认数据包因没有指向目标网络的路径而被舍弃。确认您的路由表是否包含指向正确出站接口的路径。

**RTNETLINK answers: Network is unreachable

Windows

PS C:\> Find-NetRoute -RemoteIpAddress "DEST_IP"

良好的结果:

IPAddress         : 192.168.0.2
InterfaceIndex    : 4
InterfaceAlias    : Ethernet
AddressFamily     : IPv4
Type              : Unicast
PrefixLength      : 24
PrefixOrigin      : Dhcp
SuffixOrigin      : Dhcp
AddressState      : Preferred
ValidLifetime     : 12:53:13
PreferredLifetime : 12:53:13
SkipAsSource      : False
PolicyStore       : ActiveStore

Caption            :
Description        :
ElementName        :
InstanceID         : ;:8=8:8:9<>55>55:8:8:8:55;
AdminDistance      :
DestinationAddress :
IsStatic           :
RouteMetric        : 256
TypeOfRoute        : 3
AddressFamily      : IPv4
CompartmentId      : 1
DestinationPrefix  : 192.168.0.0/24
InterfaceAlias     : Ethernet
InterfaceIndex     : 4
InterfaceMetric    : 5
NextHop            : 0.0.0.0
PreferredLifetime  : 10675199.02:48:05.4775807
Protocol           : Local
Publish            : No
State              : Alive
Store              : ActiveStore
ValidLifetime      : 10675199.02:48:05.4775807
PSComputerName     :
ifIndex            : 4

不佳的结果:

Find-NetRoute : The network location cannot be reached. For information about network troubleshooting, see Windows Help.
At line:1 char:1

  • Find-NetRoute -RemoteIpAddress "192.168.0.4"
  • ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (MSFT_NetRoute:ROOT/StandardCimv2/MSFT_NetRoute) [Find-NetRoute], CimException + FullyQualifiedErrorId : Windows System Error 1231,Find-NetRoute

此命令确认数据包因没有指向目标 IP 地址的路径而被舍弃。检查您是否有默认网关,以及该网关是否应用于正确的 vNIC 和网络。

更新路由表

必要的话,您可以将路由添加到操作系统的路由表。在运行命令以更新路由虚拟机的路由表之前,我们建议您先熟悉这些命令并理解可能的影响。路由更新命令使用不当可能会导致意外问题或与虚拟机的连接断开。请考虑设置虚拟机串行控制台访问权限,然后再继续操作。

如需了解如何更新路由,请参阅操作系统文档。

如果您发现路由存在问题并进行了更正,请重新测试连接。如果路由似乎不存在问题,请继续检查接口 MTU

检查 MTU

虚拟机的接口 MTU 应该与其所连接的 VPC 网络的 MTU 匹配。理想情况下,彼此通信的虚拟机也具有匹配的 MTU。MTU 不匹配通常不是 TCP 的问题,但可能是 UDP 的问题。

检查 VPC 的 MTU。如果虚拟机位于两个不同的网络中,请检查这两个网络。

gcloud compute networks describe NET_NAME --format="table(name,mtu)"

检查客户端和服务器网络接口的 MTU 配置。

Linux

$ netstat -i

lo(环回)接口的 MTU 始终为 65536,在此步骤中可以将其忽略。

Kernel Interface table
Iface      MTU    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
ens4      1460  8720854      0      0 0      18270406      0      0      0 BMRU
lo       65536       53      0      0 0            53      0      0      0 LRU

Windows

PS C:\> Get-NetIpInterface

环回伪接口的 MTU 始终为 4294967295,在此步骤中可以将其忽略。

ifIndex InterfaceAlias              Address NlMtu(Bytes) Interface Dhcp     Connection PolicyStore
                                    Family               Metric             State
------- --------------              ------- ------------ --------- ----     ---------- -----------
4       Ethernet                    IPv6            1500         5 Enabled  Connected  ActiveStore
1       Loopback Pseudo-Interface 1 IPv6      4294967295        75 Disabled Connected  ActiveStore
4       Ethernet                    IPv4            1460         5 Enabled  Connected  ActiveStore
1       Loopback Pseudo-Interface 1 IPv4      4294967295        75 Disabled Connected  Active

如果接口和网络 MTU 不匹配,您可以重新配置接口 MTU。如需了解详情,请参阅虚拟机和 MTU 设置。如果它们匹配,并且到目前为止您已执行问题排查步骤,则问题可能在于服务器本身。如需获取排查服务器问题的指南,请转到检查服务器日志记录以了解服务器行为

检查服务器日志记录以了解服务器行为

如果上述步骤未解决问题,则应用可能会导致超时。检查服务器和应用日志,了解说明您所看到的内容的行为。

要检查的日志源:

仍存在问题时

如果仍存在问题,请参阅获取支持以了解后续步骤。将上述问题排查步骤的输出结果提供给其他协作者非常有用。

导致吞吐量问题的网络延迟或丢失问题排查

网络延迟或丢失问题通常是由虚拟机或网络路径内的资源耗尽或瓶颈引起的。有时,网络丢失可能会导致间歇性连接超时。vCPU 耗尽、永久性磁盘限制或 vNIC 饱和等原因会导致延迟时间增加和丢包,从而导致网络性能下降。

以下说明假定连接并不是始终超时,而是出现容量或性能受限的问题。如果发生完全丢包,请参阅完全连接失败问题排查

延迟时间的细微变化(例如延迟几毫秒)是正常的。延迟时间会因网络负载或虚拟机内的排队而异。

确定连接值

首先,收集以下信息:

  • “虚拟机实例”页面中,收集两个虚拟机的以下信息:
    • 虚拟机名称
    • 虚拟机可用区
    • 进行通信的 vNIC 的内部 IP 地址
  • 从目标服务器软件的配置中,收集以下信息:
    • 第 4 层协议
    • 目标端口

如果有多个虚拟机出现问题,请选择遇到问题的单个来源虚拟机和单个目标虚拟机,并使用这些值。通常,您不需要连接的来源端口。

获取此信息后,请继续调查底层 Google 网络的问题

调查底层 Google 网络的问题

如果您的设置是近期未更改的现有设置,则表示底层 Google 网络可能存在问题。查看 Network Intelligence Center 性能信息中心,了解虚拟机可用区之间的丢包率。如果在发生网络超时的时间范围内,可用区之间的丢包率增加,则可能表示虚拟网络底层的物理网络存在问题。在提交支持请求之前,请查看 Google Cloud 状态信息中心,以了解已知问题。

如果问题似乎与底层 Google 网络无关,请继续检查握手延迟时间

检查握手延迟时间

所有基于连接的协议在执行连接设置握手时都会产生一些延迟。每次协议握手都会增加开销。例如,对于 SSL/TLS 连接,TCP 握手必须先完成,然后 SSL/TLS 握手才会完成。

同一 Google Cloud 可用区中的握手延迟时间通常可以忽略不计,但与全球较远的位置的握手可能会在连接启动时增加较长的延迟时间。如果您的资源位于较远区域,则可以检查出现的延迟是否是由协议握手引起的。

Linux 和 Windows 2019

$ curl -o /dev/null -Lvs -w 'tcp_handshake: %{time_connect}s, application_handshake: %{time_appconnect}s' DEST_IP:PORT
tcp_handshake: 0.035489s, application_handshake: 0.051321s
  • tcp_handshake 是从客户端发送初始 SYN 数据包到客户端发送 TCP 握手的 ACK 的持续时间。
  • application_handshake 是从 TCP 握手的第一个 SYN 数据包到 TLS(通常情况)握手完成之间的时间。
  • 增加的握手时间 = application_handshake - tcp_handshake

Windows 2012 和 2016

不适用于默认操作系统工具。如果防火墙规则允许,则可以使用 ICMP 往返时间作为参考。

如果延迟时间超过握手考虑在内的延迟时间,请继续确定虚拟机类型的最大吞吐量

确定虚拟机类型的最大吞吐量

虚拟机网络出站流量吞吐量受虚拟机 CPU 架构和 vCPU 数量的限制。通过参阅网络带宽页面来确定虚拟机的潜在出站流量带宽。

如果您的虚拟机无法满足出站流量要求,请考虑升级到容量更高的虚拟机。如需了解相关说明,请参阅更改实例的机器类型

如果您的机器类型应允许足够的出站流量带宽,请调查 Persistent Disk 的使用情况是否干扰了网络出站流量。Persistent Disk 操作可以最高占用虚拟机总网络吞吐量的 60%。如需确定 Persistent Disk 操作是否可能干扰网络吞吐量,请参阅检查 Persistent Disk 性能

虚拟机的网络入站流量不受 VPC 网络或虚拟机实例类型的限制。相反,它取决于虚拟机操作系统或应用的数据包排队和处理性能。如果您的出站流量带宽足够,但出现入站流量问题,请参阅检查服务器日志记录以了解服务器行为

检查 Persistent Disk 性能

虚拟机的 Persistent Disk 数据传输与其网络传输共享一个 Hypervisor 路径。此共享路径最高允许 60% 的 Hypervisor 路径用于 Persistent Disk 传输,因此网络传输可能限制为总传输的 40%。

此外,Persistent Disk 操作的速度比 vNIC 性能慢。如果虚拟机尝试突发向 Persistent Disk 写入数据,速度超出 Persistent Disk 能够处理的速度,则 Persistent Disk 将限制输入。如果发生这种情况,则在共享资源等待数据写入磁盘或从磁盘读取时,网络性能可能会下降。如需进行检查,请参阅 Persistent Disk 限制指标

如果 Persistent Disk 操作受到限制,您可以增加磁盘的存储容量。这样可以减少限制需求,从而降低延迟对网络造成影响的可能性。如需更好地了解磁盘大小调整和性能注意事项,请参阅选择存储方案

如果永久性磁盘吞吐量似乎不是问题,请检查接口 MTU

检查接口 MTU

VPC 网络的 MTU 可配置。虚拟机上的接口的 MTU 应该与其所连接的 VPC 网络的 MTU 值匹配。在 VPC 网络对等互连中,不同网络中的虚拟机可以具有不同的 MTU。发生这种情况时,请将较小的 MTU 值应用于关联的接口。MTU 不匹配通常不是 TCP 的问题,但可能是 UDP 问题。

检查 VPC 的 MTU。如果虚拟机位于两个不同的网络中,请检查这两个网络。

gcloud compute networks describe NET_NAME --format="table(name,mtu)"

检查网络接口的 MTU 配置。

Linux

lo(环回)接口的 MTU 始终为 65536,在此步骤中可以将其忽略。

$ netstat -i
Kernel Interface table
Iface      MTU    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
ens4      1460  8720854      0      0 0      18270406      0      0      0 BMRU
lo       65536       53      0      0 0            53      0      0      0 LRU

Windows

PS C:\> Get-NetIpInterface

环回伪接口的 MTU 始终为 4294967295,在此步骤中可以将其忽略。

ifIndex InterfaceAlias              Address NlMtu(Bytes) Interface Dhcp     Connection PolicyStore
                                    Family               Metric             State
------- --------------              ------- ------------ --------- ----     ---------- -----------
4       Ethernet                    IPv6            1500         5 Enabled  Connected  ActiveStore
1       Loopback Pseudo-Interface 1 IPv6      4294967295        75 Disabled Connected  ActiveStore
4       Ethernet                    IPv4            1460         5 Enabled  Connected  ActiveStore
1       Loopback Pseudo-Interface 1 IPv4      4294967295        75 Disabled Connected  Active

如果接口和网络 MTU 不匹配,您可以重新配置接口 MTU。如需了解如何为 Windows 虚拟机更新 MTU,请参阅虚拟机和 MTU 设置。如果它们匹配,则问题可能是服务器可用性。下一步是检查日志以了解虚拟机是否重新启动、停止或实时迁移,以确认在相关时间您的虚拟机是否发生任何状况。

检查日志以了解虚拟机是否重新启动、停止或实时迁移

在虚拟机生命周期内,虚拟机可被用户重新启动、实时迁移以进行 Google Cloud 维护,或者在极少数情况下,如果虚拟机所在的物理主机发生故障,虚拟机可能会丢失并重新创建。这些事件可能会导致延迟时间或连接超时时间短暂增加。如果虚拟机发生上述任何情况,系统会记录事件。

如需查看虚拟机的日志,请执行以下操作:

  1. 转到 Google Cloud Console 中的 Logging 页面。
    转到 Logging 页面
  2. 选择发生延迟时间的时间范围。
  3. 使用以下 Logging 查询来确定虚拟机事件发生时间是否接近出现延迟的时间范围:
    resource.labels.instance_id:"INSTANCE_NAME"
    resource.type="gce_instance"
    (
      protoPayload.methodName:"compute.instances.hostError" OR
      protoPayload.methodName:"compute.instances.OnHostMaintenance" OR
      protoPayload.methodName:"compute.instances.migrateOnHostMaintenance" OR
      protoPayload.methodName:"compute.instances.terminateOnHostMaintenance" OR
      protoPayload.methodName:"compute.instances.stop" OR
      protoPayload.methodName:"compute.instances.reset" OR
      protoPayload.methodName:"compute.instances.automaticRestart" OR
      protoPayload.methodName:"compute.instances.guestTerminate" OR
      protoPayload.methodName:"compute.instances.instanceManagerHaltForRestart" OR
      protoPayload.methodName:"compute.instances.preempted"
    )
    

如果虚拟机在相关时间内未重启或迁移,则问题可能是资源耗尽。如需检查这一点,请继续检查网络和操作系统统计信息以了解由于资源耗尽是否舍弃数据包

检查网络和操作系统统计信息以了解由于资源耗尽是否舍弃数据包

资源耗尽是一个泛指的术语,这意味着虚拟机上的某些资源(如出站流量带宽)被要求处理超出其处理能力的数据包。资源耗尽可能会造成数据包定期舍弃,因而导致连接延迟或超时。这些超时在客户端或服务器启动时可能不可见,但随着时间的推移在系统耗尽资源时您可能会看到。

以下是显示数据包计数器和统计信息的命令列表。其中一些命令会复制其他命令的结果。在此类情况下,您可以使用更适合自己的命令。请参阅每个部分中的备注,以更好地了解运行命令的预期结果。在不同时间运行这些命令有助于了解舍弃操作或错误是否与问题同时发生。

Linux

  1. 使用 netstat 命令可查看网络统计信息。

    $ netstat -s
    
    TcpExt:
      341976 packets pruned from receive queue because of socket buffer overrun
      6 ICMP packets dropped because they were out-of-window
      45675 TCP sockets finished time wait in fast timer
      3380 packets rejected in established connections because of timestamp
      50065 delayed acks sent
    

    netstat 命令会输出网络统计信息,其中包含按协议舍弃的数据包的值。数据包被舍弃可能是由应用或网络接口导致资源耗尽的结果。查看计数器原因,了解计数器递增的原因。

  2. 检查 kern.log 以查找与 nf_conntrack: table full, dropping packet 匹配的日志。

    Debian:cat /var/log/kern.log | grep "dropping packet"

    CentOS:sudo cat /var/log/dmesg | grep "dropping packet"

    此日志表明虚拟机的连接跟踪表已达到可跟踪的连接数上限。与此虚拟机之间的更多连接可能会超时。如果启用了 conntrack,则可以使用以下命令找到连接数上限:sudo sysctl net.netfilter.nf_conntrack_max

    您可以通过修改 sysctl net.netfilter.nf_conntrack_max 或者在多个虚拟机之间分布虚拟机工作负载来减少负载,从而增加跟踪的最大连接数的值。

Windows 界面

Perfmon

  1. 使用 Windows 菜单,搜索“perfmon”并打开该程序。
  2. 在左侧菜单中,依次选择性能 > 监视工具 > 性能监视器
  3. 在主视图中,点击绿色加号“+”,以向监视图添加性能计数器。注意以下计数器:
    • 网络适配器
      • 输出队列长度
      • 舍弃的出站数据包
      • 错误的出站数据包
      • 舍弃的已收到的数据包
      • 错误的已收到的数据包
      • 未知的已收到的数据包
    • 网络接口
      • 输出队列长度
      • 舍弃的出站数据包
      • 错误的出站数据包
      • 舍弃的已收到的数据包
      • 错误的已收到的数据包
      • 未知的已收到的数据包
    • 每个处理器的网络接口卡的活动
      • 资源接收指示低/秒
      • 资源接收数据包低/秒
    • 处理器
      • 中断时间百分比
      • 特权时间百分比
      • 处理器时间百分比
      • 用户时间百分比

Pefmon 允许您在时序图表上绘制上述计数器。这有利于在测试或服务器目前受到影响时进行监视。CPU 相关计数器(如中断时间和特权时间)的高峰可能指示虚拟机达到 CPU 吞吐量限制时的饱和问题。CPU 饱和时可能会发生数据包舍弃和错误,这会强制数据包在客户端或服务器套接字处理之前丢失。最后,在 CPU 饱和期间,随着更多数据包排入队列等待处理,输出队列长度也会增加。

Windows Powershell

PS C:\> netstat -s
IPv4 Statistics

  Packets Received                   = 56183
  Received Header Errors             = 0
  Received Address Errors            = 0
  Datagrams Forwarded                = 0
  Unknown Protocols Received         = 0
  Received Packets Discarded         = 25
  Received Packets Delivered         = 56297
  Output Requests                    = 47994
  Routing Discards                   = 0
  Discarded Output Packets           = 0
  Output Packet No Route             = 0
  Reassembly Required                = 0
  Reassembly Successful              = 0
  Reassembly Failures                = 0
  Datagrams Successfully Fragmented  = 0
  Datagrams Failing Fragmentation    = 0
  Fragments Created                  = 0

netstat 命令会输出网络统计信息,其中包含按协议舍弃的数据包的值。数据包被舍弃可能是由应用或网络接口导致资源耗尽的结果。

如果您看到资源耗尽,则可以尝试在多个实例之间分布工作负载,将虚拟机升级为一个具有更多资源的虚拟机,根据特定的性能需求调整操作系统或应用,在搜索引擎中输入错误消息来查找可能的解决方案,或使用仍存在问题时所述的某种方法寻求帮助。

如果资源耗尽似乎不是问题,则问题可能在于服务器软件本身。如需获取排查服务器软件问题的指南,请转到检查服务器日志记录以了解服务器行为

检查服务器日志记录以了解服务器行为

如果上述步骤未解决问题,则超时可能是由应用行为(例如 vCPU 耗尽导致处理停滞)引起的。检查服务器和应用日志,了解发现的行为。

例如,由于上游系统(例如负载状态下的数据库)导致延迟时间增加的服务器可能会将过多请求加入队列,因而导致内存用量和 CPU 等待时间增加。这些因素可能会造成连接失败或套接字缓冲区溢出。

TCP 连接偶尔会丢失数据包,但选择性确认和数据包重新传输通常会恢复丢失的数据包,从而避免连接超时。请考虑超时,原因可能是应用服务器发生故障或重新部署,导致连接暂时失败。

如果您的服务器应用依赖于与数据库或其他服务的连接,请确认耦合的服务没有表现不佳。您的应用可能会跟踪这些指标。

仍存在问题时

如果仍存在问题,请参阅获取支持以了解后续步骤。将问题排查步骤的输出结果提供给其他协作者非常有用。

后续步骤

  • 如果您仍遇到问题,请参阅支持页面。