跳到正文
复制成功
请遵守本站许可
报告
章节_文章 // 现场报告

文章编号: RL-TCPDUMP与

2026.08.08

tcpdump、Wireshark 与 TCP 故障排查

Chavy
Chavy
#Kubernetes#tcpdump#Wireshark#故障排查
档案

摘要:结合 tcpdump 和 Wireshark 分析 TCP 握手、RST、重传与超时,按抓包位置、NAT 和请求返回路径定位 Kubernetes 网络故障。

这一节进入网络排障最实用的部分:通过抓包观察真实数据包,判断连接究竟在哪一步失败。

学习如何观察网络通信,而不是仅凭 curl 的报错猜测原因。

本节主要掌握:

  1. TCP 三次握手与四次挥手。
  2. 使用 tcpdump 抓取和过滤数据包。
  3. 使用 Wireshark 分析 TCP 报文。
  4. 区分连接拒绝、超时、重传和应用层错误。
  5. 在 Kubernetes 中定位 Pod、Service 和跨节点网络故障。

一、先理解 TCP 连接建立过程#

假设客户端访问一个 HTTP 服务:

PRTCL // TEXT
客户端:10.244.1.10:40000
服务端:10.244.2.20:8080

TCP 连接通常通过三次握手建立。

sequenceDiagram
    participant C as 客户端 10.244.1.10:40000
    participant S as 服务端 10.244.2.20:8080
    C->>S: SYN:请求建立连接
    S->>C: SYN + ACK:服务端确认
    C->>S: ACK:连接建立

三次握手完成后,客户端就可以发送 HTTP 请求数据。

如果握手过程中出现异常,抓包往往能够直接提供线索:

  • 只有 SYN:连接请求发出,但尚未观察到响应。
  • SYN 后收到 RST:连接被拒绝或主动重置,需要进一步定位发送 RST 的设备。
  • SYN、SYN-ACK、ACK 全部出现:TCP 连接已建立,但应用仍可能返回错误或一直没有响应。

注意,单次抓包没有看到响应,不代表对端一定没有发送。抓包接口选择错误、数据包丢失或非对称路由也可能导致观察不完整。

二、tcpdump:Linux 命令行抓包工具#

tcpdump 是 Linux 上常用的网络抓包工具,可以直接观察经过指定网络接口的数据包。

它在排查 Kubernetes 网络问题时特别有用,因为你可以分别在 Pod 网络命名空间、宿主机网卡和隧道接口上抓包,比较数据包在哪里消失或发生变化。

1. 安装与基础使用#

Ubuntu / Debian:

PRTCL // BASH
Terminal window
sudo apt update
sudo apt install tcpdump

查看网卡:

PRTCL // BASH
Terminal window
ip -br addr

抓取某个接口的数据包:

PRTCL // BASH
Terminal window
sudo tcpdump -i eth0

抓取全部接口:

PRTCL // BASH
Terminal window
sudo tcpdump -i any

其中:

  • -i eth0:监听指定接口。
  • -i any:监听 Linux 支持的所有接口。
  • Ctrl+C:停止抓包并显示统计信息。

生产环境中不建议长时间无过滤抓包,因为流量可能很大,既影响分析效率,也可能记录敏感信息。

2. 过滤指定端口#

假设要排查 TCP 8080 端口:

PRTCL // BASH
Terminal window
sudo tcpdump -i any 'tcp port 8080'

只看某个目标 IP:

PRTCL // BASH
Terminal window
sudo tcpdump -i any 'host 10.244.2.20'

只看某个源 IP:

PRTCL // BASH
Terminal window
sudo tcpdump -i any 'src host 10.244.1.10'

只看两个 IP 之间的通信:

PRTCL // BASH
Terminal window
sudo tcpdump -i any \
'host 10.244.1.10 and host 10.244.2.20'

只抓 TCP SYN 报文:

PRTCL // BASH
Terminal window
sudo tcpdump -i any \
'tcp[tcpflags] & tcp-syn != 0'

如果想进一步排除握手成功时同时带有 ACK 标志的报文,可以使用:

PRTCL // BASH
Terminal window
sudo tcpdump -i any \
'tcp[tcpflags] & (tcp-syn|tcp-ack) == tcp-syn'

这类过滤条件有助于集中观察发起连接的 SYN 报文。

3. 常用参数#

参数作用
-n不解析 IP 地址对应的主机名
-nn不解析主机名和端口服务名
-i指定网络接口
-c 100抓取 100 个数据包后停止
-s 0尽可能抓取完整数据包
-w file.pcap将数据包保存到文件
-r file.pcap读取抓包文件
-tttt显示便于阅读的时间戳
-v显示更多协议细节

实际排障时,推荐先从下面这条命令开始:

PRTCL // BASH
Terminal window
sudo tcpdump -i any -nn -tttt \
'host 10.244.2.20 and tcp port 8080'

它可以减少名称解析干扰,并显示较容易比较的时间戳。

三、如何看懂 tcpdump 输出?#

