网络诊断工具
Linux 运维基础 · 第十一章 目标:掌握从连通性到应用层排查网络问题的全套工具
1. 概述#
运维排障的金字塔:从底层到应用层依次检查。网络排障贯穿全部。
应用层 (HTTP) → curl / wget
传输层 (TCP/UDP) → ss / nc / telnet
网络层 (IP) → ping / traceroute / mtr / ip route
链路层 → ip link / ethtool
DNS → dig / resolvectl工具选型(2026):现代发行版(Rocky/Alma 9、Ubuntu 22.04+)默认已不再预装
net-tools(netstat/ifconfig/route),改用 iproute2(ss/ip)。 本章一律以ss/ip/resolvectl为首选,netstat/ifconfig/nslookup仅作对照。
2. 连通性测试#
2.1 ping — 通了没?#
ping 8.8.8.8 # 发 ICMP Echo Request
ping -c 4 8.8.8.8 # 只发 4 个包(不然 Ctrl+C 才停)
ping -i 0.5 8.8.8.8 # 每 0.5 秒发一个
ping -s 1400 8.8.8.8 # 指定包大小(默认 56 字节)
# 分析输出
# 64 bytes from 8.8.8.8: icmp_seq=1 ttl=117 time=36.3 ms
# ^^^ TTL 说明经过多少跳
# ^^^^^^^ 往返时间
# 故障解释
# Request timeout → 不通(防火墙/路由/目标不响应 ICMP)
# 高延迟 → 网络拥堵/远距离
# 有丢包 → 丢包率 > 0% 说明不稳定注意:很多云服务器禁了 ICMP,ping 不通不代表服务不可用。
2.2 traceroute — 经过哪里?#
traceroute 8.8.8.8 # 显示每跳路由
traceroute -n 8.8.8.8 # 不解析域名(更快)
traceroute -T -p 443 example.com # 用 TCP SYN 代替 ICMP(穿透防火墙)
# 输出解读
# 1 192.168.1.1 1.23ms
# 2 10.0.0.1 5.67ms
# 3 * * * ← * * * 表示这一跳不响应
# 4 72.14.237.130 36.3ms首选 mtr:traceroute 只跑一趟,看不出丢包是偶发还是持续。mtr = traceroute + ping,
持续探测每一跳,是排查"路由中间某跳丢包/抖动"的利器。
mtr 8.8.8.8 # 交互界面,实时刷新每跳丢包率和延迟
mtr -n 8.8.8.8 # 不解析域名
mtr -rwc 100 8.8.8.8 # 报告模式:发 100 个包后输出统计(-r 报告 -w 宽 -c 次数)
mtr -T -P 443 example.com # 用 TCP 探测 443 端口
# 关键看 Loss% 列
# 中间某跳丢包但末跳不丢 → 常是该跳路由器限速 ICMP,不代表真丢包
# 从某跳开始一直丢到末跳 → 那一跳往后才是真问题2.3 nc (netcat) — 端口通不通?#
# TCP 端口测试
nc -zv example.com 80 # 测试 80 端口
# Connection to example.com 80 port [tcp/http] succeeded!
nc -zv example.com 22-25 # 测试 22-25 范围端口
nc -v -w 3 example.com 443 # -w 3 = 超时 3 秒
# 简易 TCP 服务端(测防火墙用)
# 在目标机器上:
nc -l -p 8080 # 监听 8080 端口
# 在测试机器上:
nc -v target_host 8080 # 尝试连接
# 两边都看到 Connected → 端口可达# nc 不止是测试工具,还能"说话"
# 场景:手动和 Redis 交互
echo "PING" | nc localhost 6379
# +PONG
# 发送 HTTP 请求
printf "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n" | nc example.com 803. HTTP 调试:curl#
curl 是运维调试 HTTP API 的标配工具。
3.1 基本用法#
curl https://example.com # GET 请求,输出响应体
curl -I https://example.com # 只看响应头(HEAD 请求)
curl -o output.html https://example.com # 下载到文件
curl -O https://example.com/file.tar.gz # 按远程文件名保存3.2 常用参数#
| 参数 | 含义 | 示例 |
|---|---|---|
-X | 指定 HTTP 方法 | curl -X POST https://api.example.com/data |
-H | 添加请求头 | curl -H "Authorization: Bearer xxx" |
-d | 发送 POST 数据 | curl -d "name=test&value=123" |
--data-raw | 发送 JSON | curl -H "Content-Type: application/json" -d '{"name":"test"}' |
-v | 详细模式(看连接过程) | curl -v https://example.com |
-k | 忽略证书错误 | curl -k https://self-signed.badssl.com/ |
-L | 跟踪重定向 | curl -L http://example.com(跟着 301/302 跳) |
-x | 走代理 | curl -x http://127.0.0.1:8080 https://example.com(也读 HTTPS_PROXY 等环境变量) |
-s | 静默模式 | curl -s https://api.example.com | jq |
-w | 输出格式化信息 | curl -w "\nHTTP code: %{http_code}\n" |
-o /dev/null | 丢弃响应体 | 配合 -w 只看时间等 |
--connect-timeout | 连接超时(秒) | curl --connect-timeout 5 ... |
-m / --max-time | 总超时(秒) | curl -m 10 ... |
3.3 实战示例#
# 测试 REST API
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $(cat /etc/myapp/token)" \
-d '{"action":"reload"}' \
https://api.example.com/v1/admin/config
# 只测响应时间
curl -s -o /dev/null -w \
"DNS: %{time_namelookup}s | Connect: %{time_connect}s | TTFB: %{time_starttransfer}s | Total: %{time_total}s\n" \
https://example.com
# 测试健康检查接口
curl -f -s https://api.example.com/health && echo "OK" || echo "FAIL"
# -f 表示 HTTP 状态码 >=400 时返回失败(退出码 22)
# 循环监控
while true; do
curl -s -o /dev/null -w "%{http_code} %{time_total}s $(date)\n" \
https://api.example.com/health
sleep 5
done4. 端口与连接#
4.1 ss — 查看 Socket(现代工具,替代 netstat)#
ss -tlnp # 列出所有 TCP 监听端口
# t=TCP, l=LISTEN, n=不解析域名, p=显示进程名
ss -tlnp | grep 8080 # 查看 8080 端口是哪个进程在监听
ss -an | grep ESTAB # 看所有已建立的连接
ss -an | wc -l # 连接总数统计
ss -s # 汇总统计
# 常用组合
ss -tlnp # TCP 监听端口及进程(最常用)
ss -ulnp # UDP 监听端口
ss -tan # 所有 TCP 连接(含 ESTAB/TIME_WAIT 等)
ss -tan state established # 只看已建立连接
ss -tan state time-wait # 只看 TIME_WAIT 连接
# 重要状态
# LISTEN — 正在监听
# ESTAB — 已建立连接(正常)
# TIME_WAIT — 主动关闭方等待(大量出现可能需要调内核参数)
# CLOSE_WAIT — 对方已关闭,本地还没关闭(可能是应用 bug)4.2 对比 netstat(已弃用)#
netstat 属于 net-tools,已停止维护,现代发行版最小化安装默认不带。
上生产别再依赖它,一律用 ss(更快、支持更细的状态过滤)。
# 迁移对照:
netstat -tlnp → ss -tlnp
netstat -an | grep ESTAB → ss -tan state established
netstat -s → ss -s
netstat -rn → ip route # 路由表
netstat -i → ip -s link # 网卡收发统计5. 接口与路由#
5.1 ip 命令(替代 ifconfig/route)#
# 查看网络接口
ip addr # 所有接口的 IP 地址(同 ip a)
ip addr show eth0 # 只看 eth0
# 查看链路状态
ip link # 所有接口的链路状态
ip link show eth0 # eth0 状态
# UP/LOWER_UP = 正常,DOWN = 没激活或被拔线
# 路由表
ip route # 查看路由表
ip route get 8.8.8.8 # 查到这个 IP 走哪条路由
ip route add 10.0.0.0/8 via 192.168.1.1 # 加静态路由(临时)
ip route del 10.0.0.0/8 # 删除路由
# 查看 ARP 表
ip neigh # 查看邻居(ARP 表)5.2 关键解读#
ip addr
# 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
# inet 192.168.1.100/24 brd 192.168.1.255 scope global eth0
# ^^ /24 = 子网掩码 255.255.255.0
ip route
# default via 192.168.1.1 dev eth0 ← 默认网关
# 10.0.0.0/8 via 10.0.1.1 dev eth1 ← 到 10 网段走 eth1
# 192.168.1.0/24 dev eth0 proto kernel ← 本地直连6. DNS 诊断#
6.1 dig — 详细查询#
dig example.com # 详细解析
dig +short example.com # 只显示结果
dig +short example.com A # A 记录
dig +short example.com MX # 邮件记录
dig -x 8.8.8.8 # 反向解析(IP → 域名)
# 指定 DNS 服务器查询
dig @8.8.8.8 example.com # 用 Google DNS 查询
dig @1.1.1.1 example.com # 用 Cloudflare DNS
# 查看解析全过程
dig +trace example.com # 从根域名服务器追踪6.2 dig 输出解读#
dig example.com
# ;; ANSWER SECTION:
# example.com. 300 IN A 93.184.216.34
# ^^^ TTL 缓存时间(秒)
# ^ 记录类型
# ;; Query time: 36 msec ← DNS 响应时间
# ;; SERVER: 8.8.8.8#53 ← 实际使用的 DNS 服务器6.3 resolvectl / nslookup#
现代 systemd 系统(跑 systemd-resolved)优先用 resolvectl(旧名 systemd-resolve):
resolvectl query example.com # 查询(走系统实际的解析链路,含本地缓存/分链路 DNS)
resolvectl status # 查看每块网卡生效的 DNS 服务器、搜索域
resolvectl statistics # 缓存命中/查询统计
resolvectl flush-caches # 清 DNS 缓存(改了记录不生效时先清这个)nslookup(属于 bind-utils/dnsutils,较老)仅作应急/对照,能用但不推荐深挖:
nslookup example.com # 简单查询
nslookup example.com 8.8.8.8 # 指定 DNS 服务器注意:
dig/nslookup直接向 DNS 服务器发查询,不走nsswitch.conf//etc/hosts;resolvectl query、ping、curl才走系统真实解析链路。所以"dig 能解析但程序连不上" 往往是hosts文件或resolved缓存作祟——见下。
6.4 DNS 解析顺序与配置文件#
程序解析主机名时,先看 /etc/nsswitch.conf 决定查询顺序,再按顺序查各数据源:
grep '^hosts:' /etc/nsswitch.conf
# hosts: files dns
# ^^^^^ 先查 /etc/hosts(files),再查 DNS
# 若为 files resolve [!UNAVAIL=return] dns → 中间经 systemd-resolved
cat /etc/hosts # 静态映射,优先级高于 DNS(排查"某域名被劫持到内网 IP"先看它)
cat /etc/resolv.conf
# nameserver 8.8.8.8
# nameserver 114.114.114.114
# search example.com ← 自动补全域名后缀
# 用了 systemd-resolved 时,这里通常是指向 127.0.0.53 的软链,真实 DNS 看 resolvectl status7. 抓包:tcpdump(简介)#
# 基本抓包
tcpdump -i eth0 # 抓 eth0 的所有包
tcpdump -i any port 80 # 抓所有网卡的 80 端口流量
tcpdump -i eth0 host 10.0.1.100 # 抓与指定 IP 的通信
# 实用过滤
tcpdump -i any port 443 -w capture.pcap # 保存到文件(Wireshark 分析)
tcpdump -i any -A port 80 # 显示 ASCII 内容
tcpdump -i any -n 'tcp[tcpflags] & tcp-syn != 0' # 只看 SYN 包(连接请求)
# 限制抓包数量
tcpdump -i any -c 100 -w sample.pcap # 只抓 100 个包8. 实战#
实战 1:端口初诊三板斧#
# 1. 端口在监听吗?
ss -tlnp | grep 8080
# 没输出:服务没启动或监听了其他端口
# 2. 端口能连上吗?
nc -zv localhost 8080
# Connection refused: 端口没监听
# Connection timed out: 防火墙拦截
# succeeded: 通了
# 3. 端口能正常响应吗?
curl -v http://localhost:8080/health实战 2:带认证的 API 调试#
# 保存 Token 到变量
TOKEN=$(curl -s -X POST https://auth.example.com/login \
-H "Content-Type: application/json" \
-d '{"user":"admin","pass":"secret"}' | jq -r '.token')
# 用 Token 调业务接口
curl -H "Authorization: Bearer $TOKEN" \
https://api.example.com/v1/health
# 检查响应
# 200 OK → 正常
# 401 Unauthorized → Token 过期/无效
# 502 Bad Gateway → 上游服务挂了实战 3:K8s 内部 DNS 查询#
# 在 Pod 内部查 K8s 服务 DNS
dig +short kubernetes.default.svc.cluster.local
# 返回 ClusterIP
# 查特定服务的 DNS
dig +short myapp-svc.my-namespace.svc.cluster.local
# 查 CoreDNS 的 Pod IP
kubectl get svc -n kube-system kube-dns -o jsonpath='{.spec.clusterIP}'
# 从 Pod 内测试 DNS
kubectl exec -it myapp-pod -- nslookup myapp-svc
kubectl exec -it myapp-pod -- curl http://myapp-svc:8080/health9. 排障顺序(网络版)#
1. ping — 网络层通不通?
2. traceroute/mtr — 卡在哪一跳?有没有丢包?
3. dig/resolvectl — DNS 能解析吗?(dig 直查 DNS,resolvectl 走系统真实链路)
4. nc — 端口通不通?
5. curl — HTTP 层正常吗?(状态码 200/502/503?)
6. ss — 端口在监听吗?连接在 ESTAB 状态吗?
7. tcpdump — 抓包看数据到底去哪了10. 小结#
| 知识点 | 一句话记忆 |
|---|---|
| ping | 测试网络层可达性(云环境可能禁 ICMP) |
| nc | nc -zv host port 测端口通断 |
| curl | HTTP 调试标配,-X 方法,-H 头,-d 数据,-v 详细 |
| ss | -tlnp 看监听端口,-tan state 看连接状态 |
| ip addr/route | 看 IP 和路由表(取代已弃用的 ifconfig/route) |
| mtr | traceroute+ping 二合一,看每跳持续丢包率 |
| dig / resolvectl | dig +short 直查 DNS;resolvectl query/status 走系统真实解析链路 |
| tcpdump | -i any port 80 -w file.pcap 抓包分析 |
上一章:十、终端复用 tmux 下一章:十二、存储与磁盘管理