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,说明模块加载了但还没绑定任何网卡。这很正常,别慌。

我的习惯:每次加载 bonding 模块前,先 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 配错了网卡名,结果主备关系完全反了,排查了一下午。

避坑:miimon 和 arp_interval 不要同时启用。两者监控机制不同,同时启用会导致 bonding 状态判断混乱。我见过有人两个都设了,结果链路明明正常,bonding 却反复切主备,业务直接抖成心电图。

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 驱动的核心逻辑串起来了。从模块加载到参数配置,再到两种监控机制,你看完应该对整个链路有个清晰的认知。

Linux Bonding 驱动核心逻辑 modprobe bonding 模块参数配置 模式参数 (mode) 监控参数 (miimon/arp) 策略参数 (primary等) miimon 硬件监控 物理层 MII 寄存器 arp_interval 网络监控 ARP 请求/响应 链路状态判断 up / down / 切换 核心:miimon 和 arp_interval 二选一,不要同时启用。mode 参数决定流量分发策略。

从图上你能看到,整个 bonding 驱动的核心就三个环节:加载模块 → 配置参数 → 监控链路。参数配置里,mode 决定“怎么分流量”,监控参数决定“什么时候切链路”。这两个搞明白了,bonding 就掌握了七八成。

一个小技巧:调试 bonding 时,多看看 /proc/net/bonding/bond0 这个文件。里面能看到当前链路状态、MII 状态、ARP 监控计数等详细信息。我每次排查 bonding 问题,第一件事就是 cat 这个文件。