1. 为什么单网卡迟早会成为生产环境的隐患
很多人在虚拟机里跑服务时,从没觉得网络是个问题——一张网卡、一个IP,跑得好好的。直到某天机房交换机做了一次固件升级,或者某台服务器的网线被误拔,业务中断了十几分钟,才开始意识到:单网卡就是单点故障。Linux双网卡绑定(bonding)要解决的核心问题,就是让两块物理网卡在系统层面虚拟成一块逻辑网卡,对外只暴露一个IP,但底层有冗余和带宽聚合能力。
这个技术的正式名称叫Linux Bonding,内核模块名是bonding,在较新的发行版里也可以用team或nmcli来管理。它的价值体现在三个层面:第一是冗余,一块网卡或一条链路断了,另一块自动接管,业务几乎无感知;第二是带宽聚合,多块网卡并行传输,理论吞吐可以叠加;第三是负载均衡,把流量分散到多条物理链路上,避免单卡过热或过载。
适合读这篇内容的人有三类:一是刚接触服务器运维、需要给生产机器做网络冗余的工程师;二是正在准备相关技术认证、需要把bonding原理和实操都吃透的学习者;三是在虚拟化或云环境中遇到网络配置困惑、想搞清楚底层逻辑的开发者。不管你属于哪一类,接下来的内容都会从原理讲到实操,再讲到踩坑排查,尽量把每个环节的“为什么”说清楚。
需要提前说明的是,bonding的配置方式在不同发行版和不同网络管理工具下差异很大。传统方式是直接改/etc/sysconfig/network-scripts/下的配置文件,新一些的系统推荐用nmcli或netplan。我会以最通用的传统配置为主线,同时补充nmcli的做法,方便你在不同环境下对照使用。
2. Bonding的七种模式:不是随便选一个就行
2.1 模式选择背后的核心逻辑
Bonding模块支持多种工作模式,每种模式对应不同的冗余策略和负载均衡算法。很多人配置时随手写个mode=1就完事,但其实模式选错了,要么浪费了带宽聚合能力,要么在特定网络环境下根本起不到冗余作用。理解每种模式的底层行为,是配好bond的第一步。
模式的选择取决于两个关键因素:对端交换机的配置能力,以及你对带宽和冗余的优先级排序。如果对端交换机不支持链路聚合协议,那你只能用不需要交换机配合的模式;如果你既要冗余又要带宽叠加,那就需要交换机侧也做相应配置。
2.2 各模式行为对比与适用场景
下面这张表是我在实际项目中总结的,把常用模式的特性、对交换机的要求和典型场景列在一起,方便你快速定位:
| 模式编号 | 模式名称 | 冗余能力 | 带宽聚合 | 交换机要求 | 典型场景 |
|---|---|---|---|---|---|
| mode=0 | balance-rr | 有 | 有 | 需静态聚合 | 对吞吐要求高的内网传输 |
| mode=1 | active-backup | 有 | 无 | 无需配置 | 最通用的高可用场景 |
| mode=2 | balance-xor | 有 | 有 | 需静态聚合 | 需要哈希负载均衡的场景 |
| mode=3 | broadcast | 有 | 无 | 无需配置 | 特殊容错场景 |
| mode=4 | 802.3ad | 有 | 有 | 需LACP动态聚合 | 标准化程度要求高的环境 |
| mode=5 | balance-tlb | 有 | 部分 | 无需配置 | 发送流量大的场景 |
| mode=6 | balance-alb | 有 | 部分 | 无需配置 | 收发都需要均衡的场景 |
mode=1(active-backup)是最省心的选择:只有一块网卡处于活动状态,另一块待命,活动网卡故障时自动切换。它不需要交换机做任何特殊配置,兼容性最好,缺点是 standby 网卡平时不承载流量,带宽没有叠加。如果你的核心诉求只是“别断”,选它准没错。
mode=4(802.3ad)是标准化程度最高的方案,基于LACP协议动态协商,能真正实现带宽聚合和负载均衡。但它要求交换机端口必须配置为LACP模式,两端要匹配。我在实际项目里遇到过交换机侧忘了配LACP、结果bond起不来的情况,排查了半天才发现是对端没开。
mode=6(balance-alb)比较特殊,它不需要交换机支持,但通过ARP协商实现了接收方向的负载均衡。原理是bond驱动会修改发出的ARP响应,让不同的对端把流量发到不同的网卡上。这个模式在虚拟化环境里用得比较多,但配置不当容易出现ARP混乱,需要谨慎。
提示:如果你的环境里交换机配置不可控,优先考虑 mode=1 或 mode=6;如果交换机可以配合,mode=4 是最规范的方案。
2.3 一个容易被忽略的参数:miimon
不管选哪种模式,miimon这个参数都值得单独说。它定义了链路监测的时间间隔,单位是毫秒。默认值通常是100,意思是每100毫秒检测一次网卡链路状态。这个值设得太大,故障切换会变慢;设得太小,又会增加系统开销。
我的经验是:普通业务场景用miimon=100就够了;如果对切换速度要求极高,可以调到miimon=50,但不要低于50,否则在一些老网卡上可能出现误判。另外还有一个updelay和downdelay参数,分别控制网卡上线和下线后的等待时间,默认是0。在交换机端口启动较慢的环境里,适当设置updelay=200可以避免网卡刚插上就被判定为可用、结果链路还没真正通的情况。
3. 传统配置文件方式:一步步搭起一个可用的bond
3.1 环境确认与前置检查
动手之前,先确认几件事。第一,系统里有没有bonding内核模块,用modinfo bonding看一下,如果有输出说明支持。第二,确认要绑定的两块网卡名称,用ip link show或nmcli device status查看,常见的是eth0、eth1或者ens33、ens34这种可预测命名。第三,确认 NetworkManager 是否在管理这些网卡,如果是,直接改配置文件可能会被覆盖,需要先决定用哪种管理方式。
我一般会先把 NetworkManager 对目标网卡的管理停掉,避免它和手动配置打架。命令是nmcli device set eth0 managed no,对每块要绑定的网卡都执行一遍。这一步不做的话,后面改完配置文件重启网络,很可能发现配置没生效,因为被 NetworkManager 接管了。
3.2 创建bond主接口配置文件
传统方式下,bond的主配置文件放在/etc/sysconfig/network-scripts/目录,文件名通常是ifcfg-bond0。内容大致如下:
DEVICE=bond0 TYPE=Bond BONDING_MASTER=yes BOOTPROTO=none IPADDR=192.168.1.100 NETMASK=255.255.255.0 GATEWAY=192.168.1.1 ONBOOT=yes BONDING_OPTS="mode=1 miimon=100"这里有几个点值得展开。TYPE=Bond和BONDING_MASTER=yes是告诉系统这是一个bond主接口。BONDING_OPTS里写的就是bonding模块的参数,mode和miimon都在这里指定。如果你选的是mode=4,还需要加上lacp_rate=1和xmit_hash_policy=layer3+4这类参数,前者控制LACP协商速率,后者决定负载均衡的哈希策略。
xmit_hash_policy这个参数在mode=4和mode=2下特别重要。默认是layer2,只根据MAC地址做哈希,在有些场景下流量分布不均匀。改成layer3+4会结合IP和端口做哈希,分布更均匀,但要注意某些交换机对哈希策略有要求,两端最好保持一致。
3.3 配置从属网卡
两块物理网卡的配置文件需要改成从属模式。以ifcfg-eth0为例:
DEVICE=eth0 TYPE=Ethernet BOOTPROTO=none ONBOOT=yes MASTER=bond0 SLAVE=yesMASTER=bond0指向主接口,SLAVE=yes表明自己是从属。ifcfg-eth1同样处理,只是 DEVICE 改成 eth1。注意从属网卡不需要配IP地址,IP是配在bond0上的。
3.4 加载模块与重启网络
配置文件写好后,需要确保bonding模块被加载。可以手动执行modprobe bonding,也可以写一个/etc/modules-load.d/bonding.conf文件,内容就一行bonding,让系统开机自动加载。有些发行版还需要在/etc/modprobe.d/bonding.conf里写alias bond0 bonding和options bond0 mode=1 miimon=100,不过如果BONDING_OPTS里已经指定了参数,这里可以不重复。
重启网络服务:CentOS 7 用systemctl restart network,CentOS 8 及以上用nmcli connection reload配合nmcli connection up bond0。重启后执行cat /proc/net/bonding/bond0,如果能看到两块网卡都列在 "Slave Interface" 下面,且 "MII Status" 是 up,说明bond已经正常工作。
3.5 用nmcli配置的替代路径
如果你的系统以 NetworkManager 为主,用nmcli会更顺手。大致步骤是:先创建bond连接nmcli con add type bond con-name bond0 ifname bond0 mode active-backup,然后给bond配IPnmcli con mod bond0 ipv4.addresses 192.168.1.100/24 ipv4.gateway 192.168.1.1 ipv4.method manual,接着把两块网卡加进去nmcli con add type bond-slave ifname eth0 master bond0和nmcli con add type bond-slave ifname eth1 master bond0,最后nmcli con up bond0激活。
nmcli的好处是配置即时生效、不容易和 NetworkManager 冲突,而且查看状态方便,nmcli con show bond0能看到所有参数。缺点是不同版本的命令参数略有差异,写脚本时要注意兼容性。
4. 验证、切换测试与那些文档里不会写的坑
4.1 怎么确认bond真的在工作
配置完成后,光看ip addr显示bond0有IP还不够,得确认底层链路状态。cat /proc/net/bonding/bond0是最直接的,输出里会显示当前活动网卡("Currently Active Slave")、每块网卡的状态、链路监测统计等。如果活动网卡是eth0,你把eth0的网线拔掉,几秒内活动网卡应该变成eth1,同时业务不中断。
另一个验证方式是看/proc/net/bonding/bond0里的 "Link Failure Count",每块网卡各有一个计数器,切换一次就会加一。这个数字可以用来判断历史上发生过多少次切换,对排查间歇性网络问题很有帮助。
4.2 故障切换测试的正确做法
测试切换时,不要直接拔网线就完事。更接近真实故障的做法是:用ip link set eth0 down模拟网卡下线,观察bond切换和业务连通性;然后再ip link set eth0 up,看它能否自动恢复。如果条件允许,在另一台机器上持续pingbond的IP,观察丢包情况。正常情况下,mode=1的切换丢包在1到3个ping包之间,如果丢包几十个,说明miimon设得太大或者交换机端口收敛太慢。
注意:在虚拟化环境里测试时,有些虚拟网卡的链路状态变化不会及时反映到bond驱动,导致切换测试结果不准确。这种情况下可以改用
ifdown eth0来模拟,效果更接近真实。
4.3 踩坑记录:那些让人抓狂的配置问题
第一个坑是从属网卡上残留了IP地址。如果eth0之前配过IP,改成slave后没清掉,bond起来后可能出现两个IP,路由表混乱。解决办法是在从属配置里确保BOOTPROTO=none且没有IPADDR行,必要时用ip addr flush dev eth0手动清一下。
第二个坑是mode=4下交换机LACP没配。表现是bond0能起来,但只有一块网卡是active,另一块一直是backup或者down。cat /proc/net/bonding/bond0里会显示 "Aggregator ID" 不一致。这时候要去交换机侧确认端口是否配置了LACP,以及是否在同一个聚合组里。
第三个坑是NetworkManager和传统配置打架。改完ifcfg文件重启网络后,发现配置被还原了,或者bond0起不来。原因就是NetworkManager接管了网卡,把手动配置覆盖了。解决办法要么彻底停用NetworkManager,要么改用nmcli来配置,不要两种方式混用。
第四个坑是miimon设得太小导致误切换。有次我把miimon设成10,结果在高负载时bond频繁切换,日志里全是link down/up。后来改回100就稳定了。链路监测不是越频繁越好,要根据实际网卡和交换机性能来定。
4.4 性能调优的几个实用参数
除了mode和miimon,还有几个参数值得关注。xmit_hash_policy在mode=4下影响流量分布,layer3+4通常比默认的layer2更均匀。lacp_rate设为1表示快速发送LACPDU,协商更快,但会增加一点协议开销。primary参数可以指定某块网卡为首选活动网卡,在mode=1下有用,比如你希望流量走万兆卡而不是千兆卡。
另外,如果bond承载的是存储或数据库这类对延迟敏感的业务,建议在交换机侧开启流量控制,并在bond参数里确认没有启用不必要的offload特性。有些网卡的TSO/GSO在bond下可能引发问题,可以用ethtool -K eth0 tso off gso off关掉试试,但这不是通用做法,要看具体网卡型号和驱动版本。
5. 从bond到team:新工具值不值得换
5.1 team的定位与差异
较新的发行版里出现了team这个网络绑定方案,它用用户态守护进程teamd来管理,支持更多负载均衡策略和更灵活的配置。和bonding相比,team的架构更现代,配置用JSON格式,可读性更好。但它的成熟度和社区资料丰富度目前还不如bonding,很多生产环境仍然以bonding为主。
我个人的看法是:如果你维护的是新部署的系统,且团队对team有了解,可以尝试;如果是已有环境或者需要大量参考资料,bonding仍然是更稳妥的选择。两者在核心功能上重叠度很高,不存在谁完全替代谁的问题。
5.2 迁移时的注意事项
从bonding迁移到team,不能直接改配置文件了事,需要先停掉bond、清理从属网卡状态,再用team的方式重新配置。迁移前一定要在测试环境验证,特别是mode=4这种依赖交换机协商的模式,team下的行为和bonding可能有细微差异。迁移过程中业务会短暂中断,要安排好窗口期。
6. 一些实际项目中的经验沉淀
做了这么多年的网络配置,关于bonding我有几个体会。第一,不要为了聚合而聚合。如果你的业务流量本身就不大,mode=1的冗余已经足够,强行上mode=4反而增加了交换机和网卡的配置复杂度,出问题的概率更高。第二,配置变更一定要有回滚方案。改bond配置时,我习惯先把原配置文件备份,并且确保有带外管理或者本地控制台可以操作,万一网络起不来还能救回来。第三,文档要写清楚交换机侧的配置。很多bond问题最后都追溯到交换机端口配置不一致,把两端的配置都记录下来,下次排查能省很多时间。
还有一点是关于监控的。bond的切换事件应该纳入监控告警,/proc/net/bonding/bond0里的 "Link Failure Count" 变化、活动网卡的变更,都值得关注。有些切换是瞬时的,业务没感知,但如果频繁发生,说明链路质量有问题,需要提前处理。我见过一块网卡因为光模块老化,每隔几小时就闪断一次,bond一直在切换,业务虽然没断但性能波动明显,最后换了模块才解决。
最后说一个容易被忽视的场景:虚拟机和容器的bond。在虚拟化环境里,给虚拟机配bond需要宿主机侧的虚拟交换机也支持相应的聚合模式,否则bond起来也是白搭。容器环境里通常用CNI插件管理网络,bonding的配置方式又不一样。这些场景下的bond配置,核心原理相通,但具体操作要结合平台文档来,不能照搬物理机的做法。