Linux 网卡 Bond 链路聚合实战:七种模式取舍、active-backup 部署与故障切换演练全流程

个人站长的服务器大多只有一块网卡,但当你开始用 VPS 跑多个站点、或者用一台物理机做虚拟化宿主、又或者机房给了你两个独立网口的时候,"一块网卡打天下"就变成了单点故障和带宽瓶颈。网卡 Bonding(链路聚合)就是把多块物理网卡绑定成一个逻辑网卡的技术,它能同时提供两样东西:冗余——一块网卡或一根网线坏了,业务不中断;带宽叠加——多块网卡并行跑,整体吞吐上去了。本文把 Linux Bond 的原理、七种模式、配置流程和真实踩坑讲清楚。

Bond 到底是什么:从一块网卡变成一块"超级网卡"

正常情况下一块网卡对应一个内核网络设备(比如 eth0),有一个 MAC 地址和一个 IP。Bond 的做法是:内核创建一个虚拟设备 bond0,然后把物理网卡(叫 slave 或成员口)"挂"到它下面。IP 地址配在 bond0 上,物理网卡只负责把数据包发出去,不再持有 IP。

这样带来两个效果:应用层只认 bond0,物理网卡的增减对上层透明;内核的 bond 驱动根据所选模式,决定数据包从哪块物理网卡发出、以及成员口故障时怎么切换。

先确认内核支持 bond:

modinfo bonding | head -3
# 输出里能看到 filename:/lib/modules/.../bonding.ko 就说明支持
cat /proc/net/bonding/bond0   # 配置好之后用它查看状态

七种模式,选错等于白干

Bond 有 7 种工作模式,这是最容易搞混的地方。很多人以为绑了两块网卡就能跑满双倍带宽,结果单条 TCP 流还是那点速度——因为模式选错了。

  • mode=0 (balance-rr):轮询。数据包依次从各块网卡发出,理论带宽叠加。但容易乱序,对 TCP 不友好,需要交换机做链路聚合配合。
  • mode=1 (active-backup):主备。只有一块网卡工作,坏了才切换。这是个人站长最该用的模式——不依赖交换机配置,纯冗余,切换快。
  • mode=2 (balance-xor):按源/目的 MAC 做 XOR 哈希分流。需要交换机配合。
  • mode=3 (broadcast):所有网卡都发同一份数据,容错性最高,浪费带宽。极少用。
  • mode=4 (802.3ad / LACP):动态链路聚合,需要交换机配置 LACP。带宽真正叠加,是数据中心标准做法,但要求两端都配置。
  • mode=5 (balance-tlb):自适应发送负载均衡,不需要交换机配合,按当前负载分配发送流量。
  • mode=6 (balance-alb):在 tlb 基础上加接收负载均衡,通过 ARP 协商实现,也不需要交换机配合。

划重点:不需要交换机配合的模式是 1、5、6;需要交换机配合的是 0、2、3、4。个人站长如果没有交换机管理权限,就不要碰 mode=4。而且即便是 mode=6 这种"带宽叠加"模式,单条 TCP 连接仍然只能走一块网卡,只有多条并发连接才能同时用上多块网卡——这是 Bond 最反直觉的一点,也是"我绑了两块千兆为什么下载还是 100M"的根因。

配置方法:NetworkManager 与原生 ifcfg 两条路

现在主流的发行版有两套网络管理方式,配置写法不同。先确认你的系统用哪套:systemctl is-active NetworkManager。返回 active 就是 NetworkManager。

方式一:NetworkManager(nmcli,推荐)

# 1. 创建 bond 接口,指定模式为 active-backup
nmcli con add type bond con-name bond0 ifname bond0 \
  bond.options "mode=active-backup,miimon=100"

# 2. 给 bond 配 IP
nmcli con mod bond0 ipv4.addresses 192.168.1.10/24
nmcli con mod bond0 ipv4.gateway 192.168.1.1
nmcli con mod bond0 ipv4.dns 8.8.8.8
nmcli con mod bond0 ipv4.method manual

