排查docker容器veth-pair丢包,关键在于定位丢包发生的具体环节:容器内egress路径、宿主机ingress路径或网桥/内核转发层,需结合nsenter、/proc/net/dev统计、sysctl参数及iptables规则分层验证。

排查 Docker 容器 veth-pair 丢包,关键不是“看哪边丢”,而是“在哪一环被丢”——veth 设备本身不主动丢包,真正丢包发生在它连接的两端:容器命名空间内(如 iptables INPUT/DROP)、宿主机网桥(docker0 或 cni0)转发层、或内核网络栈处理阶段(如 netfilter 规则、缓冲区满、反向路径过滤)。必须结合命名空间隔离特性,分侧抓包、比对计数、查统计指标。
确认 veth 设备配对与状态是否正常
veth pair 是容器网络通信的物理通道,一端在容器内(通常叫 eth0),另一端在宿主机上(如 vethabc123),两者必须成对且 UP 状态。
- 先查容器 PID:
docker inspect -f '{{.State.Pid}}' <container_id></container_id> - 再进容器命名空间查接口:
nsenter -n -t <pid> -- ip link show eth0</pid>,确认状态为 UP,且无NO-CARRIER - 在宿主机查对应 veth:
ip link show | grep -A1 veth,找到配对设备,确认也是 UP,且 MAC 地址与容器内 eth0 的 peer MAC 匹配(可通过ip -d link show vethxxx查link_netnsid或peer_ifindex验证) - 若任一端
state DOWN或NO-CARRIER,说明 veth 创建失败或被误删,需重启容器或检查 dockerd 日志
分别统计容器侧与宿主机侧收发帧计数
veth pair 的丢包一定体现在某侧的收发统计差异中。直接读取 /proc/net/dev 比 ping/iperf 更准确,不受应用层重传干扰。
- 查容器内 eth0 收发:
nsenter -n -t <pid> -- cat /proc/net/dev | grep eth0</pid>,关注rx_bytes、rx_packets、rx_dropped和tx_packets - 查宿主机对应 veth 接口(如 vethabc123):
cat /proc/net/dev | grep vethabc123,同样关注rx/tx各项 - 重点比对:
– 若容器tx_packets> 宿主机rx_packets→ 丢包发生在 **容器内 egress 路径**(如 tc qdisc drop、iptables OUTPUT DROP)
– 若宿主机tx_packets> 容器rx_packets→ 丢包发生在 **宿主机 ingress 路径**(如网桥转发失败、netfilter INPUT DROP、rp_filter 拒绝)
– 若两侧 rx/tx 均正常但业务丢包 → 问题在更高层(如 socket recv buffer 溢出、应用未及时 read)
检查宿主机网桥与内核转发关键点
veth 对挂载到 docker0 或 CNI 网桥后,丢包常源于桥接行为异常或内核参数限制。
- 查网桥统计:
cat /sys/class/net/docker0/statistics/rx_dropped、tx_dropped、rx_errors。非零值说明桥接层已丢帧(常见于 CPU 过载、netdev backlog 溢出) - 确认内核转发开启:
sysctl net.ipv4.ip_forward必须为 1;若为 0,容器访问外网时会静默丢弃 - 检查反向路径过滤:
sysctl net.ipv4.conf.all.rp_filter和net.ipv4.conf.docker0.rp_filter。设为 2(loose mode)可避免因回包路径不对称导致丢包 - 验证 MTU 一致性:容器 eth0、veth 宿主机端、docker0 三者 MTU 必须一致(默认 1500)。MTU 错配会导致 ICMP “Fragmentation Needed” 不返回,TCP 连接卡顿或间歇性丢包
定位 netfilter 规则与资源瓶颈
iptables/nftables 是 veth 流量必经之路,规则链过长或匹配动作不当是高频丢包源。
- 查容器命名空间内规则:
nsenter -n -t <pid> -- iptables -L INPUT -v</pid>,观察pkts列是否有大量 DROP 计数 - 查宿主机 FORWARD 链:
iptables -L FORWARD -v | grep -A5 'DOCKER\|FORWARD',确认无意外 DROP 规则拦截 veth 流量 - 监控相关进程 CPU:
top -p $(pgrep -f 'iptables|nft'),若持续 >70%,说明规则匹配开销过大,需合并或跳过无关链 - 检查软中断负载:
cat /proc/net/softnet_stat,第 0 列为 dropped 包数,第 1 列为 processed 数。若 dropped 持续增长,说明 NIC 收包队列溢出,需调大net.core.netdev_max_backlog