假设执行:

PRTCL // BASH
Terminal window
sudo tcpdump -i any -nn 'tcp port 8080'

观察到:

PRTCL // TEXT
10.244.1.10.40000 > 10.244.2.20.8080: Flags [S]
10.244.2.20.8080 > 10.244.1.10.40000: Flags [S.]
10.244.1.10.40000 > 10.244.2.20.8080: Flags [.]

这代表:

  1. [S]:SYN,客户端请求建立连接。
  2. [S.]:SYN + ACK,服务端确认请求。
  3. [.]:ACK,客户端确认服务端响应。

三次握手成功。

常见 TCP 标志:

标志含义
[S]SYN
[S.]SYN + ACK
[.]ACK
[P.]PSH + ACK,常见于携带应用数据的报文
[F.]FIN + ACK,常见于有序关闭连接
[R.]RST + ACK,连接重置

标志只是分析线索,不能单独代表某种故障。例如,RST 既可能来自目标应用所在主机,也可能由中间设备产生。

四、四种典型故障:通过抓包判断原因#

场景一:持续发送 SYN,没有收到响应#

抓包:

PRTCL // TEXT
10.244.1.10.40000 > 10.244.2.20.8080: Flags [S]
10.244.1.10.40000 > 10.244.2.20.8080: Flags [S]
10.244.1.10.40000 > 10.244.2.20.8080: Flags [S]

可能原因:

  • 网络路径中存在丢包。
  • NetworkPolicy 或防火墙阻断流量。
  • 目标节点或目标 Pod 不可达。
  • 服务端没有返回响应。
  • 返回路径异常,导致响应无法到达客户端。

排查方法:在客户端和服务端两侧同时抓包。

客户端执行:

PRTCL // BASH
Terminal window
sudo tcpdump -i any -nn 'host 10.244.2.20 and tcp port 8080'

服务端所在节点也执行相应抓包。

客户端观察服务端观察排查方向
发出 SYN没有收到 SYN检查中间网络、路由、策略和抓包接口
发出 SYN收到 SYN,但没有发出响应检查服务监听、主机防火墙及内核处理
发出 SYN收到 SYN,也发出 SYN-ACK检查返回路径和客户端侧是否收到响应
完整握手TCP 已建立继续检查应用层

场景二:收到 RST,连接被拒绝#

抓包:

PRTCL // TEXT
10.244.1.10.40000 > 10.244.2.20.8080: Flags [S]
10.244.2.20.8080 > 10.244.1.10.40000: Flags [R.]

这表示连接被重置,常见原因是目标端口没有进程监听,或者某个设备主动拒绝了连接。

在目标 Pod 内检查:

PRTCL // BASH
Terminal window
ss -lntp

查看是否存在目标端口的监听进程。

注意,ss -lntp 是否能显示进程信息取决于权限和网络命名空间;如果容器内没有 ss,可以在宿主机上进入对应网络命名空间检查。

场景三:TCP 握手成功,但 HTTP 请求一直等待#

抓包:

PRTCL // TEXT
客户端 -> 服务端:SYN
服务端 -> 客户端:SYN-ACK
客户端 -> 服务端:ACK
客户端 -> 服务端:HTTP 请求数据

但迟迟没有看到服务端返回应用数据。

这时,网络至少已经完成了 TCP 建连,应该进一步检查:

  • 应用是否收到请求。
  • 应用是否等待数据库或其他下游服务。
  • 应用线程、协程或连接池是否耗尽。
  • 服务端是否在处理请求时发生阻塞。
  • 返回数据是否被发送,或者在返回路径上丢失。

不要把所有 HTTP 超时都归因于网络。TCP 建连成功不等于应用处理成功。

场景四:大量 TCP 重传#

如果反复看到相同连接的数据包重传,通常说明发送方没有及时收到预期的确认或响应。

可能原因包括:

  • 网络丢包。
  • 链路拥塞。
  • MTU 或路径 MTU 问题。
  • 接收端处理能力不足。
  • 返回路径丢包。

需要结合时间间隔、TCP 序列号、ACK 和两端抓包分析,不能仅凭重传就判断是某个节点故障。


五、Wireshark:图形化分析抓包文件#

tcpdump 适合在服务器上快速抓包,Wireshark 则适合深入分析协议细节。

典型工作流程是:

flowchart TB
    N0["服务器 tcpdump 抓包"]
    N1["保存 .pcap 文件"]
    N2["传输到分析电脑"]
    N3["Wireshark 打开文件"]
    N4["分析握手、重传、RST、HTTP/TLS 等"]
    N0 --> N1
    N1 --> N2
    N2 --> N3
    N3 --> N4

1. 保存抓包文件#

PRTCL // BASH
Terminal window
sudo tcpdump -i any -nn -s 0 \
-c 1000 \
-w /tmp/network-debug.pcap \
'host 10.244.2.20 and tcp port 8080'

这里设置最多抓取 1000 个数据包,避免无边界地采集流量。