# 3. 把两块物理网卡加进去
nmcli con add type ethernet con-name bond0-slave1 ifname eth1 master bond0
nmcli con add type ethernet con-name bond0-slave2 ifname eth2 master bond0

# 4. 启动
nmcli con up bond0

注意物理网卡(eth1/eth2)自己不需要配 IP,它们只是 slave,设置 master bond0 就够了。如果之前给物理网卡配过 IP,要先清掉,否则会和 bond 的资源冲突。

方式二:原生 ifcfg 文件(RHEL/CentOS 系)

在 /etc/sysconfig/network-scripts/ 下建三个文件。先是 ifcfg-bond0:

DEVICE=bond0
TYPE=Bond
BONDING_MASTER=yes
IPADDR=192.168.1.10
PREFIX=24
GATEWAY=192.168.1.1
BOOTPROTO=none
ONBOOT=yes
BONDING_OPTS="mode=active-backup miimon=100"

再是每个 slave,比如 ifcfg-eth1:

DEVICE=eth1
TYPE=Ethernet
BOOTPROTO=none
ONBOOT=yes
MASTER=bond0
SLAVE=yes

ifcfg-eth2 照抄改设备名即可。miimon=100 是链路监测间隔,单位毫秒,100 表示每 100ms 检测一次链路状态,检测到断链会触发切换。

Debian/Ubuntu 的 ifupdown 写法

如果系统用的是老式 /etc/network/interfaces,加:

auto bond0
iface bond0 inet static
    address 192.168.1.10
    netmask 255.255.255.0
    gateway 192.168.1.1
    bond-slaves eth1 eth2
    bond-mode active-backup
    bond-miimon 100

并且在 raise 成员口之前不能让它们自动取名,Debian 里通常还要在 interfaces 里给 eth1/eth2 各加一行 iface eth1 inet manual。

验证:别再猜,看 /proc

配置完最重要的一步是"证明它真的在工作",靠的是这个文件:

cat /proc/net/bonding/bond0

正常输出会包含:

Bonding Mode: fault-tolerance (active-backup)
Currently Active Slave: eth1
MII Status: up
MII Polling Interval (ms): 100
Slave Interface: eth1
    MII Status: up
    Link Failure Count: 0
Slave Interface: eth2
    MII Status: up
    Link Failure Count: 0

关键看点:Currently Active Slave 指向当前工作的那块网卡;两块 slave 的 MII Status 都应为 up;Link Failure Count 为 0 说明没发生过故障。做一次真实故障演练:把当前 active 的网卡拔掉(或在虚拟机里 ip link set eth1 down),再 cat 一次这个文件,应该看到 Active Slave 自动切到 eth2,而 ping 网关完全不断。这才叫验证通过。

深入理解:为什么切换快慢取决于 miimon 与链路检测机制

很多人配置完 Bond 后只关心"能不能切",却忽略了"切得够不够快"。切换速度直接由链路检测机制决定,而检测机制有两套:miimon 和 arp_interval。miimon 靠的是网卡的驱动层直接探测物理链路状态(本质上读网卡的 carrier 信号),它检测得非常快,是绝大多数场景的首选;arp_interval 则是定期向指定的对端 IP 发 ARP 请求,收到应答才认为链路健康,它检测的是"整条路径通不通"而非"网线插没插",适合那种物理链路正常但中间设备已经挂了的情况。两者不能同时用,配了 miimon 就别再配 arp_interval。

miimon 的值是双刃剑:设成 100 毫秒意味着故障发生后最多 100ms 才被感知,加上切换动作本身的开销,业务侧通常要丢 1 到 3 个包;如果把 miimon 调到 1000,检测开销小了,但故障感知要慢整整一秒,对数据库这类长连接业务可能就是一次连接超时重连。反过来说,miimon 设得过小(比如 10 毫秒)会让内核频繁轮询,在网卡数量多、流量大的机器上反而增加不必要的 CPU 开销。经验值是:普通网站业务用 100,对延迟敏感的数据库或长连接服务可以降到 50,但很少需要低于这个数。

