TT Lab
博客 开始
学习 学习路径 课程

Linux 网络诊断

ping 通了,服务也可能不通

在 TT Lab 中继续学习

一句话总结

ping 只能证明到 IP 层为止的可达性。它既不能证明上面的端口,也不能证明更上面的应用,甚至不能证明大数据包能否通过。

为什么需要这个

“ping 得通但连不上”不是矛盾,而是正常状态。ping 只是收发 ICMP echo。TCP 8080 是否开放是完全不同的问题,即使端口开放,应用也可能返回 5xx。

反方向也很重要。ping 失败,服务也可能完好无损。 因为很多组织会屏蔽 ICMP echo。所以“ping 不通,服务器挂了”这种判断是危险的。

工作原理

三个工具的作用各不相同。

工具 看什么 本环境中的注意事项
ping 到目的地的 IP 往返是否可行 可用(ping_group_range 允许)
traceroute 能走到哪一跳 默认(UDP)和 -I(ICMP)可用,-T(TCP)因权限不足而失败
mtr 持续观察逐跳丢包率和延迟 默认(ICMP)和 --tcp 可用,--udp 输出的跳行为空

这张表是在本实验 Pod 中实测的结果(2026-11-06)。Pod 没有 CAP_NET_RAW,ICMP 模式却可以运行——如果 net.ipv4.ping_group_range 允许,Linux 的 ICMP 数据报套接字(“ping 套接字”)无需 raw 套接字也能发送 Echo,而本 Pod 中该值为 0 2147483647。同一个工具在不同模式下使用的套接字不同,因此与“没有特权,所以 ICMP 不能用”之类的泛泛之谈相比,在该环境中亲自运行得到的结果才是对的。

traceroute 的原理是把 TTL 从 1 开始逐个增大发送。TTL 变为 0 处的路由器会返回 ICMP time exceeded,其源地址就是那一跳的身份。所以 traceroute 不是“查询路径”的工具,而是“故意让数据包失败来收集应答”的工具。

* * * 不是故障。 只是那一跳的路由器限制或不生成 ICMP 应答而已。判断规则如下。

ping 漏掉的东西:路径 MTU

最棘手的例子是 MTU 黑洞。ping 的默认载荷是 56 字节,总能通过。可是应答稍微变大的 API 就会直接卡住。没有报错,就是卡住。因为只有超过阈值大小的数据包会消失,症状会随大小而不同。

用设置了禁止分片位的 ping 来确认。

ping -M do -s 1472 -c 1 10.20.0.5
# From 10.0.1.1 icmp_seq=1 Frag needed and DF set (mtu = 1420)

-s 的值加上 28(ICMP 8 + IP 20)就是实际 MTU。用二分查找找出能通过的最大值,就得到路径 MTU。

使用隧道时,有效 MTU 会减少相当于开销的大小。

封装 额外头部 有效 MTU 推荐 MSS 钳制
PPPoE 8 1492 1452
GRE 24 1476 1436
VXLAN (IPv4) 50 1450 1410
WireGuard (IPv4) 60 1440 1400
IPsec ESP + NAT-T 约 81 1419 1379

在现场遇到的样子

“一开 VPN,只有某些网站打不开。” 这是隧道开销使有效 MTU 减小、却没有 MSS 钳制的典型情况。小页面能打开,大页面卡住。ping 100% 成功。

在云上把 ICMP 全部封掉后运行 traceroute 的情况。 结果全是 * * *,很容易得出“路径断了”的结论。这时用 TCP 模式的 traceroute(-T -p 443)或 nc -zv 直接敲目标端口更准确。不过 -T 要自己构造 SYN,需要 raw 套接字权限——在像本实验 Pod 这样没有 CAP_NET_RAW 的地方会因权限不足而失败(实测),所以要用 nc -zv 或 curl 去敲。

在哪里测量会改变答案

即使用同样的工具测量同样的目标,结论也会因在哪里测量而不同。如果不注意这一点,就会拿着在不同地方测得的数值争论不休。

在我的笔记本上测得的值不是我们服务的值。 办公室线路、VPN、家里的路由器全都夹在路径上。它既不同于用户的体验,也不同于服务器之间的通信。所以第一原则是在与出问题的地方相同的位置测量;做不到时,要把测量位置一起写进结果。

只在一侧测量只能看到一半。 正如前面的课程所见,去程有路而回程没路的情况很常见,这时从一侧看到的 traceroute 是正常的。从两侧互相测量,不对称就会立刻显现。

路径并不每次都一样。 在有多条路径的区段,不同的流会走不同的路,所以 traceroute 跑两次,跳会不一样。只在特定流上出现丢包的问题,一次测量是抓不到的。

测量本身会产生负载。 在已经饱和的链路上挂上 mtr,它本身就会增加丢包。而且正如前面的课程所说,在已经出问题的系统上,诊断命令把故障放大的事确实会发生。

最后,写下测量的时间。 网络问题会随时间出现又消失,没有时间的测量值几天后就毫无依据。提前测好正常时的数值也很有价值,原因相同。没有可比较的东西,就无法判断现在的数值是好是坏。

下一个实验要做的事

确认接口和路由,从 ping 统计中读取丢包率和 RTT,用本环境中可用的模式运行 traceroute 和 mtr。最后亲自比较 ICMP 可以而 TCP 怎么样,并整理成表。