然后可以将文件复制到分析电脑:

PRTCL // BASH
Terminal window
scp user@node-ip:/tmp/network-debug.pcap .

如果文件中可能包含敏感业务数据、Cookie 或认证信息,应严格限制文件访问权限,并在分析完成后按组织要求处理文件。

2. Wireshark 常用显示过滤器#

Wireshark 的显示过滤器和 tcpdump 的抓包过滤器不是同一种语法。

目的Wireshark 显示过滤器
查看 TCP 流量tcp
查看特定端口tcp.port == 8080
查看特定 IPip.addr == 10.244.2.20
查看 SYNtcp.flags.syn == 1
查看 RSTtcp.flags.reset == 1
查看重传tcp.analysis.retransmission
查看重复 ACKtcp.analysis.duplicate_ack
查看 DNSdns

Wireshark 还可以通过 Analyze → Follow → TCP Stream 将某条 TCP 连接中的双向应用数据串起来观察。

如果流量使用 HTTPS,抓包通常只能直接看到 TCP、TLS 等传输信息;要读取加密后的 HTTP 内容,需要合法且适当的 TLS 解密条件。

六、Kubernetes Pod 网络故障定位#

现在把抓包方法应用到 Kubernetes。

假设:

PRTCL // TEXT
客户端 Pod:
10.244.1.10
Node A:192.168.1.10
服务端 Pod:
10.244.2.20
Node B:192.168.1.20
服务端端口:8080

客户端访问服务端:

PRTCL // BASH
Terminal window
curl -v --connect-timeout 3 http://10.244.2.20:8080

第一步:确认 Pod 和节点#

PRTCL // BASH
Terminal window
kubectl get pods -A -o wide
kubectl get nodes -o wide

确认两个 Pod 的 IP 和所在节点。

第二步:在服务端抓包#

登录 Node B:

PRTCL // BASH
Terminal window
sudo tcpdump -i any -nn \
'host 10.244.1.10 and tcp port 8080'

与此同时,从客户端 Pod 发起请求。

如果服务端侧抓不到客户端的 SYN,就应该继续检查从 Node A 到 Node B 的网络路径、CNI 数据面、路由及策略。

如果服务端能收到 SYN,但没有发出 SYN-ACK,则检查目标 Pod 的监听状态和主机网络处理规则。

如果服务端已经发出 SYN-ACK,就继续确认客户端侧是否收到它。

第三步:检查服务端监听#

PRTCL // BASH
Terminal window
kubectl exec <server-pod> -- ss -lnt

如果容器中没有 ss,可以使用临时调试容器,或者在节点上通过目标容器的网络命名空间执行相关命令。

第四步:检查 Service 与策略#

如果直接访问 Pod IP 成功,但访问 ClusterIP 失败,再检查 Service 数据面:

PRTCL // BASH
Terminal window
kubectl get svc
kubectl get endpointslices -A
kubectl get networkpolicy -A

如果使用传统 kube-proxy 模式,再结合节点上的相关规则和 conntrack 信息分析。如果使用 eBPF 数据面,则需要使用相应 CNI 的诊断工具。

这里的关键是先通过对照测试缩小问题范围,而不是同时修改多个组件。


七、进阶:同一个请求在不同接口上为什么会显示不同的 IP?#

假设客户端访问:

PRTCL // TEXT
10.96.120.30:8080

但后端 Pod 收到的目标地址是:

PRTCL // TEXT
10.244.2.20:80

这是 Service 转发过程中发生 DNAT 的典型结果。

如果你在不同位置抓包,可能看到:

抓包位置可能观察到的目标地址
客户端 Pod 的 eth0ClusterIP 10.96.120.30:8080
节点上的某个网络处理点取决于抓包接口及 NAT 处理阶段
后端 Pod 的 eth0后端 Pod IP 10.244.2.20:80

如果还发生了 SNAT,后端看到的源 IP 也可能与客户端 Pod IP 不同。

因此,抓包分析必须同时记录:

  1. 抓包位置。
  2. 源 IP 与目标 IP。
  3. 源端口与目标端口。
  4. 抓包时间。
  5. 数据包是请求方向还是返回方向。

只有这样,才能把 NAT、路由和真实网络路径联系起来。

八、本节总结#

今天最重要的能力不是记住抓包命令,而是建立一套分析顺序:

  • SYN 无响应:检查请求路径、返回路径和过滤规则。
  • 收到 RST:检查端口监听与重置来源。
  • 握手成功但应用超时:继续检查应用和依赖服务。
  • 大量重传:检查丢包、拥塞和 MTU 等问题。
  • 不同接口看到不同地址:结合 NAT 与抓包位置解释。
归档于 2026.08.08
// 档案结束
Classified
章节_06
协议编号: CC-BY-NC-SA-4.0

tcpdump、Wireshark 与 TCP 故障排查

作者:Chavy发布日期:2026.08.08

基于 CC BY-NC-SA 4.0

© 2026 Chavy
Powered by Astro