另一个常被忽略的是 downdelay 和 updelay。miimon 只是"探测",真正把一块网卡标记为故障或恢复,还要经过延迟确认:downdelay 表示连续多少毫秒检测失败才判定链路 down(防止瞬时抖动误切),updelay 表示检测恢复后延迟多久才把网卡加回使用(防止链路刚恢复还不稳定就急着切回)。这两个参数的意义在于抗抖动——如果只靠 miimon,一次短暂的链路闪断就会触发切换,切来切去把连接全打断,反而比不切更糟。合理的配置是把它们设成 miimon 的若干倍,比如 miimon=100 时 downdelay=200、updelay=400。

真实复盘:一次"绑了但没生效"的排查

我给一台双网口的虚拟化宿主做 Bond,用 nmcli 配置好 mode=1 后,cat /proc/net/bonding/bond0 显示一切正常,两块 slave 都 up。但业务侧做故障演练时,把 eth1 down 掉,SSH 立刻断了——切换根本没发生。

排查动作分三层:第一层查 bond 状态,正常;第二层查 ip a,发现 bond0 上竟然有两个 IP——原来宿主的物理网卡在更早的 cloud-init 配置里还残留着一条 DHCP 租约,bond 起来之后旧 IP 没被清掉,出现了地址冲突。第三层,即使清了旧 IP 后仍偶发切换失败,最后定位到是 交换机侧开了 STP 而没开 portfast,链路切换后端口要经过 STP 的 listening/learning 状态十几秒才转发,切换感知上就是断线。

修复:清掉物理网卡的残留配置、把 miimon 从 100 调到 50 加快检测、并在交换机侧对这两个端口开 portfast。改完后重做演练,ping 丢 1 个包即恢复,业务无感。教训非常明确:Bond 配置"看起来对"和"真正能切换"是两回事,物理网卡的残留配置和交换机侧的行为,是最容易被忽略的两个坑。

容易踩的坑汇总

  • 物理网卡还留着 IP:配置 bond 前务必确认成员口没有 IP,用 ip a 逐块检查,否则会地址冲突或路由异常。
  • 以为单条连接能跑双倍带宽:只有 mode 0/2/4/6 且多条并发连接时才叠加,单条 TCP 流永远受限于单块网卡。
  • mode=4/802.3ad 乱配:LACP 要求两端都是 LACP,交换机没配的话 bond 永远处于"设备未就绪",/proc/net/bonding/bond0 里 slave 显示 down。
  • miimon 设太大:切换检测太慢,业务已经断了才切;设太小又增加开销,100 是常用值,对延迟敏感可降到 50。
  • 忽略交换机侧的 STP/portfast:即使 bond 层切过来了,交换机端口进 STP 阻塞态照样丢包十几秒。
  • Linux bridge/OVS 里直接桥物理口:如果用了虚拟化网桥,要桥 bond0 而不是桥物理口,否则 Bond 逻辑不生效。

总结

网卡 Bond 的核心就一句话:用内核的一个虚拟设备,把多块物理网卡"捆"在一起换取冗余或带宽。选模式时记住两个坐标轴——是否需要交换机配合、是否真的能叠加带宽;个人站长没有交换机权限时,mode=1(active-backup)是最稳妥的冗余方案:配置简单、切换快、不依赖对端。配置本身不难,难的是验证和排坑:一定要读 /proc/net/bonding/bond0、一定要做真实的拔线演练、一定要顺手检查物理口残留配置和交换机端口状态。做到这三点,"绑了却没生效"这类最隐蔽的故障就不会落到你头上。

Last modification:October 9th, 2026 at 07:23 pm

Leave a Comment