记录一次 Ubuntu Server + KVM + Docker 环境下的网络故障排查。板载 Intel I219-V 在
e1000e驱动下遇到高负载/虚拟化网络场景时发生 TX Hang;关闭 EEE 和部分 offload 后解决了运行中断网,但需要延迟应用 ethtool 设置,避免冷启动时链路反复协商。
环境
服务器环境大致如下:
- Ubuntu Server 26.04 LTS
- Kernel:
7.0.0-22-generic - KVM/libvirt 虚拟化
- Docker 运行中
- Cockpit 管理
- 物理网卡:Intel Ethernet Connection (11) I219-V
- 驱动:
e1000e - 网络结构:
eno1接入br0,宿主机和虚拟机走桥接网络
桥接结构简化如下:
eno1
└── br0
├── host
└── KVM VM / vnet
初始故障现象
最早的问题是服务器运行一段时间后突然失联:
- SSH 无法连接
- Cockpit 无法连接
- 路由器 DHCP/客户端列表里看不到宿主机
- 虚拟机也同时失联
- 只能物理重启恢复
一开始看起来像是 Docker、KVM bridge、路由器或者 DHCP 的问题。但从故障影响范围看,宿主机和所有虚拟机同时失联,更像是物理出口 eno1 本身出了问题。
关键日志
查看上一次启动的内核日志:
journalctl -k -b -1 --no-pager | grep -iE 'e1000e|eno1|hardware unit hang'
发现大量重复日志:
e1000e 0000:00:1f.6 eno1: Detected Hardware Unit Hang
而且是每 2 秒左右刷一次,持续到机器被手动重启。
这基本说明问题不在上层网络配置,而在物理网卡/驱动路径。Hardware Unit Hang 通常意味着网卡发送队列或硬件单元卡住了。由于 eno1 是 br0 的底层物理接口,所以它一挂,宿主机、KVM 虚拟机、Docker 对外通信都会一起失联。
第一次处理:关闭 EEE
EEE,即 Energy Efficient Ethernet,是一种以节能为目标的以太网省电机制。对一些 Intel 板载网卡来说,在高负载、虚拟化、桥接网络场景下,它可能会参与触发链路异常。
先查看状态:
sudo ethtool --show-eee eno1
关闭 EEE:
sudo ethtool --set-eee eno1 eee off
为了持久化,创建 systemd 服务:
sudo tee /etc/systemd/system/disable-eee-eno1.service >/dev/null <<'EOF'
[Unit]
Description=Disable EEE on eno1
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/sbin/ethtool --set-eee eno1 eee off
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now disable-eee-eno1.service
验证:
sudo ethtool --show-eee eno1
期望看到:
EEE status: disabled
不过这一步之后,故障仍然复现。说明 EEE 不是唯一原因。
第二次触发:虚拟机高 CPU 负载
后来又出现一次断网,这次触发条件:在 KVM 虚拟机里跑了高 CPU 占用程序。
虚拟机 CPU 高,为什么宿主机网卡会挂?
但虚拟机并不是另一台物理机器。它实际上是宿主机上的 qemu-system-x86_64 进程,虚拟网卡走的是 virtio-net、tap、vhost-net、Linux bridge,再到物理网卡 eno1。
高 CPU 负载可能改变这些路径的时序:
- qemu/vhost 线程抢占 CPU
- 网卡中断处理延迟
- virtio-net 批量发包
- TSO/GSO/GRO 等 offload 让网卡承担更多分段/校验工作
- I219-V + e1000e 在特定负载下触发 TX Hang
高负载改变了驱动、网卡、中断、桥接网络之间的时序,触发了本来就不稳定的边界条件。
第二阶段处理:关闭 offload
继续查看 offload 状态:
ethtool -k eno1 | grep -E 'tcp-segmentation-offload|generic-segmentation-offload|generic-receive-offload|scatter-gather|tx-checksumming|rx-checksumming'
关闭关键 offload:
sudo ethtool -K eno1 tso off gso off gro off sg off tx off rx off
验证结果:
rx-checksumming: off
tx-checksumming: off
scatter-gather: off
tcp-segmentation-offload: off
generic-segmentation-offload: off
generic-receive-offload: off
运行中随机断网的问题明显改善,没有再复现。
代价是宿主 CPU 需要承担更多网络包处理工作。
新问题:冷启动后不自动联网
关闭 offload 后,又出现了新问题:
- 从关机状态开机
- 机器没有自动连上网络
- 手动插拔网线后才恢复
查看本次启动日志:
journalctl -b --no-pager | grep -iE 'eno1|br0|e1000e|networkd|disable-eee|disable-eno1-offload|carrier|link is'
发现启动早期 eno1 本来已经协商成功:
eno1: NIC Link is Up 1000 Mbps Full Duplex
br0: Gained carrier
但两个 ethtool 持久化服务同一时间执行后,链路开始反复抖动:
eno1: Lost carrier
eno1: Gained carrier
eno1: Lost carrier
eno1: Gained carrier
这说明:offload 设置本身有用,但在冷启动太早执行时,可能触发 e1000e 重置或重新协商,导致链路不稳定。
最终 workaround:延迟应用 ethtool 设置
解决办法是不要在网络刚起来时立即改网卡参数,而是等系统进入多用户状态后延迟一段时间,再统一应用 EEE/offload 设置。
先禁用之前两个服务:
sudo systemctl disable --now disable-eee-eno1.service disable-eno1-offload.service
创建新的延迟服务:
sudo tee /etc/systemd/system/fix-eno1-ethtool.service >/dev/null <<'EOF'
[Unit]
Description=Apply stable ethtool settings for eno1
After=multi-user.target systemd-networkd.service
Wants=systemd-networkd.service
[Service]
Type=oneshot
ExecStartPre=/usr/bin/sleep 60
ExecStart=/usr/sbin/ethtool --set-eee eno1 eee off
ExecStart=/usr/sbin/ethtool -K eno1 tso off gso off gro off sg off tx off rx off
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now fix-eno1-ethtool.service
验证服务状态:
systemctl status fix-eno1-ethtool.service --no-pager
验证 EEE:
ethtool --show-eee eno1
验证 offload:
ethtool -k eno1 | grep -E 'tcp-segmentation-offload|generic-segmentation-offload|generic-receive-offload|scatter-gather|tx-checksumming|rx-checksumming'
如果冷启动后仍然链路抖动,可以把:
ExecStartPre=/usr/bin/sleep 60
改成:
ExecStartPre=/usr/bin/sleep 120
然后执行:
sudo systemctl daemon-reload
sudo systemctl restart fix-eno1-ethtool.service
额外观察
排查过程中还看到:
NetworkManager在运行,但相关接口是unmanaged,不是主因systemd-networkd负责 netplan 生成的 bridge 配置eno1当前没有 CRC、carrier error、collision 等典型线缆错误计数- BIOS/固件较旧,板载 I219-V 稳定性本身一般
e1000e的 private flags 中有省电相关参数,例如s0ix-enabled
如果上述 workaround 后仍然复现,可以继续尝试:
sudo ethtool --set-priv-flags eno1 s0ix-enabled off
sudo ethtool --set-priv-flags eno1 disable-k1 on
但这些属于更深一层的省电路径调整,建议先观察 EEE + offload + 延迟应用是否足够稳定。
最终结论
Intel I219-V + e1000e 在高负载/虚拟化网络场景下发生 Hardware Unit Hang
- 关闭 EEE
- 关闭关键 offload:TSO/GSO/GRO/SG/TX/RX checksum
- 不要开机立刻执行 ethtool 修改,延迟 60 到 120 秒执行
绕开大部分 e1000e TX Hang 场景。