LACP 链路聚合技术详解
LACP 链路聚合技术
在 GPU 裸金属服务器和数据中心网络中,单条网卡的带宽和可靠性都不够。LACP(Link Aggregation Control Protocol)将多条物理链路捆绑为一条逻辑链路,实现带宽叠加、链路冗余和负载分担——这是裸金属服务器网络配置的基石。
概述
链路聚合(Link Aggregation)是将多个物理网络接口合并为一个逻辑接口的技术。LACP(Link Aggregation Control Protocol,链路聚合控制协议)是 IEEE 802.3ad 标准定义的协商协议,用于两端设备自动协商聚合组的形成和成员状态。
在 GPU 集群中,链路聚合用于:
- 管理网络:双网卡 bonding,保证 BMC/SSH 管理通道高可用
- 存储网络:多条 100GbE 聚合,支撑分布式文件系统的高吞吐
- 业务网络:多网卡负载分担,提升整体带宽
flowchart LR
subgraph 服务器侧
A[eth0<br/>100GbE]
B[eth1<br/>100GbE]
C[eth2<br/>100GbE]
D[eth3<br/>100GbE]
end
A --> LA[bond0<br/>逻辑接口<br/>LACP]
B --> LA
C --> LA
D --> LA
LA --> SW[交换机聚合组<br/>Port-Channel]
subgraph 交换机侧
SW --> P0[端口1]
SW --> P1[端口2]
SW --> P2[端口3]
SW --> P3[端口4]
end
P0 -.->|LACPDU 协商| A
P1 -.->|LACPDU 协商| B
P2 -.->|LACPDU 协商| C
P3 -.->|LACPDU 协商| D
style LA fill:#4a9eff,color:#fff
style SW fill:#f59e0b,color:#fff
一、LACP 协议原理
1.1 核心概念
| 概念 | 含义 |
|---|---|
| LAG(Link Aggregation Group) | 链路聚合组,多个物理端口的集合 |
| Aggregator | 聚合器,将 LAG 呈现为单一逻辑端口 |
| LACPDU | LACP 数据单元,两端协商的报文 |
| Actor / Partner | 本端 / 对端(LACP 协商中的角色命名) |
| System Priority | 系统优先级,决定哪端做主动方 |
| Port Priority | 端口优先级,决定哪些端口被选入活跃组 |
| Operational Key | 操作密钥,标识聚合组能力(速率/双工) |
1.2 LACP 协商流程
sequenceDiagram
participant S as 服务器 (Actor)
participant SW as 交换机 (Partner)
Note over S,SW: 1. 初始状态:两端均未聚合
S->>SW: LACPDU (Actor: S, Partner: 空, Active)
SW->>S: LACPDU (Actor: SW, Partner: S, Active)
Note over S,SW: 2. 交换参数:系统优先级、端口能力
S->>SW: LACPDU (Key=速率+双工, State=同步中)
SW->>S: LACPDU (Key=速率+双工, State=同步中)
Note over S,SW: 3. 参数匹配:速率/双工/Key 一致
S->>SW: LACPDU (State=已同步, Collecting+Distributing)
SW->>S: LACPDU (State=已同步, Collecting+Distributing)
Note over S,SW: 4. 聚合建立:双方开始转发流量
Note over S,SW: 5. 周期性 LACPDU 保活(默认 30s / 快速 1s)
1.3 LACP 模式
| 模式 | 行为 | 特点 | 适用场景 |
|---|---|---|---|
| Active(主动) | 主动发送 LACPDU | 总是尝试建立聚合 | 推荐,两端至少一端 Active |
| Passive(被动) | 仅响应 LACPDU | 等待对方发起 | 谨慎场景,减少误聚合 |
关键规则:LACP 聚合至少需要一端为 Active 模式。两端都为 Passive 则永远不会建立聚合。
1.4 LACPDU 状态标志
| 标志位 | 含义 |
|---|---|
| Activity | 0=Passive, 1=Active |
| Timeout | 0=Long(30s), 1=Short(1s) |
| Aggregation | 0=Individual, 1=Aggregatable |
| Synchronization | 0=未同步, 1=已同步 |
| Collecting | 0=不接收, 1=接收流量 |
| Distributing | 0=不发送, 1=发送流量 |
| Default | 0=使用对端默认值, 1=使用对端配置值 |
| Expired | 0=未过期, 1=已过期(超时) |
二、Linux Bonding 模式
Linux 内核提供 bonding 驱动,支持 7 种模式,其中 Mode 4 对应 LACP。
2.1 七种 Bonding 模式对比
| 模式 | 名称 | 协议 | 负载分担 | 冗余 | 交换机配置 | 典型场景 |
|---|---|---|---|---|---|---|
| 0 | balance-rr | 无 | 轮询 | 是 | 无需特殊配置 | 最大带宽,但乱序风险 |
| 1 | active-backup | 无 | 否(主备) | 是 | 无需特殊配置 | 管理网络高可用 |
| 2 | balance-xor | 无 | XOR hash | 是 | 无需特殊配置 | 确定性分流 |
| 3 | broadcast | 无 | 广播 | 是 | 无需特殊配置 | 特殊容错场景 |
| 4 | 802.3ad | LACP | 是 | 是 | 需配置 LACP | 生产推荐 |
| 5 | balance-tlb | 无 | 发送负载 | 是 | 无需特殊配置 | 无 LACP 支持时 |
| 6 | balance-alb | 无 | 收发负载 | 是 | 无需特殊配置 | 无 LACP 支持时 |
2.2 Mode 4 (LACP) 详解
flowchart TB
subgraph "Linux Bonding Mode 4 (802.3ad / LACP)"
subgraph "发送方向"
TX[应用数据] --> HASH[流量分发 Hash]
HASH -->|flow 1| S0[eth0 发送]
HASH -->|flow 2| S1[eth1 发送]
HASH -->|flow 3| S2[eth2 发送]
HASH -->|flow 4| S3[eth3 发送]
end
subgraph "接收方向"
R0[eth0 接收] --> AGG[聚合到 bond0]
R1[eth1 接收] --> AGG
R2[eth2 接收] --> AGG
R3[eth3 接收] --> AGG
end
subgraph "LACP 协商"
L0[eth0 ←→ SW Port1]
L1[eth1 ←→ SW Port2]
L2[eth2 ←→ SW Port3]
L3[eth3 ←→ SW Port4]
end
end
流量分发机制(Hash 策略):
| xmit_hash_policy | 说明 | 分流粒度 | 适用场景 |
|---|---|---|---|
| layer2 | 仅用 MAC 地址 | 交换机友好 | 少量主机间通信 |
| layer2+3 | MAC + IP | 较均衡 | 推荐,通用场景 |
| layer3+4 | IP + Port | 最均衡 | 推荐,高并发场景 |
| encap2+3 | VLAN + MAC + IP | 较均衡 | VLAN 环境 |
| encap3+4 | VLAN + IP + Port | 最均衡 | VLAN + 高并发 |
关键理解:LACP 不是”单条流量的带宽叠加”。一条 TCP 连接只会走一条物理链路。LACP 提升的是多条并发连接的总带宽。选择 layer3+4 策略可以让不同 TCP/UDP 流分散到不同链路。
三、Linux Bonding 配置
3.1 配置方式一:sysfs + ifcfg(RHEL/CentOS/Rocky)
# ====== 1. 加载 bonding 模块 ======
modprobe bonding
echo "bonding" >> /etc/modules-load.d/bonding.conf
# ====== 2. 配置 bond0 接口 ======
# /etc/sysconfig/network-scripts/ifcfg-bond0
cat > /etc/sysconfig/network-scripts/ifcfg-bond0 << 'EOF'
DEVICE=bond0
NAME=bond0
TYPE=Bond
BONDING_MASTER=yes
IPADDR=10.0.20.100
PREFIX=24
GATEWAY=10.0.20.1
ONBOOT=yes
BOOTPROTO=none
BONDING_OPTS="mode=4 miimon=100 lacp_rate=1 xmit_hash_policy=layer3+4"
# mode=4: LACP (802.3ad)
# miimon=100: 链路监控频率 100ms
# lacp_rate=1: 快速 LACPDU(1秒),默认 0=慢速(30秒)
# xmit_hash_policy=layer3+4: IP+Port 分流
EOF
# ====== 3. 配置成员接口 ======
# /etc/sysconfig/network-scripts/ifcfg-eth0
cat > /etc/sysconfig/network-scripts/ifcfg-eth0 << 'EOF'
DEVICE=eth0
NAME=eth0
TYPE=Ethernet
ONBOOT=yes
BOOTPROTO=none
MASTER=bond0
SLAVE=yes
EOF
# /etc/sysconfig/network-scripts/ifcfg-eth1
cat > /etc/sysconfig/network-scripts/ifcfg-eth1 << 'EOF'
DEVICE=eth1
NAME=eth1
TYPE=Ethernet
ONBOOT=yes
BOOTPROTO=none
MASTER=bond0
SLAVE=yes
EOF
# ====== 4. 重启网络 ======
nmcli connection reload
nmcli connection up bond0
3.2 配置方式二:nmcli(NetworkManager)
# 创建 bond0 接口
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"
# 设置 IP
nmcli connection modify bond0 ipv4.addresses 10.0.20.100/24
nmcli connection modify bond0 ipv4.gateway 10.0.20.1
nmcli connection modify bond0 ipv4.method manual
# 添加成员接口
nmcli connection add type ethernet con-name eth0-bond ifname eth0 \
master bond0
nmcli connection add type ethernet con-name eth1-bond ifname eth1 \
master bond0
# 激活
nmcli connection up bond0
3.3 配置方式三:Netplan(Ubuntu)
# /etc/netplan/01-bonding.yaml
network:
version: 2
renderer: networkd
ethernets:
eth0:
dhcp4: no
eth1:
dhcp4: no
eth2:
dhcp4: no
eth3:
dhcp4: no
bonds:
bond0:
interfaces: [eth0, eth1, eth2, eth3]
addresses: [10.0.20.100/24]
routes:
- to: default
via: 10.0.20.1
parameters:
mode: 802.3ad
miimon: 100
lacp-rate: fast
transmit-hash-policy: layer3+4
sudo netplan apply
3.4 验证 Bond 状态
# 查看 bond 接口概要
cat /proc/net/bonding/bond0
# 预期输出:
# Ethernet Channel Bonding Driver: v3.7.1
# Bonding Mode: IEEE 802.3ad Dynamic link aggregation
# Transmit Hash Policy: layer3+4 (802.3ad Layer 3+4)
# MII Status: up
# MII Polling Interval (ms): 100
# Up Delay (ms): 0
# Down Delay (ms): 0
#
# 802.3ad info
# LACP rate: fast
# LACPDU Max Rx: 65535
#
# Slave Interface: eth0
# MII Status: up
# Speed: 100000 Mbps
# Duplex: full
# Link Failure Count: 0
# Permanent HW addr: xx:xx:xx:xx:xx:xx
# Slave queue ID: 0
# Aggregator ID: 1
# Actor Churn State: none
# Partner Churn State: none
# Actor System Priority: 65535
# Partner System Priority: 32768
# Actor System: xx:xx:xx:xx:xx:xx
# Partner System: xx:xx:xx:xx:xx:xx
# Actor Key: 9
# Partner Key: 1
# Actor Port State: 63 ← 63=全活跃(Active+Short+Agg+Sync+Coll+Dist)
# Partner Port State: 63
# 查看 LACPDU 统计
ip -s link show bond0
# 查看各成员链路状态
ip link show master bond0
Actor Port State 解码:
| 位 | 标志 | 值=0 | 值=1 |
|---|---|---|---|
| 0 | Activity | Passive | Active |
| 1 | Timeout | Long(30s) | Short(1s) |
| 2 | Aggregation | Individual | Aggregatable |
| 3 | Synchronization | 未同步 | 已同步 |
| 4 | Collecting | 不接收 | 接收 |
| 5 | Distributing | 不发送 | 发送 |
63 = 0b111111 = 所有标志位为 1 = 链路完全活跃。如果值为 0b001100 = 28,表示已同步但不收发,说明聚合协商未完成。
四、交换机侧配置
4.1 Cisco(NX-OS / IOS)
# ====== Cisco NX-OS ======
# 进入配置模式
configure terminal
# 创建 Port-Channel
interface port-channel10
description GPU-Node-01-Bond0
switchport mode trunk
switchport trunk allowed vlan 20,30
spanning-tree port type edge trunk
# 配置成员端口
interface Ethernet1/1
description GPU-Node-01-eth0
channel-group 10 mode active ! active = LACP Active
no shutdown
interface Ethernet1/2
description GPU-Node-01-eth1
channel-group 10 mode active
no shutdown
interface Ethernet1/3
description GPU-Node-01-eth2
channel-group 10 mode active
no shutdown
interface Ethernet1/4
description GPU-Node-01-eth3
channel-group 10 mode active
no shutdown
# 设置 LACP 快速模式
lacp rate fast interface Ethernet1/1
lacp rate fast interface Ethernet1/2
lacp rate fast interface Ethernet1/3
lacp rate fast interface Ethernet1/4
# 设置 LACP 系统优先级(小的优先)
lacp system-priority 4096
end
# 验证
show port-channel summary
show lacp port-channel 10
show lacp neighbor
4.2 华为 / 华三(VRP / Comware)
# ====== 华为 VRP ======
system-view
# 创建 Eth-Trunk
interface Eth-Trunk10
description GPU-Node-01-Bond0
mode lacp-static ! 静态 LACP 模式
trunkport GigabitEthernet 1/0/1 to 1/0/4
# 配置成员端口
interface GigabitEthernet1/0/1
eth-trunk 10
lacp priority 100 ! 端口优先级(小的优先活跃)
interface GigabitEthernet1/0/2
eth-trunk 10
lacp priority 200
interface GigabitEthernet1/0/3
eth-trunk 10
lacp priority 300
interface GigabitEthernet1/0/4
eth-trunk 10
lacp priority 400
# LACP 系统优先级
lacp priority 100
# LACP 超时模式
interface Eth-Trunk10
lacp timeout fast ! 快速超时(3秒)
# 验证
display eth-trunk 10
display lacp verbose
4.3 Mellanox Onyx(Spectrum 交换机)
# Mellanox 交换机常用于 GPU 集群的 RoCE/IB 网络
# ====== Mellanox Onyx ======
enable
configure terminal
# 创建 Port-Channel
interface port-channel 10
description GPU-Node-01-Bond0
no shutdown
exit
# 配置成员端口
interface ethernet 1/1
channel-group 10 mode active
no shutdown
exit
interface ethernet 1/2
channel-group 10 mode active
no shutdown
exit
# LACP 快速模式
interface ethernet 1/1
lacp rate fast
interface ethernet 1/2
lacp rate fast
# 验证
show interfaces port-channel 10
show lacp port-channel 10
五、GPU 集群中的链路聚合场景
5.1 三网分离架构
GPU 集群通常采用管理网、存储网、计算网三网分离,每个网络都使用链路聚合。
flowchart TB
subgraph "GPU 裸金属服务器"
subgraph "管理网络"
MGMT0[eth0<br/>1GbE]
MGMT1[eth1<br/>1GbE]
MGMT0 --> MB[bond0<br/>active-backup<br/>Mode 1]
MGMT1 --> MB
end
subgraph "存储网络"
STO0[eth2<br/>25GbE]
STO1[eth3<br/>25GbE]
STO0 --> SB[bond1<br/>LACP Mode 4]
STO1 --> SB
end
subgraph "计算网络 (RDMA/RoCE)"
COMP0[eth4<br/>100GbE]
COMP1[eth5<br/>100GbE]
COMP2[eth6<br/>100GbE]
COMP3[eth7<br/>100GbE]
COMP0 -.-> CB[bond2<br/>LACP Mode 4<br/>或独立使用]
COMP1 -.-> CB
COMP2 -.-> CB
COMP3 -.-> CB
end
end
MB --> MGMT_SW[管理交换机]
SB --> STO_SW[存储交换机]
CB --> COMP_SW[计算交换机<br/>Spine-Leaf]
5.2 各网络 Bonding 策略
| 网络 | 带宽需求 | Bonding 模式 | xmit_hash_policy | 交换机 | 理由 |
|---|---|---|---|---|---|
| 管理网 | 低 (1GbE) | Mode 1 (active-backup) | N/A | 无需 LACP | 管理流量小,主备足够,避免交换机配置 |
| 存储网 | 高 (25-100GbE) | Mode 4 (LACP) | layer3+4 | 需配 LACP | 多并发 IO 流需要带宽叠加 |
| 计算网 | 极高 (100-400GbE) | 不 Bonding | N/A | 各自独立 | RDMA/RoCE 要求无损网络,Bonding 会破坏 RoCE PFC/ECN |
重要:计算网络(RDMA/RoCE)通常不使用 Bonding!RDMA 需要精确的 PFC(Priority Flow Control)和 ECN 配置,Bonding 的负载分担会打乱流量到端口的映射,导致 PFC 失效。正确做法是每张网卡独立配置 RoCE,由 NCCL 层面做多路径通信。
5.3 管理网络 active-backup 配置
# 管理网络:Mode 1 (active-backup) —— 最简单的冗余方案
# /etc/sysconfig/network-scripts/ifcfg-bond0
DEVICE=bond0
IPADDR=10.0.10.100
PREFIX=24
GATEWAY=10.0.10.1
ONBOOT=yes
BOOTPROTO=none
BONDING_OPTS="mode=1 miimon=100 primary=eth0"
# mode=1: active-backup(主备)
# miimon=100: 100ms 检测链路状态
# primary=eth0: 优先使用 eth0
# 成员接口
# ifcfg-eth0, ifcfg-eth1: MASTER=bond0, SLAVE=yes
5.4 存储网络 LACP 配置
# 存储网络:Mode 4 (LACP) —— 带宽叠加 + 冗余
# /etc/sysconfig/network-scripts/ifcfg-bond1
DEVICE=bond1
IPADDR=10.0.30.100
PREFIX=24
MTU=9000 # Jumbo Frame,存储网络必备
ONBOOT=yes
BOOTPROTO=none
BONDING_OPTS="mode=4 miimon=100 lacp_rate=1 xmit_hash_policy=layer3+4"
# MTU=9000: 开启巨型帧,提升存储网络吞吐
# 交换机侧需同步开启 Jumbo Frame
六、监控与排障
6.1 Bond 状态监控
# 实时监控 bond 状态(每秒刷新)
watch -n 1 'cat /proc/net/bonding/bond0'
# 监控各成员链路流量
watch -n 1 'ip -s link show master bond0'
# 查看 LACPDU 收发统计
cat /proc/net/bonding/bond0 | grep -A2 "LACP"
6.2 Prometheus 监控指标
# node_exporter 自动采集 bond 接口指标
# 关键指标:
# node_network_up{device="bond0"} — bond 接口状态
# node_network_receive_bytes_total{device="eth0"} — 各成员接收字节
# node_network_transmit_bytes_total{device="eth1"} — 各成员发送字节
# PromQL: 检查 bond 成员链路是否均衡
# 各成员发送流量
sum(rate(node_network_transmit_bytes_total{device=~"eth[0-3]", instance="gpu-node-01"}[5m])) by (device)
# bond 总流量
rate(node_network_transmit_bytes_total{device="bond0", instance="gpu-node-01"}[5m])
# 成员链路数量(活跃成员数)
count by (instance) (node_network_up{device=~"eth[0-9]+", instance="gpu-node-01"} == 1)
# Alertmanager 告警规则
groups:
- name: bonding
rules:
# bond 接口 down
- alert: BondInterfaceDown
expr: node_network_up{device=~"bond[0-9]+"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Bond 接口 {{ $labels.device }} 在 {{ $labels.instance }} 上 down"
# bond 成员减少
- alert: BondSlaveCountReduced
expr: count by (instance, device) (node_network_up{device=~"eth[0-9]+"} == 1) < 2
for: 2m
labels:
severity: warning
annotations:
summary: "{{ $labels.instance }} bond 成员链路数量减少"
description: "活跃成员数 < 2,可能存在物理链路故障"
# bond 成员流量严重不均
- alert: BondTrafficImbalance
expr: |
stddev by (instance) (
rate(node_network_transmit_bytes_total{device=~"eth[0-9]+"}[5m])
) /
avg by (instance) (
rate(node_network_transmit_bytes_total{device=~"eth[0-9]+"}[5m])
) > 0.8
for: 10m
labels:
severity: info
annotations:
summary: "{{ $labels.instance }} bond 成员流量严重不均"
description: "标准差/均值 > 0.8,可能 hash 策略不合适或存在单流瓶颈"
6.3 常见故障排查
| 故障现象 | 可能原因 | 排查步骤 | 解决方案 |
|---|---|---|---|
| bond0 状态 down | 所有成员链路断 | ip link show bond0 | 检查物理线缆和交换机端口 |
| 成员未加入聚合 | LACP 协商失败 | 检查两端 LACP 模式 | 至少一端设为 Active |
| 成员 Collecting only | 对端未 Distributing | 检查交换机 Port-Channel | 确保交换机侧成员都 active |
| 流量只走一条链路 | hash 策略不当 | 检查 xmit_hash_policy | 改用 layer3+4 |
| 偶发丢包 | LACP 超时太长 | 检查 lacp_rate | 设为 fast(1s) |
| MTU 不匹配 | 巨型帧配置不一致 | ip link show 对比两端 | bond+成员+交换机统一 MTU |
| MAC 地址冲突 | bond MAC 来源异常 | 检查 fail_over_mac | 设置 fail_over_mac=1 |
6.4 诊断脚本
"""LACP Bond 诊断工具"""
from dataclasses import dataclass, field
import subprocess
import re
@dataclass
class BondSlave:
interface: str
mii_status: str # up / down
speed: str # 100000 Mbps
duplex: str # full / half
link_failure_count: int = 0
aggregator_id: int = 0
actor_port_state: int = 0
partner_port_state: int = 0
lacp_active: bool = False
lacp_synced: bool = False
lacp_collecting: bool = False
lacp_distributing: bool = False
@dataclass
class BondStatus:
bond_name: str
bonding_mode: str
xmit_hash_policy: str
mii_status: str
miimon: int = 0
lacp_rate: str = ""
slaves: list[BondSlave] = field(default_factory=list)
class BondDiagnostics:
"""Bond/LACP 诊断工具"""
def get_status(self, bond_name: str = "bond0") -> BondStatus:
"""获取 bond 状态"""
result = subprocess.run(
["cat", f"/proc/net/bonding/{bond_name}"],
capture_output=True, text=True, timeout=5,
)
return self._parse_bond_info(result.stdout, bond_name)
def diagnose(self, bond_name: str = "bond0") -> dict:
"""执行诊断,返回问题列表"""
status = self.get_status(bond_name)
issues = []
# 1. 检查 bond 接口状态
if status.mii_status != "up":
issues.append({
"severity": "critical",
"issue": f"{bond_name} 接口状态: {status.mii_status}",
"action": "检查物理链路和交换机端口",
})
# 2. 检查成员数量
if len(status.slaves) < 2:
issues.append({
"severity": "warning",
"issue": f"{bond_name} 仅有 {len(status.slaves)} 个成员,"
f"无冗余保护",
"action": "添加更多成员接口",
})
# 3. 检查各成员状态
for slave in status.slaves:
if slave.mii_status != "up":
issues.append({
"severity": "critical",
"issue": f"成员 {slave.interface} 链路 down",
"action": f"检查 {slave.interface} 物理连接",
})
continue
# 检查 LACP 协商状态
if status.bonding_mode and "802.3ad" in status.bonding_mode:
if not slave.lacp_synced:
issues.append({
"severity": "warning",
"issue": f"成员 {slave.interface} LACP 未同步",
"action": "检查交换机侧 LACP 配置",
})
if not slave.lacp_collecting:
issues.append({
"severity": "warning",
"issue": f"成员 {slave.interface} 未在接收流量"
f" (Collecting=No)",
"action": "检查对端 Distributing 状态",
})
if not slave.lacp_distributing:
issues.append({
"severity": "warning",
"issue": f"成员 {slave.interface} 未在发送流量"
f" (Distributing=No)",
"action": "检查对端 Collecting 状态",
})
if slave.link_failure_count > 0:
issues.append({
"severity": "info",
"issue": f"成员 {slave.interface} 有 "
f"{slave.link_failure_count} 次链路故障记录",
"action": "关注是否持续增长",
})
# 4. 检查速率一致性
speeds = set(s.speed for s in status.slaves if s.mii_status == "up")
if len(speeds) > 1:
issues.append({
"severity": "warning",
"issue": f"成员速率不一致: {speeds}",
"action": "确保所有成员速率和双工模式一致",
})
return {
"bond_name": bond_name,
"mode": status.bonding_mode,
"status": status.mii_status,
"slaves_count": len(status.slaves),
"active_slaves": sum(
1 for s in status.slaves if s.mii_status == "up"
),
"issues": issues,
}
def _parse_bond_info(self, output: str, bond_name: str) -> BondStatus:
"""解析 /proc/net/bonding/bondX"""
status = BondStatus(
bond_name=bond_name,
bonding_mode="",
xmit_hash_policy="",
mii_status="",
)
lines = output.strip().split("\n")
current_slave: BondSlave = None
for line in lines:
line = line.strip()
if "Bonding Mode:" in line:
status.bonding_mode = line.split(":", 1)[1].strip()
elif "Transmit Hash Policy:" in line:
status.xmit_hash_policy = line.split(":", 1)[1].strip()
elif "MII Status:" in line:
value = line.split(":", 1)[1].strip()
if current_slave is None:
status.mii_status = value
else:
current_slave.mii_status = value
elif "MII Polling Interval" in line:
status.miimon = int(
line.split(":", 1)[1].strip().replace(" ms", "")
)
elif "LACP rate:" in line:
status.lacp_rate = line.split(":", 1)[1].strip()
elif "Slave Interface:" in line:
if current_slave:
status.slaves.append(current_slave)
iface = line.split(":", 1)[1].strip()
current_slave = BondSlave(interface=iface, mii_status="",
speed="", duplex="")
elif "Speed:" in line and current_slave:
current_slave.speed = line.split(":", 1)[1].strip()
elif "Duplex:" in line and current_slave:
current_slave.duplex = line.split(":", 1)[1].strip()
elif "Link Failure Count:" in line and current_slave:
current_slave.link_failure_count = int(
line.split(":", 1)[1].strip()
)
elif "Aggregator ID:" in line and current_slave:
current_slave.aggregator_id = int(
line.split(":", 1)[1].strip()
)
elif "Actor Port State:" in line and current_slave:
current_slave.actor_port_state = int(
line.split(":", 1)[1].strip()
)
current_slave.lacp_active = bool(
current_slave.actor_port_state & 1
)
current_slave.lacp_synced = bool(
current_slave.actor_port_state & 8
)
current_slave.lacp_collecting = bool(
current_slave.actor_port_state & 16
)
current_slave.lacp_distributing = bool(
current_slave.actor_port_state & 32
)
if current_slave:
status.slaves.append(current_slave)
return status
# 使用示例
if __name__ == "__main__":
diag = BondDiagnostics()
result = diag.diagnose("bond0")
print(f"Bond: {result['bond_name']}")
print(f"Mode: {result['mode']}")
print(f"Status: {result['status']}")
print(f"Slaves: {result['active_slaves']}/{result['slaves_count']} active")
print(f"\nIssues ({len(result['issues'])}):")
for issue in result["issues"]:
print(f" [{issue['severity']}] {issue['issue']}")
print(f" → {issue['action']}")
七、高级配置
7.1 LACP 速率与超时
| 参数 | Long (慢速) | Short (快速) | 推荐 |
|---|---|---|---|
| LACPDU 间隔 | 30 秒 | 1 秒 | Short |
| 超时时间 | 90 秒 | 3 秒 | Short |
| 故障检测时间 | 最长 90 秒 | 最长 3 秒 | Short |
| CPU 开销 | 低 | 略高 | 可忽略 |
| 适用场景 | 稳定环境 | 生产环境 | 生产必选 Short |
# Linux 侧
BONDING_OPTS="mode=4 miimon=100 lacp_rate=1"
# lacp_rate=0: Slow (30s)
# lacp_rate=1: Fast (1s)
# 交换机侧 (Cisco)
lacp rate fast
7.2 LACP 抢占与优先级
当聚合组的活跃成员数受限(如 4 条链路中只允许 2 条活跃),优先级决定哪些链路被选入。
# Linux 侧
BONDING_OPTS="mode=4 miimon=100 lacp_rate=1 ad_select=1"
# ad_select=0: stable(默认,不抢占)
# ad_select=1: bandwidth(链路变化时重新选择)
# ad_select=2: count(链路变化时重新选择并重置计数器)
7.3 VLAN over Bond
# 在 bond 接口上创建 VLAN 子接口
# ifcfg-bond0.20
VLAN=yes
DEVICE=bond0.20
IPADDR=10.0.20.100
PREFIX=24
ONBOOT=yes
BOOTPROTO=none
PHYSDEV=bond0
# ifcfg-bond0.30
VLAN=yes
DEVICE=bond0.30
IPADDR=10.0.30.100
PREFIX=24
ONBOOT=yes
BOOTPROTO=none
PHYSDEV=bond0
7.4 fail_over_mac 策略
| 值 | 策略 | 说明 |
|---|---|---|
| 0 | none(默认) | bond 使用第一个成员的 MAC,切换时不变 |
| 1 | active | bond MAC 跟随当前活跃成员的 MAC(适合 active-backup) |
| 2 | follow | bond MAC 跟随,但成员使用各自 MAC 发送 |
在虚拟化/容器环境中,
fail_over_mac=1可以避免 ARP 表混乱。
八、Bonding vs Team vs NIC 独立
| 特性 | Bonding | Team | 多 NIC 独立 |
|---|---|---|---|
| 内核支持 | 内置(bonding.ko) | teamd 用户态守护 | 无需配置 |
| LACP 支持 | ✅ Mode 4 | ✅ | ❌ |
| 热备切换 | ✅ active-backup | ✅ runner | ❌ |
| 运行时配置 | 需重启接口 | D-Bus 动态配置 | N/A |
| 性能 | 内核态,高 | 用户态,略低 | 最高 |
| 推荐度 | ✅ 生产首选 | 逐步被弃用 | 计算/RDMA 网络 |
建议:生产环境统一使用 bonding(内核态性能最好),避免使用 teamd(已被 Red Hat 标记为弃用)。
九、最佳实践
| 场景 | 推荐 | 原因 |
|---|---|---|
| 管理网络 | Mode 1 (active-backup) | 无需交换机配置,简单可靠 |
| 存储网络 | Mode 4 (LACP) + layer3+4 | 多并发 IO 带宽叠加 |
| RDMA/RoCE 网络 | 不 Bonding | Bonding 破坏 RoCE PFC/ECN |
| 对外服务网络 | Mode 4 (LACP) + layer3+4 | 高并发流量均衡 |
| LACP 速率 | lacp_rate=1 (fast) | 3秒检测故障 vs 90秒 |
| MTU | 全链路一致 | 避免 Jumbo Frame 不匹配 |
| 监控 | Prometheus + 告警 | 成员减少、流量不均、链路抖动 |
关联知识
- GPU 裸金属服务器运维 — 裸金属服务器网络配置基础
- GPU 集群网络拓扑设计 — GPU 集群网络架构
- RDMA 与 InfiniBand 详解 — RDMA 网络不使用 Bonding 的原因
- NCCL 通信原理与调优 — NCCL 多路径通信与 Bonding 的关系
- 集群自动化部署方案 — 自动化部署中的网络配置
- 可观测性知识总览 — Bond 状态监控
- SRE 稳定性工程总览 — 链路冗余是高可用的基础
- 高可用架构设计总览 — 冗余设计
参考资源
- IEEE 802.3ad-2000 Standard
- Linux Bonding Documentation:
Documentation/networking/bonding.rst - Cisco NX-OS Layer 2 Configuration Guide
- 华为 VRP Eth-Trunk 配置指南
- Mellanox Spectrum Switch Configuration Guide
学习时间
约 3-4 小时(含实际配置一次 LACP Bonding)
状态
- 理解 LACP 协议原理和协商流程
- 掌握 Linux bonding 七种模式
- 能配置 Mode 4 (LACP) bonding
- 掌握交换机侧 LACP 配置(Cisco/华为/Mellanox)
- 理解 GPU 集群中各网络的 Bonding 策略
- 能监控和排查 LACP 故障
- 理解 RDMA 网络不 Bonding 的原因
- 实际配置一次完整的 LACP Bonding
- 搭建 Prometheus 监控 bond 状态