mtr —— traceroute + ping 合体
一句话定义
mtr(My Traceroute)实时显示到目标的每一跳网络节点及每一跳的丢包率和延迟。它把 traceroute(看路径)和 ping(看丢包/延迟)合二为一,是诊断"慢 / 不稳定"网络问题最直观的工具。
典型场景
- "节点连 apiserver 偶尔超时" → mtr 看哪一跳丢包
- "国内访问国外 GitHub 慢" → 看在哪一跳延迟暴涨
- "跨机房 K8s 集群偶发性失败" → 看路径是否不稳
- 装机时验证节点出网路径质量
装
apt install -y mtr-tiny # Debian / Ubuntu,轻量版
apt install -y mtr # 含 GUI
yum install -y mtr # CentOS / RHEL
brew install mtr # macOS
mtr-tiny 是 server 用的小版本(没 GTK GUI),训练营足够。
基础用法
mtr example.com
打开一个实时刷新的界面:
Packets Pings
Host Loss% Snt Last Avg Best Wrst StDev
1. _gateway 0.0% 50 0.5 0.6 0.4 1.0 0.2
2. 192.168.1.1 0.0% 50 2.1 2.5 1.8 5.2 0.7
3. 10.0.0.1 0.0% 50 10.2 11.0 9.5 15.3 1.2
4. 203.0.113.1 0.0% 50 12.0 12.5 11.8 20.1 1.5
5. ??? 100.0% 50 0.0 0.0 0.0 0.0 0.0
6. core-router.isp.net 5.0% 50 25.0 26.2 23.0 45.0 3.1
7. example.com 0.0% 50 30.1 30.5 29.5 40.0 1.8
读法(每跳):
- Host —— 这一跳的 IP / 主机名
- Loss% —— 这一跳的丢包率
- Snt —— 发的探测包数
- Last —— 最近一次 RTT(毫秒)
- Avg —— 平均 RTT
- Best / Wrst —— 最好 / 最差 RTT
- StDev —— 标准差(抖动指标)
按 q 退出,p 暂停。
五个核心 flag
mtr -r example.com # 报告模式(一次性输出,不交互)
mtr -n example.com # 不解析名字
mtr -c 100 example.com # 跑 100 个包后停
mtr -i 0.5 example.com # 间隔 0.5 秒(默认 1 秒)
mtr -T -P 443 example.com # TCP 模式打 443 端口
报告模式 -r —— 脚本 / 留证据用
mtr -rn -c 30 example.com > /tmp/mtr.txt
# 跑 30 个包后退出,不解析名字,输出文本报告
适合"我跑了 30 秒看到这个状况,你也看看"——发给同事 / 工单系统。
TCP 模式 -T —— 防火墙挡 ICMP 时
mtr -T -P 6443 10.0.24.28
默认 mtr 用 ICMP(同 traceroute)。某些防火墙挡 ICMP,要换 TCP。-T -P 6443 让 mtr 用 TCP SYN 探测 6443 端口。
实际上生产网络多数挡 ICMP——TCP 模式更可靠。
UDP 模式 -u
mtr -u -P 53 8.8.8.8
UDP 探测,模拟 DNS 流量。
怎么读 mtr 报告(最关键)
模式 1:某跳 100% 丢包,但后续跳正常
5. ??? 100.0%
6. router.isp.com 0.0%
这个 100% 是假的。某些路由器配置为不响应 ICMP TTL exceeded(mtr 探测原理依赖此),所以你看不到它的回应,但流量正常穿过去了。
看这种行:忽略它,只关心后续跳的丢包率。
模式 2:某跳后所有后续跳都有丢包
5. router-A 10.0%
6. router-B 15.0%
7. router-C 12.0%
8. dest 11.0%
罪魁多半是第 5 跳——它丢包,导致后续的探测包都丢。
或者第 5 跳本身丢包率被错误显示(它把自己回的包优先级低 / 限速),实际 5/6/7 都正常。判断:
- 如果所有后续跳丢包率近似第 5 跳 → 真问题在第 5 跳或之前
- 如果第 5 跳 100%,后续跳都 0% → 第 5 跳只是不回 ICMP,没问题
模式 3:延迟暴涨
4. router 10ms
5. router 12ms
6. router 250ms ← 跨洋
7. dest 255ms
正常的——跨洋 / 跨大区延迟暴涨是物理距离决定的。看绝对值是否符合预期(同城 1-5ms / 同国 10-30ms / 跨大洋 100-200ms)。
模式 4:抖动大(StDev 高 / Best vs Wrst 差距大)
4. router Loss 0% Last 15ms Avg 25ms Best 5ms Wrst 80ms StDev 20ms
延迟不稳——可能是某个路由器拥塞、buffer bloat、半双工冲突等。表现:服务"间歇性慢"。
训练营场景
1. 节点连 apiserver 偶发性超时
# 在 worker 节点上
ssh m4 'mtr -rn -c 30 -T -P 6443 10.0.24.28 > /tmp/m4-to-cp.txt'
cat /tmp/m4-to-cp.txt
5 节点同机房应该 < 1ms 且 0% 丢包。任何异常都要查。
2. 集群跨机房 / 公网回程
集群 cp1/cp2 在 A 机房、cp3 在 B 机房:
# 在 cp1 上
mtr -rn -c 30 -T -P 2380 <cp3-IP> # 跨机房探 etcd peer
# 看跳数 / 延迟 / 丢包
# > 50ms 的跨机房 etcd 集群 → raft 抖动概率大幅升高
3. pod 出网慢
# 找 pod 容器 PID
PID=$(crictl inspect $(crictl ps -q --name my-pod) | jq '.info.pid')
# 在 pod netns 里跑 mtr(要节点上装了 mtr)
nsenter -t $PID -n mtr -rn -c 30 -T -P 443 github.com
如果 pod 出网慢但节点出网快 —— 问题在 CNI / iptables / SNAT。
4. 国内 → GitHub 慢
经典问题。mtr 一跑看到丢包在哪一跳:
mtr -rn -c 50 -T -P 443 github.com
# 通常在国际出口某跳 30-50% 丢包
没有完美解决方案——这是物理网络问题。临时缓解:HK / SG 转发 / CDN。
mtr 探测原理(懂这个能解释一切"坑")
mtr 持续做 traceroute:
- 发 TTL=1 的 ICMP / UDP / TCP 探测包
- 第一跳路由器看到 TTL=1,回
ICMP Time Exceeded给源 - mtr 拿到响应,得知第一跳是谁、延迟多少
- 继续 TTL=2、TTL=3 ...
- 直到 TTL 足够大、达到目标 IP,目标回
ICMP Echo Reply(或 TCP ACK / UDP port unreachable)
所以:
- 100% 丢包但流量正常 = 这跳路由器没回
ICMP Time Exceeded(被限速 / 配置如此) - 中间跳显示延迟比末尾跳高 = 那个路由器处理慢、但转发不慢
- 目标显示
???= 目标没有回应任何探测(防火墙挡)
命令行 vs 交互界面
mtr 默认交互式,但实战大部分场景用 -r(report):
# 交互(看实时变化)
mtr 8.8.8.8
# 报告(固定包数后停止,给文本)
mtr -rn -c 100 8.8.8.8
# JSON / XML / CSV 报告
mtr -rn -c 100 --json 8.8.8.8
mtr -rn -c 100 --csv 8.8.8.8
JSON 适合自动化分析(监控告警系统抓 JSON 算每跳丢包率历史)。
常见踩坑
坑 1:忘了加 -n
mtr 8.8.8.8
# 每一跳都做反向 DNS,慢 + 噪音多
加 -n,需要时再去 dig -x <IP> 单查某跳的名字。
坑 2:用 ICMP 模式但运营商挡 ICMP
mtr 8.8.8.8
# 大量 ???,看着像彻底不通
# 但 curl 跑得好好的
换 TCP:
mtr -T -P 443 8.8.8.8
或 UDP:
mtr -u -P 33434 8.8.8.8
别人手里的 mtr 报告里看到中间一堆
???,先问"是用什么协议跑的"。
坑 3:看到中间一跳 50% 丢包就慌
5. router 50% 丢包
6. router 0% 丢包
7. dest 0% 丢包
如果后续跳丢包率正常,第 5 跳的丢包只是它自己回包慢 / 被限速,对实际业务流量没影响。真业务流量看末跳。
坑 4:mtr 在 K8s pod 里没权限
kubectl exec my-pod -- mtr 8.8.8.8
# 报错 / 权限不足
mtr 需要 raw socket(CAP_NET_RAW)。普通 pod 没这权限。
替代:
- 在节点上对 pod IP 跑 mtr(看到 pod → 外网的路径)
- 用
nsenter -t <pid> -n mtr ...(节点上有 mtr,进 pod netns 跑) - 用
kubectl debug起带特权的调试容器
坑 5:mtr 不存在
$ mtr
sh: mtr: not found
apt install mtr-tiny 或 yum install mtr。
坑 6:看抖动(StDev)不等于看丢包
延迟稳定但丢包高、或者延迟抖动但 0% 丢包 —— 两个独立问题。
- 抖动高(StDev 大):可能是 buffer bloat 或拥塞、影响实时业务(VoIP / 游戏)
- 丢包高:影响吞吐 / TCP 重传
K8s 集群两个都要小。
互补工具
| 工具 | 用途 |
|---|---|
mtr | 一直看(路径 + 丢包) |
traceroute | 一次性看路径 |
ping | 一次性看丢包 / 延迟,不看路径 |
tracepath | 类似 traceroute 但发 UDP、自动探 MTU |
nping | nmap 套件的多协议 ping |
hping3 | 高级(造 TCP SYN flood、SYN scan 等) |
iperf3 | 测带宽(不是路径) |
记住一组哲学:
- 通不通 →
ping/nc -zv - 慢不慢 / 路径 →
mtr - 丢包多不多 / 持续监控 →
mtr -r长跑 - 带宽多大 →
iperf3 - 内容对不对 →
curl/tcpdump