Linux Bonding 驱动:内核模块加载与参数详解
说实话,很多搞网络的人一上来就配 bond,配完发现要么不生效,要么动不动就断。问题出在哪?出在没搞懂底层驱动是怎么工作的。这一章,我就带你从内核模块加载开始,把 bonding 驱动的底裤扒干净。
2.1 内核模块加载:bonding 是怎么进到系统里的
Linux 的 bonding 功能,本质是一个内核模块。它不像网卡驱动那样随系统启动自动加载,你得手动告诉内核:“嘿,我要用 bonding 了”。
加载方式有两种:
- 静态编译进内核:编译内核时选上 CONFIG_BONDING=y,模块直接嵌在内核里。好处是启动就能用,坏处是改参数得重新编译。
- 动态加载模块:用 modprobe 或 insmod 加载 bonding.ko。这是最常用的方式,灵活,参数可以在加载时指定。
我个人习惯用 modprobe,因为它会自动处理依赖关系。举个例子:
# 加载 bonding 模块,指定模式为 802.3ad,miimon 为 100ms
modprobe bonding mode=4 miimon=100
加载成功后,用 lsmod | grep bonding 确认:
bonding 180224 0
嗯,这里要注意:lsmod 输出里第三列是“被其他模块引用的次数”。如果为 0,说明模块加载了但还没绑定任何网卡。这很正常,别慌。
modinfo bonding 看一眼当前模块支持的参数列表。不同内核版本支持的参数有差异,尤其是 RHEL 7 和 RHEL 8 之间差别不小。
2.2 bonding 模块参数详解:每个参数都是坑
bonding 模块的参数,说白了就是告诉内核“你怎么管这些网卡”。参数可以在加载时传,也可以在 /etc/modprobe.d/ 下写配置文件。我见过太多人把参数写错位置,结果重启后 bonding 配置全丢了。
下面这张表,是我这些年踩坑总结出来的核心参数:
| 参数名 | 默认值 | 说明 | 我的建议 |
|---|---|---|---|
mode |
0 (balance-rr) | 绑定模式,0-6 共 7 种 | 生产环境别用 mode 0,乱序严重 |
miimon |
0 (关闭) | 链路监控间隔,单位 ms | 至少设 100,不设等于没监控 |
arp_interval |
0 (关闭) | ARP 监控间隔,单位 ms | 和 miimon 二选一,别同时用 |
arp_ip_target |
无 | ARP 监控的目标 IP,最多 16 个 | 必须和 arp_interval 配合使用 |
primary |
无 | 主网卡设备名 | active-backup 模式下必设 |
updelay |
0 | 链路恢复后的延迟,单位 ms | 建议设 200,防止链路抖动 |
downdelay |
0 | 链路确认断开前的延迟,单位 ms | 设 0 就行,别画蛇添足 |
fail_over_mac |
0 | 故障切换时的 MAC 策略 | active-backup 建议设 1 |
这里我重点说几个容易出问题的参数:
mode 参数:0 到 6 七种模式,各有各的适用场景。mode 4(802.3ad)需要交换机支持 LACP,mode 6(balance-alb)不需要交换机配合但 CPU 开销大。我遇到过有人把 mode 4 配在傻瓜交换机上,结果链路死活起不来——因为交换机根本不认 LACP 报文。
primary 参数:只在 active-backup 模式下有效。指定了主网卡后,只要主网卡链路正常,流量就走它。主网卡挂了才切到备用。我曾经有个客户,primary 配错了网卡名,结果主备关系完全反了,排查了一下午。
2.3 miimon 与 arp_interval 监控机制:到底选哪个?
这两个参数,是 bonding 的“眼睛”。没有它们,bonding 就是个瞎子——网线断了它都不知道,照样往断链路上发数据。
2.3.1 miimon:基于 MII 状态的硬件级监控
miimon 的工作原理很简单:内核定时读取网卡的 MII(Media Independent Interface)状态寄存器,判断链路是否 up。这个寄存器由网卡硬件维护,只要物理层有信号,它就报告 link up。
优点:
- 速度快,100ms 就能检测到链路变化
- 不依赖网络层,物理断开就能感知
- CPU 开销极低
缺点:
- 只能检测物理层故障。交换机端口 down 了、网线断了,它能感知。但交换机死机但端口灯还亮着?它检测不到。
- 某些虚拟化环境或 USB 网卡,MII 状态可能不准
我在项目中遇到过一个问题:某台服务器的 bonding 配了 miimon=100,但业务还是偶尔中断。排查到最后发现,是中间的光纤收发器出了问题——光口信号正常,但电口已经不通了。MII 寄存器看到的是光口状态,所以 miimon 一直报告 link up。
2.3.2 arp_interval:基于 ARP 的网络层监控
arp_interval 的思路不一样:它定期发送 ARP 请求到指定的目标 IP,如果能收到回应,就认为链路正常。收不到?那就切换。
优点:
- 能检测到三层以上的故障。交换机死机、路由不可达,它都能发现
- 不依赖网卡硬件,虚拟化环境也能用
缺点:
- 依赖目标 IP 的可用性。目标挂了,bonding 会误判
- ARP 广播可能影响网络性能,尤其是大规模集群
- 配置复杂,需要指定 arp_ip_target
- 物理服务器直连交换机 → 用 miimon,简单可靠
- 虚拟化环境或跨网络 bonding → 用 arp_interval,但目标 IP 要选网关或核心交换机
- 关键业务 → 两者都不放心?那就自己写监控脚本,结合两种机制
2.3.3 两种机制的对比
| 对比维度 | miimon | arp_interval |
|---|---|---|
| 检测层级 | 物理层(L1) | 网络层(L3) |
| 检测速度 | 快(100ms 级别) | 慢(通常 1s 以上) |
| CPU 开销 | 极低 | 中等 |
| 配置复杂度 | 低,设一个值就行 | 高,需要配目标 IP |
| 误判风险 | 物理层正常但网络不通时误判 | 目标 IP 不可达时误判 |
| 适用场景 | 物理服务器、直连拓扑 | 虚拟化、跨网络、复杂拓扑 |
你想想看,如果交换机端口还亮着,但 VLAN 配置被人改了,你的流量根本过不去。这时候 miimon 还傻乎乎地报告 link up,而 arp_interval 已经发现网关 ping 不通了。这就是为什么有些场景必须用 arp_interval。
2.4 知识结构总览
下面这张图,把 bonding 驱动的核心逻辑串起来了。从模块加载到参数配置,再到两种监控机制,你看完应该对整个链路有个清晰的认知。
从图上你能看到,整个 bonding 驱动的核心就三个环节:加载模块 → 配置参数 → 监控链路。参数配置里,mode 决定“怎么分流量”,监控参数决定“什么时候切链路”。这两个搞明白了,bonding 就掌握了七八成。
/proc/net/bonding/bond0 这个文件。里面能看到当前链路状态、MII 状态、ARP 监控计数等详细信息。我每次排查 bonding 问题,第一件事就是 cat 这个文件。