前言
干运维这行十年了,见过太多因为单网卡故障导致的生产事故。记得2019年那会,某电商客户双十一当天,核心交易服务器的网卡突然挂了,整整断网40分钟,直接损失几百万。事后复盘,其实就是一块几十块钱的网卡坏了,但因为没做任何冗余,结果损失惨重。
从那以后,我就把网卡Bonding当成服务器上架的标配操作。这玩意配置起来不复杂,但能在关键时刻救命。今天就把这些年踩过的坑、总结的经验都写出来,希望能帮到同行们少走弯路。
一、Bonding技术概述
1.1 什么是网卡Bonding
简单说,Bonding就是把多块物理网卡绑定成一个逻辑网卡。对上层应用来说,它只看到一个网络接口,但底层实际上有多块网卡在工作。这样做有两个核心好处:
第一是高可用。任何一块物理网卡坏了,流量自动切换到其他网卡,业务无感知。
第二是带宽聚合。多块网卡的带宽可以叠加使用,比如两块千兆网卡绑定后理论上能跑到2Gbps。
Linux内核从2.0版本就开始支持Bonding了,到现在已经非常成熟稳定。2025年的主流发行版,不管是RHEL 9、Ubuntu 24.04还是Debian 12,都对Bonding有完善的支持。
1.2 Bonding的工作原理
Bonding驱动在内核层面工作,它会创建一个虚拟的bond接口,然后把多个物理网卡(称为slave)挂载到这个虚拟接口下面。所有发往bond接口的流量,都会根据配置的模式分发到各个slave网卡上。
从协议栈的角度看,流量是这样走的:
应用程序
|
TCP/IP协议栈
|
Bond虚拟接口(bond0)
|
+---+---+
| |
eth0 eth1
| |
物理交换机
Bond接口有自己的MAC地址,默认会使用第一个slave网卡的MAC。当然这个可以手动指定,后面会讲到。
1.3 为什么要用Bonding而不是其他方案
有人可能会问,现在不是有很多高可用方案吗,比如Keepalived、HAProxy这些,为啥还要用Bonding?
这里要搞清楚一点:Bonding解决的是单机网卡层面的冗余,而Keepalived这些解决的是服务层面的冗余。两者不是替代关系,而是互补关系。
举个例子,你用Keepalived做了MySQL主从切换,但如果主库的网卡坏了,Keepalived检测到故障需要时间,切换也需要时间,这期间业务就是中断的。但如果主库本身做了Bonding,网卡坏了流量瞬间切换,Keepalived根本感知不到,业务完全无损。
所以我的建议是:关键业务服务器,Bonding是必须的,在此基础上再叠加服务层面的高可用方案。
二、Bonding模式详解
Linux Bonding支持7种工作模式,编号从0到6。每种模式的特点和适用场景都不一样,选错模式可能达不到预期效果。下面逐个分析。
2.1 Mode 0:balance-rr(轮询模式)
这是最简单的模式,数据包轮流从各个slave网卡发出去。比如第一个包从eth0发,第二个包从eth1发,第三个包又从eth0发,以此类推。
优点:
- 配置简单,不需要交换机配合
- 理论上可以实现带宽叠加
缺点:
- 可能导致数据包乱序,对TCP连接有影响
- 某些交换机可能因为MAC地址在多个端口出现而产生困惑
适用场景: 说实话,生产环境我几乎不用这个模式。因为数据包乱序的问题在高负载下会很明显,可能导致TCP重传增加,反而降低性能。如果你的场景主要是UDP流量,可以考虑。
2.2 Mode 1:active-backup(主备模式)
这是我用得最多的模式。顾名思义,同一时间只有一块网卡在工作,其他网卡作为备份。主网卡故障时,自动切换到备份网卡。
优点:
- 配置简单,不需要交换机任何特殊配置
- 切换速度快,通常在毫秒级
- 稳定可靠,几乎不会出问题
缺点:
- 不能实现带宽叠加,同时只用一块网卡的带宽
- 备份网卡平时闲置,有点浪费
适用场景: 大多数需要高可用但对带宽要求不那么极端的场景。比如数据库服务器、应用服务器、管理网络等。这个模式我推荐作为默认选择,除非有特殊需求。
2.3 Mode 2:balance-xor(异或模式)
这个模式根据源MAC地址和目标MAC地址做异或运算,结果决定用哪块网卡发送。相同的源目地址对,总是走同一块网卡。
优点:
- 可以实现一定程度的负载均衡
- 同一个连接的数据包不会乱序
缺点:
- 需要交换机支持,要配置端口聚合
- 负载均衡效果取决于连接数,连接少的话可能分布不均
适用场景: 需要负载均衡且交换机支持静态聚合的场景。
2.4 Mode 3:broadcast(广播模式)
所有数据包都从所有slave网卡发送出去。
说实话这个模式我从来没在生产环境用过。它的主要用途是一些特殊的容错场景,比如两块网卡连到两个完全独立的网络,确保数据一定能送达。但这种场景太少见了。
2.5 Mode 4:802.3ad(LACP动态链路聚合)
这是IEEE标准协议,也叫LACP(Link Aggregation Control Protocol)。它需要交换机也支持LACP,双方协商后建立聚合链路。
优点:
- 标准协议,兼容性好
- 真正的带宽聚合
- 自动故障检测和恢复
缺点:
- 必须交换机支持LACP并正确配置
- 配置相对复杂
- 负载均衡效果取决于hash算法和流量模式
适用场景: 对带宽有较高要求,且交换机支持LACP的场景。比如存储服务器、大数据节点、虚拟化宿主机等。这是目前业界用得最多的聚合模式。
2.6 Mode 5:balance-tlb(自适应传输负载均衡)
这个模式比较聪明,它根据每个slave网卡的负载情况动态分配出站流量。负载低的网卡会分配更多流量。
优点:
- 不需要交换机特殊配置
- 出站流量可以负载均衡
缺点:
- 入站流量不能负载均衡,都走主网卡
- 实现相对复杂,可能有兼容性问题
适用场景: 交换机不支持聚合,但又想实现出站负载均衡的场景。
2.7 Mode 6:balance-alb(自适应负载均衡)
这是Mode 5的增强版,不仅出站流量负载均衡,入站流量也能均衡。它通过ARP协商来实现,会主动修改ARP响应中的MAC地址。
优点:
- 不需要交换机特殊配置
- 出入站流量都能负载均衡
缺点:
- ARP操作可能在某些网络环境下有问题
- 虚拟化环境下可能不work
适用场景: 物理服务器环境,交换机不支持聚合但需要双向负载均衡。
2.8 模式选择建议
基于这些年的经验,我总结了一个选择流程:
- 如果只需要高可用,不需要带宽叠加 -> Mode 1(active-backup)
- 如果需要带宽聚合,交换机支持LACP -> Mode 4(802.3ad)
- 如果需要带宽聚合,交换机只支持静态聚合 -> Mode 2(balance-xor)
- 如果交换机啥都不支持,又想负载均衡 -> Mode 6(balance-alb)
90%的场景,用Mode 1或Mode 4就够了。
三、Bonding配置实战
3.1 环境准备
在开始配置之前,先检查几个前提条件。
确认内核支持Bonding:
# 检查bonding模块
lsmod | grep bonding
# 如果没有加载,手动加载
modprobe bonding
# 查看模块信息
modinfo bonding
在现代Linux发行版上,bonding模块默认都是编译进内核的,一般不需要额外安装。
确认有多块网卡:
# 查看所有网络接口
ip link show
# 或者用老命令
ifconfig -a
# 查看网卡详细信息
ethtool eth0
ethtool eth1
确认网卡连接状态:
# 查看链路状态
ethtool eth0 | grep "Link detected"
ethtool eth1 | grep "Link detected"
# 或者
cat /sys/class/net/eth0/carrier
cat /sys/class/net/eth1/carrier
3.2 RHEL/Rocky/AlmaLinux 9 配置方法
RHEL系从版本8开始推荐使用nmcli(NetworkManager命令行工具)来管理网络。RHEL 9上,传统的network-scripts已经彻底移除了。
3.2.1 使用nmcli配置Mode 1(主备模式)
# 创建bond接口
nmcli connection add type bond \
con-name bond0 \
ifname bond0 \
bond.options "mode=active-backup,miimon=100,primary=ens33"
# 添加第一个slave
nmcli connection add type ethernet \
slave-type bond \
con-name bond0-slave1 \
ifname ens33 \
master bond0
# 添加第二个slave
nmcli connection add type ethernet \
slave-type bond \
con-name bond0-slave2 \
ifname ens34 \
master bond0
# 配置IP地址
nmcli connection modify bond0 \
ipv4.addresses 192.168.1.100/24 \
ipv4.gateway 192.168.1.1 \
ipv4.dns "8.8.8.8,8.8.4.4" \
ipv4.method manual
# 启动bond
nmcli connection up bond0
参数说明:
- mode=active-backup:主备模式
- miimon=100:每100毫秒检测一次链路状态
- primary=ens33:指定ens33为主网卡
3.2.2 使用nmcli配置Mode 4(LACP模式)
# 创建bond接口
nmcli connection add type bond \
con-name bond0 \
ifname bond0 \
bond.options "mode=802.3ad,miimon=100,lacp_rate=fast,xmit_hash_policy=layer3+4"
# 添加slave
nmcli connection add type ethernet \
slave-type bond \
con-name bond0-slave1 \
ifname ens33 \
master bond0
nmcli connection add type ethernet \
slave-type bond \
con-name bond0-slave2 \
ifname ens34 \
master bond0
# 配置IP
nmcli connection modify bond0 \
ipv4.addresses 192.168.1.100/24 \
ipv4.gateway 192.168.1.1 \
ipv4.method manual
# 启动
nmcli connection up bond0
参数说明:
- mode=802.3ad:LACP模式
- lacp_rate=fast:快速LACP协商(每秒一次),默认是slow(每30秒一次)
- xmit_hash_policy=layer3+4:使用IP地址和端口号做hash,负载均衡效果更好
3.2.3 查看和管理bond状态
# 查看bond状态
cat /proc/net/bonding/bond0
# 查看连接状态
nmcli connection show
# 查看设备状态
nmcli device status
# 查看详细配置
nmcli connection show bond0
# 临时禁用某个slave(测试用)
nmcli device disconnect ens33
# 重新启用
nmcli device connect ens33
3.3 Ubuntu 24.04 配置方法
Ubuntu从17.10开始使用Netplan作为网络配置工具,底层可以选择NetworkManager或systemd-networkd作为渲染器。服务器版默认用systemd-networkd。
3.3.1 Netplan配置Mode 1
编辑配置文件 /etc/netplan/01-bond-config.yaml:
network:
version: 2
renderer: networkd
ethernets:
ens33:
dhcp4: false
dhcp6: false
ens34:
dhcp4: false
dhcp6: false
bonds:
bond0:
interfaces:
- ens33
- ens34
addresses:
- 192.168.1.100/24
routes:
- to: default
via: 192.168.1.1
nameservers:
addresses:
- 8.8.8.8
- 8.8.4.4
parameters:
mode: active-backup
primary: ens33
mii-monitor-interval: 100
fail-over-mac-policy: active
应用配置:
# 检查配置语法
netplan try
# 应用配置
netplan apply
# 查看状态
networkctl status bond0
3.3.2 Netplan配置Mode 4
network:
version: 2
renderer: networkd
ethernets:
ens33:
dhcp4: false
ens34:
dhcp4: false
bonds:
bond0:
interfaces:
- ens33
- ens34
addresses:
- 192.168.1.100/24
routes:
- to: default
via: 192.168.1.1
nameservers:
addresses:
- 8.8.8.8
parameters:
mode: 802.3ad
lacp-rate: fast
mii-monitor-interval: 100
transmit-hash-policy: layer3+4
3.3.3 使用systemd-networkd直接配置
如果不想用Netplan,也可以直接写systemd-networkd配置文件。
创建 /etc/systemd/network/10-bond0.netdev:
[NetDev]
Name=bond0
Kind=bond
[Bond]
Mode=802.3ad
TransmitHashPolicy=layer3+4
MIIMonitorSec=100ms
LACPTransmitRate=fast
创建 /etc/systemd/network/20-bond0-slave.network:
[Match]
Name=ens33 ens34
[Network]
Bond=bond0
创建 /etc/systemd/network/30-bond0.network:
[Match]
Name=bond0
[Network]
Address=192.168.1.100/24
Gateway=192.168.1.1
DNS=8.8.8.8
重启网络服务:
systemctl restart systemd-networkd
3.4 Debian 12 配置方法
Debian 12可以使用传统的ifupdown配置,也可以使用systemd-networkd。这里演示ifupdown方式。
首先安装ifenslave:
apt install ifenslave
编辑 /etc/network/interfaces:
# 回环接口
auto lo
iface lo inet loopback
# 物理网卡设为手动模式
auto ens33
iface ens33 inet manual
bond-master bond0
auto ens34
iface ens34 inet manual
bond-master bond0
# Bond接口配置
auto bond0
iface bond0 inet static
address 192.168.1.100
netmask 255.255.255.0
gateway 192.168.1.1
dns-nameservers 8.8.8.8
bond-slaves ens33 ens34
bond-mode active-backup
bond-miimon 100
bond-primary ens33
重启网络:
systemctl restart networking
3.5 配置永久加载bonding模块
确保bonding模块开机自动加载:
# RHEL系
echo "bonding" > /etc/modules-load.d/bonding.conf
# Debian/Ubuntu
echo "bonding" >> /etc/modules
# 配置模块参数(可选)
cat > /etc/modprobe.d/bonding.conf << EOF
options bonding max_bonds=0
EOF
max_bonds=0表示不自动创建bond接口,让网络管理工具来创建。
四、交换机配置
Bonding的某些模式需要交换机配合配置,特别是Mode 4(LACP)。这里给出几个主流交换机的配置示例。
4.1 华为交换机配置LACP
# 进入系统视图
system-view
# 创建链路聚合组
interface Eth-Trunk 1
mode lacp-static
# 将端口加入聚合组
interface GigabitEthernet 0/0/1
eth-trunk 1
interface GigabitEthernet 0/0/2
eth-trunk 1
# 配置负载均衡模式
interface Eth-Trunk 1
load-balance src-dst-ip
# 查看聚合状态
display eth-trunk 1
4.2 思科交换机配置LACP
# 进入全局配置模式
configure terminal
# 创建Port-Channel
interface Port-channel1
switchport mode access
switchport access vlan 100
# 将端口加入Port-Channel
interface range GigabitEthernet0/1-2
channel-group 1 mode active
# 配置负载均衡
port-channel load-balance src-dst-ip
# 查看状态
show etherchannel summary
show lacp neighbor
4.3 H3C交换机配置LACP
# 进入系统视图
system-view
# 创建聚合接口
interface Bridge-Aggregation 1
link-aggregation mode dynamic
# 将端口加入聚合组
interface GigabitEthernet 1/0/1
port link-aggregation group 1
interface GigabitEthernet 1/0/2
port link-aggregation group 1
# 配置负载均衡
link-aggregation load-sharing mode destination-ip source-ip
# 查看状态
display link-aggregation verbose
4.4 交换机配置注意事项
- 端口属性要一致:聚合组内的所有端口,速率、双工模式、VLAN配置必须完全一致,否则聚合会失败。
- LACP模式选择:交换机端可以配置为active或passive。建议服务器和交换机至少有一端是active,否则协商不会启动。
- 负载均衡算法:交换机和服务器的负载均衡算法最好配置成一样的,比如都用layer3+4,这样流量分布更均匀。
- 生成树协议:聚合端口通常不需要启用STP,因为聚合本身就是冗余的。但如果网络拓扑复杂,还是建议保留。
- 跨设备聚合:如果要把服务器的两块网卡分别连到两台交换机,需要交换机支持跨设备聚合(如华为的Eth-Trunk跨框、思科的vPC/VSS)。这种配置更复杂,但可用性更高。
五、高级配置与调优
5.1 ARP监控配置
除了MII监控,Bonding还支持ARP监控。ARP监控通过定期发送ARP请求来检测链路状态,比MII监控更可靠,因为它能检测到网络不通但链路层正常的情况。
# nmcli配置ARP监控
nmcli connection modify bond0 \
bond.options "mode=active-backup,arp_interval=1000,arp_ip_target=192.168.1.1"
参数说明:
- arp_interval=1000:每1000毫秒发送一次ARP请求
- arp_ip_target=192.168.1.1:ARP请求的目标地址,通常设为网关
注意:ARP监控和MII监控不能同时使用。
5.2 多个ARP目标
可以配置多个ARP目标地址,提高检测可靠性:
nmcli connection modify bond0 \
bond.options "mode=active-backup,arp_interval=1000,arp_ip_target=192.168.1.1+192.168.1.2+192.168.1.3,arp_all_targets=any"
arp_all_targets参数:
- any:任意一个目标可达就认为链路正常
- all:所有目标都可达才认为链路正常
5.3 配置Bond接口的MAC地址
默认情况下,bond接口使用第一个slave的MAC地址。可以手动指定:
# 设置固定MAC
nmcli connection modify bond0 \
ethernet.cloned-mac-address "00:11:22:33:44:55"
或者配置fail_over_mac参数控制故障切换时的MAC行为:
nmcli connection modify bond0 \
bond.options "mode=active-backup,miimon=100,fail_over_mac=active"
fail_over_mac选项:
- none:默认值,bond接口MAC不变
- active:bond接口使用当前active slave的MAC
- follow:active slave的MAC跟随bond接口
5.4 LACP参数调优
使用Mode 4时,有几个重要参数可以调优:
nmcli connection modify bond0 \
bond.options "mode=802.3ad,miimon=100,lacp_rate=fast,ad_select=bandwidth,xmit_hash_policy=layer3+4"
参数说明:
lacp_rate:
- slow:默认值,每30秒发送一次LACPDU
- fast:每秒发送一次LACPDU,故障检测更快
ad_select:聚合组选择策略
- stable:默认值,选择后不再改变
- bandwidth:选择带宽最大的聚合组
- count:选择端口数最多的聚合组
xmit_hash_policy:发送hash策略
- layer2:基于MAC地址hash
- layer3+4:基于IP地址和端口号hash(推荐)
- layer2+3:基于MAC和IP地址hash
- encap2+3:针对隧道封装流量
- encap3+4:针对隧道封装流量,使用内层IP
5.5 配置多个Bond接口
一台服务器可以配置多个bond接口,用于不同网络:
# 业务网bond
nmcli connection add type bond \
con-name bond0 \
ifname bond0 \
bond.options "mode=802.3ad,miimon=100,xmit_hash_policy=layer3+4"
nmcli connection add type ethernet \
slave-type bond \
con-name bond0-slave1 \
ifname ens33 \
master bond0
nmcli connection add type ethernet \
slave-type bond \
con-name bond0-slave2 \
ifname ens34 \
master bond0
nmcli connection modify bond0 \
ipv4.addresses 192.168.1.100/24 \
ipv4.gateway 192.168.1.1 \
ipv4.method manual
# 管理网bond
nmcli connection add type bond \
con-name bond1 \
ifname bond1 \
bond.options "mode=active-backup,miimon=100"
nmcli connection add type ethernet \
slave-type bond \
con-name bond1-slave1 \
ifname ens35 \
master bond1
nmcli connection add type ethernet \
slave-type bond \
con-name bond1-slave2 \
ifname ens36 \
master bond1
nmcli connection modify bond1 \
ipv4.addresses 10.0.0.100/24 \
ipv4.method manual
# 启动
nmcli connection up bond0
nmcli connection up bond1
5.6 Bond接口配置VLAN
bond接口上可以叠加VLAN配置:
# 先创建bond
nmcli connection add type bond \
con-name bond0 \
ifname bond0 \
bond.options "mode=802.3ad,miimon=100"
# ... 添加slave省略 ...
# 在bond上创建VLAN接口
nmcli connection add type vlan \
con-name bond0.100 \
dev bond0 \
id 100 \
ipv4.addresses 192.168.100.10/24 \
ipv4.method manual
nmcli connection add type vlan \
con-name bond0.200 \
dev bond0 \
id 200 \
ipv4.addresses 192.168.200.10/24 \
ipv4.method manual
这种配置常用于服务器需要接入多个VLAN的场景,比如虚拟化宿主机。
六、监控与运维
6.1 Bond状态检查脚本
写一个实用的检查脚本:
#!/bin/bash
# bond_check.sh - 检查bonding状态
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
check_bond() {
local bond=$1
local bond_file="/proc/net/bonding/${bond}"
if [[ ! -f "$bond_file" ]]; then
echo -e "${RED}[ERROR]${NC} Bond interface ${bond} does not exist"
return 1
fi
echo "=========================================="
echo "Checking: ${bond}"
echo "=========================================="
# 获取bond模式
local mode=$(grep "Bonding Mode:" "$bond_file" | cut -d: -f2 | xargs)
echo "Mode: ${mode}"
# 获取MII状态
local mii_status=$(grep "MII Status:" "$bond_file" | head -1 | cut -d: -f2 | xargs)
if [[ "$mii_status" == "up" ]]; then
echo -e "Bond MII Status: ${GREEN}${mii_status}${NC}"
else
echo -e "Bond MII Status: ${RED}${mii_status}${NC}"
fi
# 检查各slave状态
echo ""
echo "Slave Interfaces:"
local slave_count=0
local active_count=0
while IFS= read -r line; do
if [[ "$line" =~ ^Slave\ Interface:\ (.+) ]]; then
current_slave="${BASH_REMATCH[1]}"
((slave_count++))
fi
if [[ "$line" =~ ^MII\ Status:\ (.+) ]]; then
if [[ -n "$current_slave" ]]; then
status="${BASH_REMATCH[1]}"
if [[ "$status" == "up" ]]; then
echo -e " - ${current_slave}: ${GREEN}${status}${NC}"
((active_count++))
else
echo -e " - ${current_slave}: ${RED}${status}${NC}"
fi
current_slave=""
fi
fi
done < <(tail -n +10 "$bond_file")
echo ""
echo "Summary: ${active_count}/${slave_count} slaves active"
if [[ $active_count -eq 0 ]]; then
echo -e "${RED}[CRITICAL]${NC} No active slaves!"
return 2
elif [[ $active_count -lt $slave_count ]]; then
echo -e "${YELLOW}[WARNING]${NC} Some slaves are down"
return 1
else
echo -e "${GREEN}[OK]${NC} All slaves are active"
return 0
fi
}
# 主程序
if [[ $# -eq 0 ]]; then
# 检查所有bond接口
for bond in /proc/net/bonding/bond*; do
if [[ -f "$bond" ]]; then
bond_name=$(basename "$bond")
check_bond "$bond_name"
echo ""
fi
done
else
# 检查指定的bond接口
for bond in "$@"; do
check_bond "$bond"
echo ""
done
fi
使用方法:
chmod +x bond_check.sh
# 检查所有bond
./bond_check.sh
# 检查指定bond
./bond_check.sh bond0
6.2 Prometheus监控配置
使用node_exporter可以采集bonding指标。确保node_exporter启用了bonding collector:
# 启动node_exporter时启用bonding collector
./node_exporter --collector.bonding
然后配置Prometheus告警规则:
groups:
- name: bonding
rules:
# Bond接口有slave down
- alert: BondingSlaveDegraded
expr: node_bonding_slaves - node_bonding_active != 0
for: 1m
labels:
severity: warning
annotations:
summary: "Bonding interface degraded on {{ $labels.instance }}"
description: "Bond {{ $labels.master }} has {{ $value }} inactive slaves"
# Bond接口完全down
- alert: BondingInterfaceDown
expr: node_bonding_active == 0
for: 30s
labels:
severity: critical
annotations:
summary: "Bonding interface down on {{ $labels.instance }}"
description: "Bond {{ $labels.master }} has no active slaves"
Grafana面板示例:
{
"panels": [
{
"title": "Bond Active Slaves",
"type": "stat",
"targets": [
{
"expr": "node_bonding_active{instance=\"$instance\"}",
"legendFormat": "{{ master }}"
}
]
},
{
"title": "Bond Status",
"type": "table",
"targets": [
{
"expr": "node_bonding_slaves{instance=\"$instance\"} - node_bonding_active{instance=\"$instance\"}",
"legendFormat": "{{ master }}"
}
]
}
]
}
6.3 日志监控
bonding相关的日志在系统日志中,可以这样监控:
# 实时查看bonding日志
journalctl -f | grep -i bonding
# 或者
tail -f /var/log/messages | grep -i bonding
配置rsyslog转发bonding日志:
# /etc/rsyslog.d/bonding.conf
:msg, contains, "bonding" /var/log/bonding.log
& stop
6.4 定期健康检查Cron任务
# /etc/cron.d/bond-check
*/5 * * * * root /usr/local/bin/bond_check.sh > /dev/null 2>&1 || echo "Bond degraded on $(hostname)" | mail -s "Bond Alert" ops@example.com
七、故障排查指南
7.1 常见问题:Bond接口无法启动
现象:配置完成后,bond接口无法UP。
排查步骤:
# 1. 检查bonding模块是否加载
lsmod | grep bonding
# 2. 检查配置文件语法
# RHEL/Rocky
nmcli connection show bond0
# Ubuntu
netplan try
# 3. 检查slave网卡状态
ip link show ens33
ip link show ens34
# 4. 查看系统日志
journalctl -xe | grep -i bond
dmesg | grep -i bond
# 5. 检查是否有IP冲突
arping -I bond0 192.168.1.100
常见原因:
- slave网卡已经配置了IP地址,需要先清除
- slave网卡被其他进程占用
- bonding模块参数错误
解决方法:
# 清除slave网卡的IP配置
ip addr flush dev ens33
ip addr flush dev ens34
# 重新加载配置
nmcli connection reload
nmcli connection up bond0
7.2 常见问题:LACP协商失败
现象:配置了Mode 4,但bond状态显示不正常,没有建立聚合。
排查步骤:
# 1. 检查LACP状态
cat /proc/net/bonding/bond0
# 注意看Partner Mac Address是否为00:00:00:00:00:00
# 2. 抓包看LACPDU
tcpdump -i ens33 ether proto 0x8809 -vv
# 3. 检查交换机配置
# 登录交换机查看聚合状态
常见原因:
- 交换机没有配置LACP或配置错误
- 交换机端口模式不匹配(access vs trunk)
- 交换机端口VLAN配置不一致
- 网线连接错误
解决方法:
- 确认交换机配置正确
- 确保端口属性一致
- 尝试将交换机LACP模式改为active
7.3 常见问题:Slave频繁切换
现象:bond运行中,slave频繁在up和down之间切换。
排查步骤:
# 1. 查看切换日志
journalctl -u NetworkManager | grep -i bond
# 2. 检查网卡和链路状态
ethtool ens33
ethtool ens34
# 3. 检查miimon设置是否合理
cat /proc/net/bonding/bond0 | grep "MII Polling"
# 4. 检查网卡驱动和固件版本
ethtool -i ens33
常见原因:
- 网线接触不良
- 网卡或交换机端口硬件问题
- 网卡驱动bug
- miimon设置太短
解决方法:
- 更换网线
- 更换网卡或交换机端口
- 更新网卡驱动
- 适当增加miimon值(如200ms)
7.4 常见问题:Mode 4流量不均衡
现象:使用LACP模式,但流量明显偏向某一块网卡。
排查步骤:
# 1. 查看各slave的流量统计
cat /proc/net/bonding/bond0
# 或者用ip命令
ip -s link show ens33
ip -s link show ens34
# 2. 检查hash策略
cat /proc/net/bonding/bond0 | grep "Transmit Hash"
# 3. 分析流量模式
iftop -i bond0
原因分析: LACP的负载均衡是基于hash的,如果流量都来自少量的源或目的地址,hash结果可能都落到同一块网卡上。
解决方法:
- 改用layer3+4的hash策略(如果还没用的话)
- 这是正常现象,hash负载均衡不是绝对均匀的
- 如果需要更均匀的分布,考虑Mode 6(balance-alb)
7.5 常见问题:虚拟机中Bonding不工作
现象:在虚拟机中配置bonding,功能不正常。
这个问题比较常见,原因是虚拟化平台的虚拟交换机可能对bonding的某些模式支持不好。
VMware环境:
- Mode 1(active-backup)通常没问题
- Mode 4(LACP)需要vDS(分布式交换机)且配置LAG
- Mode 6(balance-alb)可能不工作,因为ARP代理受限
KVM/libvirt环境:
- 建议在宿主机而不是虚拟机中配置bonding
- 如果必须在VM中配置,使用bridge网络且确保宿主机桥接配置正确
解决方法:
- 虚拟机中优先使用Mode 1
- 如果需要带宽聚合,在虚拟化平台层面做聚合
7.6 调试命令汇总
# 查看bond详细状态
cat /proc/net/bonding/bond0
# 查看所有网络接口
ip addr show
ip link show
# 查看网卡详细信息
ethtool eth0
ethtool -i eth0 # 驱动信息
ethtool -S eth0 # 统计信息
# 查看ARP表
ip neigh show
# 抓包分析
tcpdump -i bond0 -nn
tcpdump -i ens33 ether proto 0x8809 -vv # LACP
# 查看系统日志
journalctl -xe | grep -i bond
dmesg | grep -i bond
# NetworkManager调试
nmcli general logging level DEBUG domain ALL
journalctl -u NetworkManager -f
# 重新加载配置
nmcli connection reload
systemctl restart NetworkManager
八、实战案例
8.1 案例一:电商核心交易库高可用改造
背景: 某电商平台的MySQL主库单网卡部署,之前发生过网卡故障导致服务中断的情况。需要改造为双网卡bonding,要求不能影响现有业务。
环境:
- 操作系统:Rocky Linux 9.3
- 服务器:Dell PowerEdge R750
- 网卡:板载双千兆 + 双万兆网卡
- 交换机:华为CE6800系列,支持LACP
方案设计:
- 使用两块万兆网卡做bond,配置Mode 4(LACP)
- 利用维护窗口期执行变更
- 提前在测试环境验证
实施步骤:
# 1. 检查当前网络配置
ip addr show
nmcli connection show
# 当前配置:
# ens33: 192.168.1.100/24 (业务IP)
# ens34: 未配置
# ens35: 未配置
# ens36: 10.0.0.100/24 (管理IP)
# 2. 交换机配置(由网络工程师执行)
# 华为交换机配置LACP
# interface Eth-Trunk 10
# mode lacp-static
# interface 10GE1/0/1
# eth-trunk 10
# interface 10GE1/0/2
# eth-trunk 10
# 3. 服务器端配置
# 备份当前配置
nmcli connection show --active > /root/network_backup.txt
# 创建bond接口(先不配IP)
nmcli connection add type bond \
con-name bond0 \
ifname bond0 \
bond.options "mode=802.3ad,miimon=100,lacp_rate=fast,xmit_hash_policy=layer3+4"
# 添加slave
nmcli connection add type ethernet \
slave-type bond \
con-name bond0-port1 \
ifname ens34 \
master bond0
nmcli connection add type ethernet \
slave-type bond \
con-name bond0-port2 \
ifname ens35 \
master bond0
# 4. 关键步骤:IP迁移
# 这一步需要快速执行,建议写成脚本
cat > /root/migrate_ip.sh << 'EOF'
#!/bin/bash
set -e
# 删除原网卡IP
nmcli connection down ens33-connection
# 配置bond IP
nmcli connection modify bond0 \
ipv4.addresses 192.168.1.100/24 \
ipv4.gateway 192.168.1.1 \
ipv4.dns "8.8.8.8" \
ipv4.method manual
# 启动bond
nmcli connection up bond0
echo "Migration completed"
EOF
chmod +x /root/migrate_ip.sh
# 5. 执行迁移(维护窗口内)
# 先通过管理IP连接服务器
ssh admin@10.0.0.100
# 执行迁移脚本
/root/migrate_ip.sh
# 6. 验证
cat /proc/net/bonding/bond0
ping -c 3 192.168.1.1
nmcli connection show --active
验证结果:
Bonding Mode: IEEE 802.3ad Dynamic link aggregation
Transmit Hash Policy: layer3+4 (1)
MII Status: up
MII Polling Interval (ms): 100
LACP rate: fast
Slave Interface: ens34
MII Status: up
Speed: 10000 Mbps
Permanent HW addr: 00:11:22:33:44:55
Slave Interface: ens35
MII Status: up
Speed: 10000 Mbps
Permanent HW addr: 00:11:22:33:44:56
故障测试:
# 模拟网卡故障
nmcli device disconnect ens34
# 查看bond状态
cat /proc/net/bonding/bond0
# 应显示ens34为down,但bond接口仍然正常
# 业务验证
mysql -h192.168.1.100 -uroot -p -e "SELECT 1"
# 应该正常返回
# 恢复
nmcli device connect ens34
8.2 案例二:Kubernetes Worker节点网络优化
背景: 某公司的Kubernetes集群Worker节点跑容器业务,单网卡带宽经常跑满。需要增加网络带宽,同时保证高可用。
环境:
- 操作系统:Ubuntu 24.04 LTS
- Kubernetes:1.31
- 服务器:自组装服务器,4块Intel i350千兆网卡
- 交换机:普通千兆交换机,不支持LACP
方案设计: 由于交换机不支持LACP,选择Mode 6(balance-alb)来实现负载均衡,不需要交换机配合。
Netplan配置文件 /etc/netplan/01-bond-config.yaml:
network:
version: 2
renderer: networkd
ethernets:
enp1s0:
dhcp4: false
enp2s0:
dhcp4: false
enp3s0:
dhcp4: false
enp4s0:
dhcp4: false
bonds:
bond0:
interfaces:
- enp1s0
- enp2s0
- enp3s0
- enp4s0
addresses:
- 192.168.1.101/24
routes:
- to: default
via: 192.168.1.1
nameservers:
addresses:
- 8.8.8.8
parameters:
mode: balance-alb
mii-monitor-interval: 100
mtu: 9000
注意这里还配置了巨型帧(MTU 9000),可以进一步提升大数据量传输的性能。
应用配置:
# 验证配置
netplan try
# 应用
netplan apply
# 查看状态
networkctl status bond0
cat /proc/net/bonding/bond0
Kubernetes CNI配置调整:
使用Calico时,需要确保Calico使用bond接口:
# 检查Calico自动发现的IP
kubectl get node k8s-worker-1 -o jsonpath='{.status.addresses}'
# 如果需要指定,修改Calico配置
kubectl -n kube-system edit daemonset calico-node
# 添加环境变量:IP_AUTODETECTION_METHOD=interface=bond0
性能测试:
# 安装iperf3
apt install iperf3
# 服务端
iperf3 -s
# 客户端(4个并发连接测试)
iperf3 -c 192.168.1.101 -P 4
# 预期结果:总带宽接近4Gbps(4块千兆网卡)
8.3 案例三:VMware ESXi环境下的Bond配置
背景: VMware ESXi 8.0环境,需要在虚拟机(RHEL 9)中配置bonding,虚拟机有两块虚拟网卡连接到不同的物理上行链路。
这个场景稍微特殊,因为需要在虚拟化层面和虚拟机内部同时做配置。
ESXi端配置:
- 确保虚拟机有两块网卡,分别连接到不同的vSwitch上行链路
- 虚拟交换机需要开启”允许MAC地址变更”和”允许伪传输”(因为bonding会修改MAC)
vSphere Web Client中:
- 选择vSwitch -> 编辑设置
- 安全策略:
- 允许MAC地址变更:是
- 允许伪传输:是
- 混杂模式:否(不需要)
虚拟机内部配置:
由于ESXi不支持真正的LACP(除非用vDS),虚拟机内只能用Mode 1(active-backup):
# 创建bond
nmcli connection add type bond \
con-name bond0 \
ifname bond0 \
bond.options "mode=active-backup,miimon=100,fail_over_mac=active"
# fail_over_mac=active 很重要,让MAC跟随active接口
# 否则VMware可能会丢包
# 添加slave
nmcli connection add type ethernet \
slave-type bond \
con-name bond0-eth0 \
ifname ens192 \
master bond0
nmcli connection add type ethernet \
slave-type bond \
con-name bond0-eth1 \
ifname ens224 \
master bond0
# 配置IP
nmcli connection modify bond0 \
ipv4.addresses 192.168.1.50/24 \
ipv4.gateway 192.168.1.1 \
ipv4.method manual
# 启动
nmcli connection up bond0
测试failover:
# 在vSphere中断开其中一块网卡的上行链路
# 或者在VM中:
nmcli device disconnect ens192
# 检查bond状态
cat /proc/net/bonding/bond0
# 应该自动切换到ens224,网络不中断
ping -c 10 192.168.1.1
8.4 案例四:跨机房双活网络架构
背景: 某金融客户要实现跨机房双活,服务器需要同时连接两个机房的网络。每个机房各有一根专线,要求任一专线故障业务不受影响。
这是个相对复杂的场景,需要结合Bonding和策略路由。
网络架构:
+-------------------+
| 应用服务器 |
| bond0: 双网卡 |
+--------+----------+
|
+--------------+--------------+
| |
+-----+-----+ +-----+-----+
| eth0 | | eth1 |
+-----+-----+ +-----+-----+
| |
+-----+-----+ +-----+-----+
| 机房A交换机 | | 机房B交换机 |
+-----------+ +-----------+
| |
专线接入机房A 专线接入机房B
配置步骤:
# 1. 创建主备模式bond,eth0为主
nmcli connection add type bond \
con-name bond0 \
ifname bond0 \
bond.options "mode=active-backup,miimon=100,primary=eth0,arp_interval=1000,arp_ip_target=10.1.1.1+10.2.1.1,arp_all_targets=any"
# 这里使用ARP监控而不是MII,因为要检测的是到网关的连通性
# arp_ip_target配置两个机房的网关
# 2. 添加slave
nmcli connection add type ethernet \
slave-type bond \
con-name bond0-eth0 \
ifname eth0 \
master bond0
nmcli connection add type ethernet \
slave-type bond \
con-name bond0-eth1 \
ifname eth1 \
master bond0
# 3. 配置IP
nmcli connection modify bond0 \
ipv4.addresses 10.1.1.100/24 \
ipv4.gateway 10.1.1.1 \
ipv4.routes "10.2.0.0/16 10.1.1.1 100" \
ipv4.method manual
# 启动
nmcli connection up bond0
配置策略路由,确保回程流量走正确的路径:
# 添加路由表
echo "100 dc_a" >> /etc/iproute2/rt_tables
echo "200 dc_b" >> /etc/iproute2/rt_tables
# 配置策略路由规则
cat > /etc/networkd-dispatcher/routable.d/policy-route.sh << 'EOF'
#!/bin/bash
# 机房A的流量走机房A网关
ip route add default via 10.1.1.1 table dc_a
ip rule add from 10.1.1.100 table dc_a priority 100
# 机房B的流量走机房B网关(当failover到机房B时)
ip route add default via 10.2.1.1 table dc_b
ip rule add from 10.2.1.100 table dc_b priority 100
EOF
chmod +x /etc/networkd-dispatcher/routable.d/policy-route.sh
这个配置确保了:
- 正常情况下,流量走机房A
- 机房A专线故障时,ARP检测失败,自动切换到机房B
- 切换后,流量自动走机房B的路径
九、最佳实践总结
9.1 配置最佳实践
- 模式选择:
- 单纯高可用选Mode 1,简单可靠
- 需要带宽聚合且交换机支持LACP选Mode 4
- 交换机不支持聚合但需要负载均衡选Mode 6
- 监控间隔设置:
- miimon建议设置100ms,既能快速检测故障,又不会造成太大开销
- 如果网络不太稳定,可以适当增加到200ms,避免误切换
- ARP监控:
- 关键业务建议启用ARP监控,能检测到三层网络问题
- arp_ip_target设置为网关或上游可靠设备的IP
- LACP参数:
- lacp_rate建议设置为fast,加快故障检测
- xmit_hash_policy建议用layer3+4,负载均衡效果更好
- 命名规范:
- Bond接口用bond0、bond1命名
- 连接名用有意义的名字,如bond0-mgmt、bond0-storage
9.2 运维最佳实践
- 变更窗口:
- 网络配置变更务必在维护窗口执行
- 保留备用访问通道(如管理网、IPMI/iDRAC)
- 回滚预案:
- 变更前备份配置
- 准备回滚脚本
- 设置定时任务自动回滚(万一连不上)
# 自动回滚示例
# 在变更前执行
echo "nmcli connection down bond0; nmcli connection up eth0" | at now + 10 minutes
# 变更成功后取消
atrm $(atq | awk '{print $1}')
- 监控告警:
- Bond状态必须纳入监控
- Slave数量少于配置数量时告警
- 定期检查Bond健康状态
- 文档记录:
- 记录每台服务器的Bond配置
- 记录交换机端口对应关系
- 配置变更要更新文档
9.3 故障处理最佳实践
- 故障定级:
- 所有Slave down = P0(紧急)
- 部分Slave down = P1(重要,需尽快处理)
- 应急处理:
- 业务影响时优先恢复服务
- 可以临时配置单网卡运行
- 事后再排查根因
- 复盘改进:
- 每次故障后要复盘
- 改进监控和告警
- 完善应急预案
十、总结
写到这里,差不多把这些年关于网卡Bonding的经验都掏出来了。总结几个核心观点:
- Bonding是服务器的基本保障。任何稍微重要一点的服务器,都应该配置网卡冗余。一块几十块的网卡故障导致几十万甚至几百万的损失,这种事情完全可以避免。
- 配置不复杂,重在理解。Bonding的配置命令就那么几条,但要用好它,需要理解各种模式的原理、交换机的配合、监控参数的含义。理解了这些,配置就是水到渠成的事。
- 选对模式很重要。大部分场景Mode 1或Mode 4就够了。别为了追求花哨选一些不合适的模式,简单可靠才是王道。
- 监控和告警不能少。配置完不是终点,要纳入监控。Slave down了没人知道,等Bond完全挂了才发现就晚了。
- 定期演练。找个维护窗口,手动拔一根网线,验证一下failover是不是真的work。光配置不测试,心里没底。
最后,技术在不断发展,Linux内核的Bonding模块也在持续优化。保持学习,关注最新的变化,才能不被淘汰。
希望这篇文章对大家有帮助。有问题欢迎交流。
参考资料:
IEEE 802.3ad Link Aggregation Standard
Linux Kernel Documentation – Bonding
Red Hat Enterprise Linux 9 Networking Guide
Ubuntu Server Guide – Network Configuration