做Linux服务器运维的,几乎都会碰到网卡绑定(bond)这个话题。刚入行那会儿,我最怕听到“bond”两个字,因为总觉得它就是个把两块网卡绑一起的活儿,但真到生产环境里一配,发现模式选不对,轻则带宽跑不满,重则直接把业务搞断。后来踩了无数坑,才把bond的7种模式彻底吃透——从mode 0到mode 6,每一种的原理、适用场景、坑点,都是有讲究的,不是随便在配置文件里抄一段就能收工的事。
这篇文章我会把bond的7种模式全部拆开讲清楚,从原理到配置命令,从交换机配合到问题排查,全部用我实际运维中的案例来说。适合刚接手服务器网络的运维新人,也适合那些已经配过bond但一直没搞明白“为什么这么选模式”的同行参考。
1. 网卡绑定到底解决什么问题
1.1 带宽聚合与高可用是两件不同的事
很多人一上来就以为bond就是把两块千兆网卡变成一块两千兆网卡,这个理解其实只对了一半。bond机制本质上做两件事:一是链路冗余,二是带宽叠加,而且这两件事在7种模式里是各有侧重的,不是每一个模式都能同时满足。
举个实际的例子。我之前维护过一台数据库服务器,业务方要求网络必须做到单点无故障,也就是说一块网卡突然挂了,业务不能断。这种情况下,bond的mode 1(主备模式)是最合适的——它的核心目标是冗余而非带宽。但同一批业务里,还有几台文件分发服务器,带宽需求很高,要求两块千兆网卡的带宽都能利用起来,这时就必须考虑负载均衡类模式了。
所以选bond模式,第一步不是看配置模板,而是先回答自己三个问题:这台服务器是数据流量大、还是可靠性要求高、还是两者都要?交换机支不支持LACP协议?网卡本身的性能和虚拟化环境有没有特殊限制?这三个问题直接决定了后面选哪种模式。
1.2 交换机和物理链路的限制,bond应运而生
单块服务器的网卡再快,也受限于协议栈、总线带宽和物理线路的能力。千兆网卡理论带宽是1000Mbps,实际业务跑到800Mbps可能就接近上限了,再往上就容易出现丢包和延迟飙升。万兆网卡虽然快,但成本和交换机的端口成本都很高,不是所有场景都舍得换。
于是就有了bond这种折中方案:用多块物理网卡组合成一块逻辑网卡,对外统一出IP和MAC,对内分别走不同物理链路。关键在于,不同的bond模式处理流量分配的方式完全不同,有的按“包”轮询,有的按“连接”哈希,有的干脆只走一块卡待机,这直接决定了你能用上多少带宽、丢包风险有多大。
还有个物理层面的现实问题:如果两块网卡连到的是同一个交换机,交换机的单点故障依然存在。所以很多正规机房要求bond的两块网卡分别接到两台交换机上,利用堆叠或独立冗余实现更高可用,这个我们在后面交换机配合部分详细讲。
1.3 7种模式先记个总览
Linux内核的bonding驱动一共支持7种模式,编号从0到6,名字分别是balance-rr、active-backup、balance-xor、broadcast、802.3ad、balance-tlb、balance-alb。先把它们的核心特点列个表,后面再逐个拆开讲。
| 模式 | 名称 | 核心机制 | 是否需要交换机支持 | 主要用途 |
|---|---|---|---|---|
| mode 0 | balance-rr | 按包轮流发送 | 不需要 | 双向带宽叠加 |
| mode 1 | active-backup | 主备切换 | 不需要 | 高可用冗余 |
| mode 2 | balance-xor | 按源目MAC/IP哈希分流 | 不需要 | 静态负载均衡 |
| mode 3 | broadcast | 所有包广播到所有从属网卡 | 不需要 | 极少用,高风险 |
| mode 4 | 802.3ad | LACP协议动态聚合 | 必须支持LACP | 标准链路聚合 |
| mode 5 | balance-tlb | 发送负载均衡,接收由网卡决定 | 不需要 | 发送流量大的场景 |
| mode 6 | balance-alb | 发送接收都做负载均衡 | 不需要 | 免交换机配合的聚合 |
注意:mode 0到mode 3,交换机端口通常要配置成静态聚合(trunking)或者干脆不做聚合,因为它们在数据链路层之上自己处理流量分配,交换机的聚合规则会和它们冲突。mode 4则必须交换机配合协商LACP。mode 5和mode 6属于比较“聪明”的模式,交换机端不需要特殊配置,但硬件兼容性要测试。
2. 7种模式逐个拆解:原理、适用场景和坑
2.1 mode 0 balance-rr:轮询聚合,能跑满但会产生乱序
balance-rr是“round-robin”轮询模式,从bond口发出的数据包会按照先后顺序,依次从第一块网卡、第二块网卡、第三块网卡发出去。比如一个TCP连接里连续的几个报文,1号包走eth0,2号包走eth1,3号包又走eth0,循环往复。
它的最大优点是双向带宽能真正叠加,特别是小包转发和多会话场景,性能提升非常明显。我实测过用两块千兆网卡做mode 0跑iPerf,多线程TCP传输总量能到1900Mbps以上,基本吃满了物理链路。
但它有一个致命问题:同一个TCP连接的数据包可能走不同物理链路到达对端,链路延迟不一致时很容易乱序,TCP协议栈会因此频繁触发重传,导致高延迟场景反而性能变差。另外,交换机如果做了静态链路聚合,它的哈希算法和你的轮询逻辑会冲突,交换机可能把一部分包丢弃。所以mode 0更适合“同网段内部多会话、且不跨公网长链路”的场景,比如内网存储同步、大数据节点之间互传,它需要有网卡驱动的hash重排序支持才能发挥最大价值。
配置方式上,mode 0也不需要交换机做什么特殊配合,但一定记住两端交换机端口必须划在同一个VLAN里,并且在交换机上不要启用LACP动态聚合,否则bond口会频繁UP/DOWN抖动。
2.2 mode 1 active-backup:最稳妥的主备冗余
active-backup是我自己在生产环境里用得最多的模式。它的逻辑非常简单:同一时刻只有一块网卡处于Active状态,负责收发所有流量,其他网卡处于Backup状态,监听链路状态。一旦Active网卡物理链路断开或者miimon检测到链路down,bond驱动会把MAC地址迁移到备用网卡上,流量自动切过去,切换速度一般在几百毫秒到1秒左右。
这个模式最适合跑数据库、核心业务系统、KVM宿主机这类对“持续可用”要求很高、但对带宽需求不超过单网卡上限的场景。因为没有了负载均衡的复杂性,它的稳定性和故障可预期性是最好的,只要别在交换机端口开了生成树协议导致阻塞时间过长,基本很少出幺蛾子。
不过有两点要特别注意。第一,mode 1虽然不需要交换机支持LACP,但交换机端口一定要设置成trunk或access,并且两个端口的VLAN配置要一致,不然切换过去之后直接网络不通。第二,如果两块网卡插在同一台物理机上,它们共享同一个PCIe总线或同一个网卡控制器,冗余效果会打折扣,最好让两块网卡分别走不同的控制器、不同的中断,甚至插在不同CPU的PCIe插槽上。
2.3 mode 2 balance-xor:按哈希规则来分流
mode 2的设计思路是解决mode 0的乱序问题。它不再按数据包轮询分配,而是通过哈希算法决定某个方向的流量走哪块网卡。最常见的哈希参数是xmit_hash_policy,可选layer2(源目MAC哈希)、layer2+3(MAC+IP哈希)、layer3+4(IP+端口哈希)。
它的好处是:同一个TCP连接的流量会被哈希到同一块物理网卡上,所以不会被拆散,避免了乱序和重传,对业务来说更友好。坏处是:如果流量主要是两条大连接,恰好哈希到同一块网卡,带宽叠加效果就几乎为零,出现“一块卡跑满、另一块卡闲死”的失衡情况。
我遇到过最典型的案例:某备份服务器用mode 2,xmit_hash_policy选layer2,把两块千兆网卡绑在一起跑NFS备份,结果备份速度始终只有100MB/s左右。后来查了很久才发现,由于NFS客户端都是同一台机器、同一张MAC,layer2哈希把所有流量都分到了同一块网卡上。改成layer3+4并配合IP地址轮询之后,流量才均匀分配,速度翻了近一倍。
所以如果要用mode 2,一定要理解自己的流量模型。大多数内网互访场景,source+dest IP已经能打散流量;如果流量还要细分,再考虑按端口哈希。同时交换机端也需要配置静态聚合,且聚合算法要和bond端哈希规则尽量一致,否则交换机会把本来分给eth1的包分发给eth0,造成丢包。
2.4 mode 3 broadcast:广播模式,备胎中的备胎
broadcast模式比较冷门,它的行为很有意思:每发送一个数据包,就会同时从所有从属网卡各发一份。接收端会收到重复包,靠协议栈去重,这样即便有一条链路出问题,另一端照样能收到完整数据。
这种模式最大的优势是“极端高可靠”,但代价也非常昂贵:带宽不仅不能叠加,还会因为重复包占用大量链路资源。它适用于极少数对延迟抖动零容忍、但又没条件做更复杂冗余方案的特殊环境,比如某些工业控制场景、金融交易行情转发,但不建议常规业务使用。
另外一个问题是,很多交换机对相同源MAC的帧从多个端口进来非常敏感,会直接把它当作环路或MAC漂移处理,甚至把端口给禁用掉。所以mode 3生产环境极少见,我自己只在测试环境里开过一次做对比实验,真实项目里几乎不会选它。
2.5 mode 4 802.3ad:真正的链路聚合,需要交换机配合
mode 4是目前大型数据中心里用的最多的标准聚合方案。它基于IEEE 802.3ad协议,bond口和交换机之间通过LACPDU报文协商,形成一个动态链路聚合组,两端会把成员链路绑定成一个逻辑链路。相比前面几种模式,mode 4的最大优点是:协商机制标准、状态可查、故障切换相对平滑。
在这模式下,出方向流量由xmit_hash_policy决定哈希到哪条链路,入方向流量由交换机的聚合哈希算法决定从哪条链路进来。两端必须使用相同的聚合策略和成员链路数,否则会出现“交换机认为链路A是成员,服务器却认为A是独立链路”的错位,表现为流量忽通忽断或严重丢包。
配置mode 4时,交换机侧通常要在连接服务器的端口上启用LACP动态模式,不同品牌配置语句不一样,华为是interface Eth-Trunk 1 + mode lacp-static,思科是port-channel mode active,H3C和华为类似。服务器端在bonding配置文件中设定mode=4、miimon=100,用lacp_rate来调整LACPDU报文速率,一般默认慢速即可。
注意:mode 4不能随便加网卡。成员链路必须连接在同一台交换机上,或者连接在支持跨设备链路聚合的堆叠/集群交换机上。如果两台交换机不是堆叠关系,而是普通级联,链路聚合会直接失效。
2.6 mode 5 balance-tlb:发送负载均衡,接收靠网卡自己
tlb是“Transmit Load Balancing”的缩写,它只在发送方向做负载均衡,接收方向由当前负载较小或指定的网卡处理。发送时,bond驱动会估算每块网卡的实时负载,把新流量调度到最空闲的一块网卡上,所以它比静态哈希更“智能”,但接收方向没有负载均衡能力,接收流量可能全部集中在一块网卡上。
这种模式的适用场景是:服务器主要往外发数据、接收数据较少,比如日志归档服务器、缓存刷新任务节点。如果业务是下载型或收包型,比如文件下载服务器,那么mode 5就不合适了。
配置上,mode 5同样不需要交换机做任何聚合配置,两块网卡连接普通交换机端口即可,比较适合遇到交换机不支持LACP、又想要多网卡参与发送的场景。不过要注意,网卡必须支持ARP协商,部分老旧网卡驱动在tlb模式下会不稳定,需要实测验证。
2.7 mode 6 balance-alb:发送接收都均衡,最省心
alb是“Adaptive Load Balancing”,是在tlb基础上增加了接收方向的负载均衡能力,主要手段是ARP协商。bond驱动会通过修改ARP应答,让对端设备认为这个bond口具有多个源MAC地址,这样发过来的流量就能被分散到不同网卡上。
mode 6是唯一一个不需要交换机配合、又能做到收发都均衡的模式。在测试环境里,我经常用这个模式快速组建高带宽虚拟化宿主机网络,两块千兆网卡跑多台虚拟机的混合业务,整体表现很稳,TCP总吞吐量也能到1.8Gbps左右。
但它不是没有代价。ARP协商机制在某些交换机的mac地址学习表里会造成MAC地址频繁漂移,如果交换机启用了严格端口安全策略,可能会触发告警甚至封禁端口。另外,mode 6模式下网卡MAC地址会动态变化,一些基于MAC做License授权或安全扫描的业务就需要特别小心。
整体来看,mode 6是“全都要”时的妥协方案:带宽有提升、冗余有保障、交换机不用改配置。但如果生产条件允许,我更推荐优先上mode 4,因为标准和可维护性都更好。
3. 实际配置实操:从modprobe到ifcfg
3.1 加载bonding模块时的参数怎么定
Linux的bond功能由内核模块bonding提供。绝大多数发行版都内置了这个模块,但加载时的一些参数会影响后续模式切换和链路检测,一开始就要确认好。比如:
modprobe bonding mode=1 miimon=100mode参数指定默认bond模式,miimon是链路检测时间间隔,单位是毫秒,意思是每隔100ms通过MII方式检测一次物理链路状态。这个值不是越大越好,也不是越小越好:太小会增加系统开销和误报概率,太大会延长故障切换时间。常规生产建议100ms到200ms之间,千兆网卡基本都够用。
如果想长期生效,需要写入配置。RHEL/CentOS系列通常在/etc/modprobe.d/目录下新建一个bonding.conf:
echo "alias bond0 bonding" > /etc/modprobe.d/bonding.conf echo "options bonding mode=1 miimon=100" >> /etc/modprobe.d/bonding.confUbuntu/Debian系也可以同样方式,路径一样是/etc/modprobe.d/。要注意的是,如果修改了modprobe配置里的mode,必须重新加载模块或重启系统才会生效,光改ifcfg文件里的BONDING_OPTS不一定能覆盖模块默认值;而ifcfg里的BONDING_OPTS在系统启动时会被systemd的网络脚本读取并应用到bond0接口上,所以两者要保持一致。
3.2 基于sysfs和ip命令的临时绑定(适合验证)
在没有生产压力的测试环境,我习惯先用ip命令或sysfs临时创建一个bond口,验证完模式效果再落到永久配置。比如我要临时创建bond0并添加两块网卡:
ip link add bond0 type bond mode 4 miimon 100 ip link set eth0 master bond0 ip link set eth1 master bond0 ip addr add 192.168.10.10/24 dev bond0 ip link set bond0 up这种临时方法的好处是,不需要动任何配置文件,改坏了直接重启网络服务就能恢复。验证完流量分布后,可以用下面的命令删除:
ip link set eth0 nomaster ip link set eth1 nomaster ip link del bond0不过这个方法在部分发行版上,ip命令对bond类型的支持会有差异,比如老版本的iproute2可能不认识mode参数,这时候就需要用到ifenslave或者直接改内核sysfs里/sys/class/net/bond0/bonding/mode进行调试,但生产环境还是建议走标准配置流程。
3.3 RHEL/CentOS风格永久配置(ifcfg-bond0 + 从属网卡)
在RHEL系里,永久配置bond的套路很固定,但很多人会在细节上翻车。我以CentOS 7.9、两块网卡eth0和eth1、mode 4为例写一份标准配置。
先编辑bond0的配置文件/etc/sysconfig/network-scripts/ifcfg-bond0:
DEVICE=bond0 TYPE=Bond NAME=bond0 BONDING_MASTER=yes ONBOOT=yes BOOTPROTO=none IPADDR=192.168.10.10 NETMASK=255.255.255.0 GATEWAY=192.168.10.1 BONDING_OPTS="mode=4 miimon=100 lacp_rate=fast xmit_hash_policy=layer3+4"然后编辑从属网卡配置文件。以eth0为例,/etc/sysconfig/network-scripts/ifcfg-eth0:
DEVICE=eth0 TYPE=Ethernet BOOTPROTO=none ONBOOT=yes MASTER=bond0 SLAVE=yeseth1的配置同理,把DEVICE改成eth1就行。这里有个关键点:从属网卡文件里一定不能配置IP地址,IP只能写在bond0上,否则会出现两个接口都持有IP的混乱状态。另外不同发行版可能要求TYPE=Ethernet,但老的配置里经常写成TYPE=Ethernet且没有NAME字段,其实都可以,关键是确保NetworkManager或network服务能正确识别。
配置完成后执行:
systemctl restart network重启后可以用cat /proc/net/bonding/bond0查看完整状态。
3.4 Ubuntu netplan风格配置
Ubuntu 18.04开始默认用netplan,配置bond的写法跟RHEL完全两套。在/etc/netplan/01-netcfg.yaml里可以这样写:
network: version: 2 renderer: networkd ethernets: eth0: dhcp4: false eth1: dhcp4: false bonds: bond0: interfaces: [eth0, eth1] addresses: [192.168.10.10/24] gateway4: 192.168.10.1 parameters: mode: 802.3ad mii-monitor-interval: 100 lacp-rate: fast transmit-hash-policy: layer3+4注意mode字段在netplan里不能用数字,要用字符串,比如802.3ad对应mode 4,active-backup对应mode 1,balance-rr对应mode 0。写好之后用sudo netplan apply生效,一秒钟就能建好bond口。Ubuntu下如果不用netplan也可以直接用/etc/network/interfaces方式,不过现在的版本我更推荐netplan,因为它的配置更结构化、可读性好。
3.5 验证bond状态的常用命令
配置完成后,一定要学会看bond的运行状态,不然配置对不对只能靠业务反馈来判断,那就慢了。最常用的命令是:
cat /proc/net/bonding/bond0输出里会详细列出bond当前模式、从属网卡、每块网卡在active/backup状态,以及miimon检测状态。另外几个命令也很关键:
ip link show bond0 ip -d link show bond0 ethtool eth0ip -d link可以查看bond口的真实类型和下层成员链路,ethtool eth0可以确认物理链路速率和双工模式。如果发现某块从属网卡状态是DOWN,直接用ethtool去看物理链路是否协商成功,很多时候不是bond配置问题,而是网线没插好或者交换机端口没启用。
4. 模式选型和交换机配合的实战经验
4.1 什么场景选什么模式
很多新手会纠结“到底选哪个模式”,我直接给一个实战选型清单,按场景来选:
| 业务场景 | 推荐模式 | 原因 |
|---|---|---|
| 数据库/核心业务 | mode 1 | 稳定优先,切换逻辑简单 |
| 内网大数据传输 | mode 0 或 mode 4 | 需要带宽叠加,能接受乱序或交换机支持LACP |
| 常规Web服务器 | mode 2 或 mode 4 | 哈希分流不拆连接,对TCP友好 |
| 虚拟化宿主机混合流量 | mode 4 或 mode 6 | 高可用+带宽均衡兼顾 |
| 交换机不支持LACP | mode 6 | 免交换机配合,收发都均衡 |
| 特定高可靠场景 | mode 3 | 极少用,需要严格评估 |
需要强调的是,不要把mode 0当作默认选项,它虽然带宽叠得高,但对业务的影响往往是最隐蔽的,尤其到了跨交换机的复杂网络,乱序带来的重传反而拖慢速度。
4.2 交换机端LACP配置要点
选mode 4时,交换机端配置不能出错。以华为交换机为例,连接服务器两个端口一般这样配置:
interface Eth-Trunk1 port link-type trunk port trunk allow-pass vlan 10 mode lacp-static然后把服务器接入端口加入Eth-Trunk:
interface GigabitEthernet0/0/1 eth-trunk 1 interface GigabitEthernet0/0/2 eth-trunk 1思科交换机则用:
interface Port-channel1 switchport trunk allowed vlan 10 interface GigabitEthernet0/1 channel-group 1 mode active interface GigabitEthernet0/2 channel-group 1 mode active这里有个非常容易踩的坑:服务器的两个网口必须接入交换机的同一个Eth-Trunk逻辑口,不能在交换机上把两个物理口分别配成两个access口再去连服务器,否则bond口能up但流量会随机走一条链路,另一条链路完全不参与转发。
4.3 双交换机堆叠与跨交换机bond的坑
如果服务器追求更高的冗余级别,两块网卡会分别接到两台交换机上。这时候只有两类方案靠谱:一是两台交换机做了堆叠或者集群(比如华为的CSS、思科的VPC、H3C的IRF),对于服务器来说它们逻辑上还是一台交换机,可以正常用mode 4;二是两台交换机没有堆叠,那就只能退用mode 1或mode 6,靠服务器侧自己做主备切换,不能指望交换机的链路聚合去跨设备协商。
我在项目里就见过一次事故:运维把两块网卡接了不同机柜的两台交换机,然后强行配了mode 4,结果LACPDU协商失败,bond物理口频繁UP/DOWN,业务直接中断。后来改成mode 1,问题立刻消失。所以选型之前,先搞清楚机房交换机的型号和堆叠状态,别想当然。
5. 常见问题与排查技巧实录
5.1 bond起来了但不通或丢包严重
这类问题多半出在链路协商和交换机配置上。先按下面的顺序排:
- 执行ethtool eth0和ethtool eth1,确认双端速率和双工模式都是1000Mb/s和Full。
- 检查交换机端口是否处于Err-Disable状态,有些交换机检测到MAC漂移会主动禁用端口。
- 用tcpdump在bond口和物理口上同时抓包,看物理口是否有流量进入但bond口没有转发。
- 检查
cat /proc/net/bonding/bond0里是否有“link failure count”异常增长,增长太快说明链路不稳定。
印象最深的一次是,bond口配好后能ping通网关,但跨网段访问时丢包严重,最后发现是交换机两个端口开启了STP,端口从阻塞到转发花了30秒,在bond的miimon100ms检测下,一个端口刚UP,另一个端口还在STP等待,流量混乱导致丢包。解决办法是在交换机端口配置portfast/edge-port,或者调整STP参数。
5.2 miimon和arp_interval到底配哪个
miimon基于物理链路状态检测,是最常用也最可靠的方案,但它有个盲区:如果交换机端口没有物理down,而是网线接到了错误的VLAN,或者上游出现了逻辑故障,miimon可能感知不到。这时候可以考虑arp_interval + arp_ip_target,让bond通过定期发送ARP请求来检测IP层的连通性。
配置方式是在BONDING_OPTS里加:
BONDING_OPTS="mode=1 miimon=0 arp_interval=1000 arp_ip_target=192.168.10.1"注意miimon和arp_interval不能混用,需要二选一,同时要指定一个稳定的网关或对端IP作为ARP探测目标。这个方案对于mode 1特别有用,能在物理链路正常但逻辑不通时实现切换。不过它的缺点是依赖目标IP可达性,如果目标IP本身抖动频繁,会导致误切换,所以生产上我还是倾向于miimon为主,特殊情况再叠加ARP检测。
5.3 网卡MAC地址处理与虚拟机环境特别提醒
bond模式切换时,内核会把active网卡的MAC地址同步到backup网卡上,这样才能保证对端ARP缓存不变。但如果你的服务器在虚拟化平台里,比如KVM或VMware虚拟机,虚拟网卡的MAC地址是由虚拟化层管理的,用bond时很可能出现MAC地址漂移问题。我之前在VMware虚拟机里做bond测试,就遇到过两块虚拟网卡MAC不同、bond切换后对端ARP表刷新不及时的情况,流量延迟增加很明显。
虚拟机里做bond,最稳的做法是先把两块虚拟网卡的MAC地址固定成同一个(很多虚拟化平台允许手动指定),或者在bond配置中设置fail_over_mac=1,让bond在切换时不改变物理网卡的MAC,而是通过更新ARP表来通知对端。另外,虚拟机网卡类型尽量选择virtio或vmxnet3,这类驱动对bonding的支持更完善。
5.4 踩坑记录:一次模式调优把自己关在门外
最后分享一个教训。有一次我远程配置一台服务器的bond,原本是mode 4,我改成mode 6并重启网络服务。结果SSH当场断掉,因为mode 6的ARP协商让交换机临时学习到了新的MAC对应关系,而我的SSH连接是走的老的MAC表项,导致回包全部被丢弃。后来是通过带外管理口登上去才恢复的。
从那以后,我给自己定了一个规矩:凡是远程改bond,必须在计划窗口执行,并且保留一个独立管理口或者带外通道作为逃生通道。改完配置后,不要急着把当前SSH会话断掉,先新开一个终端测试网络连通性,确认无误后再关闭旧会话。这是远程运维bond最基本的保命手段。
另外,改bond配置后,不要马上重启服务器,而是先用ip link set eth0 nomaster这类命令做回滚验证,确认新配置稳定后再写入开机自启。很多生产故障,都是因为“配完直接重启”导致系统起来后发现网络没起,最后只能跑机房连显示器抢救,那场面真的不好受。