ethtool —— 物理网卡参数 / 速率 / offload
一句话定义
ethtool 显示 / 修改物理网卡 NIC 的硬件参数:速率 / 双工 / 自动协商 / 驱动信息 / offload 特性 / 统计计数。是排查"是不是物理层问题"的标准工具。
典型场景
- 网络变慢、怀疑物理层:
ethtool eth0看速率 - 节点丢包:
ethtool -S eth0看错误计数 - 网卡 link down:判断是网卡 / 网线 / 对端的问题
- K8s 节点 CNI 性能优化:开 / 关 offload
- 调 ring buffer 应对大流量
主要用于物理机 / 裸金属节点。云上虚拟机网卡受 hypervisor 控制,很多参数改不了。
装
apt install -y ethtool # Ubuntu / Debian
yum install -y ethtool # CentOS / RHEL
1. 看网卡基本信息
$ ethtool eth0
Settings for eth0:
Supported ports: [ TP ]
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
10000baseT/Full
Supported pause frame use: No
Supports auto-negotiation: Yes
Supported FEC modes: Not reported
Advertised link modes: 1000baseT/Full
10000baseT/Full
Advertised pause frame use: No
Advertised auto-negotiation: Yes
Speed: 10000Mb/s ← 当前协商的速率
Duplex: Full ← 全双工
Auto-negotiation: on
Port: Twisted Pair
PHYAD: 0
Transceiver: internal
MDI-X: Unknown
Supports Wake-on: g
Wake-on: g
Current message level: 0x00000007 (7)
drv probe link
Link detected: yes ← 物理层通了
逐字段解读:
| 字段 | 含义 | 生产意义 |
|---|---|---|
Supported link modes | 网卡支持的速率组合 | 看上限 |
Advertised link modes | 当前告诉对端的能力 | 想限制低速可改 |
Speed | 当前实际协商速率 | 期望 1000 / 10000、看到 100 = 自动协商失败 |
Duplex | 全双工 / 半双工 | 半双工 = 老网络 / 自动协商错 |
Auto-negotiation | 自动协商开关 | 通常 on |
Port | 物理介质:TP(双绞)/ FIBRE / DA(DAC 线) | |
Link detected | 物理链路是否通 | no = 网线 / 对端问题 |
速率没跑满标称的常见原因
服务器声称 10G 网卡、但 Speed: 1000Mb/s:
| 原因 | 排查 |
|---|---|
| 网线不够(Cat5e 跑不了 10G) | 换 Cat6a 或 DAC |
| 交换机端口配置错 | 看交换机口配置 |
| 网卡两端 advertise 不匹配 | ethtool -s eth0 advertise 0x40000000000(10G) |
| 网卡硬件问题 / 兼容性 | 换网卡测 |
2. 看驱动 / 固件信息
$ ethtool -i eth0
driver: ixgbe ← Intel 10G 驱动
version: 5.15.0-91-generic ← 内核驱动版本
firmware-version: 0x800003e7
expansion-rom-version:
bus-info: 0000:01:00.0 ← PCI 总线地址
supports-statistics: yes
supports-test: yes
supports-eeprom-access: yes
supports-register-dump: yes
supports-priv-flags: yes
| 字段 | 含义 |
|---|---|
driver | 内核驱动名(报 bug 时必报) |
version | 驱动版本 |
firmware-version | 网卡固件 |
bus-info | PCI 地址,lspci -s <addr> 看详情 |
常见网卡驱动 → 厂商速查
| 驱动 | 厂商 / 系列 |
|---|---|
ixgbe | Intel 10G (82598/82599/X540/X550) |
i40e / iavf | Intel 40G / 100G (XL710 / X710 / CX5) |
mlx4_en / mlx5_core | Mellanox / NVIDIA ConnectX |
bnxt_en | Broadcom NetXtreme |
tg3 | Broadcom 1G |
e1000e | Intel 1G (老主板) |
virtio_net | KVM 虚拟网卡 |
vmxnet3 | VMware 虚拟网卡 |
ena | AWS Nitro |
3. 统计计数(排错关键)
$ ethtool -S eth0 | head -30
NIC statistics:
rx_packets: 12345678
tx_packets: 9876543
rx_bytes: 12345678901
tx_bytes: 9876543210
rx_errors: 0
tx_errors: 0
rx_dropped: 1234 ← 接收丢包!
tx_dropped: 0
multicast: 5678
collisions: 0
rx_length_errors: 0
rx_over_errors: 0
rx_crc_errors: 12 ← CRC 错误!
rx_frame_errors: 0
rx_fifo_errors: 1234 ← FIFO 错误
rx_missed_errors: 1234
...
异常关键字 + 含义:
| 计数器 | 异常时表示 | 修法 |
|---|---|---|
rx_dropped | 接收丢包(buffer 满 / 限速) | 调 ring buffer / 看应用消费速度 |
tx_dropped | 发送丢包 | 看队列 / 流量 |
rx_crc_errors | CRC 错(坏网线 / 物理层问题) | 换网线 / 网卡 / 端口 |
rx_frame_errors | 帧错误(物理层) | 同上 |
rx_fifo_errors | NIC 内部 FIFO 溢出 | 调 ring buffer |
rx_over_errors | 包大小超限 | 配 MTU |
rx_missed_errors | DMA 跟不上、丢包 | 调 ring buffer / CPU 亲和 |
rx_no_buffer_count | 没 buffer 接 | 调 ring buffer |
大流量节点必看
# 排错"网络偶发卡"
ssh m1 'ethtool -S eth0 | grep -iE "drop|error|miss|fifo" | grep -v ": 0$"'
# 任何非 0 都要查
监控里可以这样定期采:
# Prometheus node-exporter 已经导出这些
node_network_receive_errs_total{device="eth0"}
node_network_receive_drop_total{device="eth0"}
4. Ring buffer
NIC 在内核和硬件之间有个 "ring buffer"(环形队列)。buffer 太小 + 流量大 = 丢包。
$ ethtool -g eth0
Ring parameters for eth0:
Pre-set maximums: ← 硬件支持的最大
RX: 4096
RX Mini: 0
RX Jumbo: 0
TX: 4096
Current hardware settings: ← 当前
RX: 512 ← 太小!
RX Mini: 0
RX Jumbo: 0
TX: 512
生产 10G+ 节点建议调到硬件最大:
$ ethtool -G eth0 rx 4096 tx 4096
$ ethtool -g eth0
Current hardware settings:
RX: 4096
TX: 4096
立即生效。持久化(每次开机):
# /etc/systemd/network/eth0-tweaks.service
[Unit]
Description=Tune eth0
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/sbin/ethtool -G eth0 rx 4096 tx 4096
[Install]
WantedBy=multi-user.target
或用 udev rules / NetworkManager dispatcher script。
5. Offload 特性
NIC 现代化的"硬件加速"特性。让 CPU 不用做某些工作。
$ ethtool -k eth0
Features for eth0:
rx-checksumming: on
tx-checksumming: on
tx-checksum-ipv4: on
tx-checksum-ip-generic: off [fixed]
tx-checksum-ipv6: on
scatter-gather: on
tx-scatter-gather: on
tcp-segmentation-offload: on ← TSO: 让 NIC 帮忙分大包
tx-tcp-segmentation: on
tx-tcp-ecn-segmentation: off [fixed]
generic-segmentation-offload: on ← GSO: 软件版 TSO
generic-receive-offload: on ← GRO: 接收聚合
large-receive-offload: off ← LRO: 硬件接收聚合
rx-vlan-offload: on
tx-vlan-offload: on
ntuple-filters: off
receive-hashing: on
highdma: on
rx-vlan-filter: on
vlan-challenged: off [fixed]
tx-lockless: off [fixed]
netns-local: off [fixed]
tx-gso-robust: off [fixed]
...
关键 offload:
| Offload | 含义 |
|---|---|
rx-checksumming / tx-checksumming | 校验和卸载 |
tcp-segmentation-offload (TSO) | 让 NIC 帮 TCP 切大包成小包 |
generic-segmentation-offload (GSO) | 软件版 TSO(K8s 节点常用) |
generic-receive-offload (GRO) | 接收时聚合多个小包成大包 |
large-receive-offload (LRO) | 硬件版 GRO(很多场景不推荐开) |
K8s 节点常见问题:开错 offload 导致 VXLAN 不通
某些 NIC 的 TSO / GSO 对 VXLAN 封装的内层包处理有 bug —— 跨节点 pod 通信偶发性丢包。
排查:
# 关掉所有 TSO / GSO 看是否好
ethtool -K eth0 tx off
ethtool -K eth0 gso off
ethtool -K eth0 tso off
如果关了之后变好 → 网卡 driver bug。固定关闭:
# /etc/network/interfaces 或者 NetworkManager dispatcher
post-up ethtool -K eth0 tso off gso off
代价:CPU 占用略高。但稳定性优先。
6. 改速率 / 双工(慎用)
# 强制 1G 全双工(disable 自动协商)
ethtool -s eth0 speed 1000 duplex full autoneg off
# 启用自动协商(默认)
ethtool -s eth0 autoneg on
远程改速率小心断连
ethtool -s 改速率会让 link 短暂 down → ssh 断 → 你回不来。
只在 console / IPMI / 救援场景用。日常不要远程跑 ethtool -s。
7. 暂停帧 / Pause Frame
$ ethtool -a eth0
Pause parameters for eth0:
Autonegotiate: on
RX: off
TX: off
Pause frame = "对端来不及处理、暂停发"。10G+ 网络 + 大流量场景建议开:
ethtool -A eth0 rx on tx on
但跟交换机要协商一致——单边开没用。
8. 查看 EEPROM / 模块信息
# 看光模块(SFP+ / QSFP+)
$ ethtool -m eth0
Identifier : 0x03 (SFP)
Extended identifier : 0x04 (GBIC/SFP defined by 2-wire interface ID)
Connector : 0x07 (LC)
Transceiver codes : 0x10 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
Transceiver type : 10G Ethernet: 10G Base-LR
Encoding : 0x06 (64B/66B)
BR, Nominal : 10300MBd
Vendor name : Cisco-Finisar
Vendor PN : FCLF-8521-3
...
光纤场景排查"模块是否 OK"用。能看模块温度、光功率、厂商。
9. 测试网卡
# 让网卡 LED 闪 10 秒(找哪个口)
ethtool -p eth0 10
# 自检
ethtool -t eth0
The test result is PASS
The test extra info:
...
物理排错救命招——服务器机柜里 LED 闪可以指明"就是这块"。
10. 真实场景
Case 1: 10G 网卡只跑 1G
$ ethtool eth0 | grep Speed
Speed: 1000Mb/s
$ ethtool eth0 | grep "Link partner"
Link partner advertised link modes: 1000baseT/Full
← 对端只声明 1G
# 看交换机配置 / 换 Cat6a 网线
Case 2: 节点 dmesg 报 ring buffer 满
$ dmesg | grep -i "rx ring"
... ixgbe 0000:01:00.0 eth0: tx hang
... rx ring exhausted
$ ethtool -g eth0
RX: 256 ← 太小
$ ethtool -G eth0 rx 4096
Case 3: VXLAN 跨节点偶发丢包
# Pod 间大包丢、小包通
$ kubectl exec pod-a -- ping -c 10 -s 1400 pod-b # OK
$ kubectl exec pod-a -- ping -c 10 -s 1450 pod-b # 30% 丢
# 网卡某些 offload 可能 bug
$ ethtool -k eth0 | grep -E "tso|gso|gro"
tcp-segmentation-offload: on
generic-segmentation-offload: on
generic-receive-offload: on
# 尝试关掉
$ ethtool -K eth0 tso off gso off
# 再测、好了 → driver bug
修:固化关闭 TSO / GSO 或升级 driver / firmware。
Case 4: K8s 节点出向流量大、CPU 飙
$ top # CPU 100%、且 si (软中断) 高
$ ethtool -S eth0 | grep -iE "irq|cpu"
$ ls /proc/interrupts | head
软中断高 + 单核被打满 → NIC 多队列没开 / CPU 亲和性错:
# 看 NIC 队列数
$ ethtool -l eth0
Channel parameters for eth0:
Pre-set maximums:
RX: 0
TX: 0
Combined: 8 ← 硬件支持 8 队列
Current hardware settings:
RX: 0
TX: 0
Combined: 1 ← 当前只用 1 队列
# 开 8 队列
$ ethtool -L eth0 combined 8
外加 RPS / RFS 设置让中断分散到多个 CPU 核。
11. 反面教材
反面 1:远程 ethtool -s 改速率断连
$ ssh m1 'ethtool -s eth0 speed 100' # ssh 立刻断、再连不上
改物理层参数前确保有 console / IPMI 备份。
反面 2:盲目调 ring buffer
$ ethtool -G eth0 rx 65536 # 设超过硬件 max
ethtool: invalid parameter "rx 65536"
-g 看 max、不要超。
反面 3:所有 offload 一键关
$ for f in tso gso gro lro tx rx; do
ethtool -K eth0 $f off
done
关多了 CPU 飙 + 网络性能差。关之前先确认问题是不是 offload 引起的。
反面 4:忘了持久化
$ ethtool -G eth0 rx 4096 # 当前生效
$ reboot
$ ethtool -g eth0 # 又变回 512
写到 systemd unit / NetworkManager / /etc/network/interfaces。
反面 5:以为虚拟机网卡能调
$ ssh aliyun-ecs 'ethtool -G eth0 rx 4096'
ethtool: error
云上 / KVM 虚拟机的 virtio_net 大部分参数受 hypervisor 控制、改不了。只在物理机 / 裸金属上能调到底。
12. K8s 节点 NIC 调优清单(生产推荐)
10G+ 节点跑 K8s 推荐调:
# 1. Ring buffer 最大
ethtool -G eth0 rx 4096 tx 4096
# 2. 多队列开满
ethtool -L eth0 combined $(nproc)
# 3. 看是否需要关有问题的 offload
ethtool -k eth0 | grep -E ": on" | grep -E "tso|gso|gro|lro"
# 4. 暂停帧(如果交换机支持)
ethtool -A eth0 rx on tx on
# 5. 监控这些计数
ethtool -S eth0 | grep -iE "drop|error" > /var/log/ethtool.log
写 systemd unit 持久化:
# /etc/systemd/system/nic-tune.service
[Unit]
Description=Tune NIC eth0 for K8s
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash -c '\
ethtool -G eth0 rx 4096 tx 4096 ; \
ethtool -L eth0 combined $(nproc) ; \
ethtool -A eth0 rx on tx on'
[Install]
WantedBy=multi-user.target
systemctl enable --now nic-tune.service