接入LACP(802.3ad),开启链路聚合
Preface
使用 HPE ProLiant MicroServer Generation 8(以下简称Gen8)很久了,其自带了 HPE Ethernet 1Gb 2-port 332i Adapter 作为 Network Controller,具备两个支持 1000Base-TX 的 RJ45 网口。一直以来,我都只使用其中一个网口来接入局域网。但自从又添置了一台 Gen8 以后,两台 Gen8 之间的网络通信还是维持在千兆速度,就使得移动大文件耗时比较久。插两根网线,不同操作使用不同 IP 也不是不行,但是还是繁琐,于是就想着是不是可以只用一个 IP,但又充分利用两个网口,将网速提升到 1000Mbps x 2 呢?
起初,我是不知道计算机网络中管这种效果叫做什么。直到去筛选交换机时,看到有“端口聚合”这种利器。随后,才知道 Bonding / NIC (Network Interface Card) Teaming / Link Aggregation 这些名词概念,以及802.3ad(LACP)等协议。事实上,早在上个世纪九十年代后期,已经有交换机厂商开始着手解决这个问题,并 2000 年由 IEEE 提出了802.3ad 标准来规范化地解决,其更是通过 LACP(Link Aggregation Control Protocol)在 Static Link Aggregation(静态链路聚合,等同于端口聚合)之外提供了动态链路聚合。果然是太阳底下没有新鲜事,在我犯难之前,工程师们早就考虑到了,并且解决掉了。
如果本文有幸被读者翻到,并且想要动手,那么建议在操作之前,先阅读 Debian 文档 Bonding 。
Enable Module bonding and Install Package ifenslave
在 Gen8 上安装的操作系统是 Debian 12,要使得它支持链路聚合,需要先生效内核模块 bonding
。在 Linux interfaces-bond 包的 Mannual 中是这么介绍 bonding
的:
The Linux implementation for Link Aggregation Groups (LAGs) is called bonding, whereas a LAG interface is called bond.
通过以下命令,确认系统当前是否加载了 bonding
模块:
lsmod | grep bonding
如果有类似下面的输出,则可以认定为已加载。
bonding 221184 0 tls 135168 1 bonding
否则就是没有加载,则执行以下命令来加载它:
modprobe bonding
同时,可以参考下面的步骤来设置开机自动加载,不必手工加载。首先确认当前已经有哪些开机自动加载的模块:
cat /etc/modules
对于从未修改过的配置文件,大致如下:
# /etc/modules: kernel modules to load at boottime. # # This file contains the names of kernel modules that should be loaded # at boot time, one per line. Lines beginning with "#" are ignored.
通过下面的命令添加:
echo "bonding" | tee -a /etc/modules
然后再次查看moduels文件,确认结果。最后,参考 Debian 的 Bonding 文档,需要安装 bonding
包:
apt install ifenslave
Configure Computer Network Interface
在准备好了 bonding
模块后,开始配置网络接口。首先查看配置文件 /etc/network/interfaces
,大致如下:
auto lo iface lo inet loopback allow-hotplug eno1 iface eno1 inet dhcp allow-hotplug eno2 iface eno2 inet dhcp
可以看到除了 lo
本地回环接口外,还有 eno1
和 eno2
两个以太网接口。那么,就再查看当前网络接口:
ip addr show
在我的Gen8上大致如下,–移除无关信息:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 略 2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 94:18:82:37:2c:48 brd ff:ff:ff:ff:ff:ff altname enp3s0f0 inet 192.168.1.175/24 brd 192.168.1.255 scope global eno1 valid_lft forever preferred_lft forever 略 3: eno2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 94:18:82:37:2c:49 brd ff:ff:ff:ff:ff:ff altname enp3s0f1 inet 192.168.1.176/24 brd 192.168.1.255 scope global eno2 valid_lft forever preferred_lft forever 略
可以确认 eno1
和 eno2
正常运行。
注意:接下来将修改网络配置,一旦生效,会使得你失去当前网络连接。如果你是远程操作,务必注意。但是,如果你通过 iLo 的远程控制台,那就没有这个担心了。
在 /etc/network/interfaces 中,修改配置如下,–可以移除 eno1
和 eno2
的单独配置信息:
auto bond0 iface bond0 inet dhcp bond-mode 4 bond-miimon 100 bond-updelay 200 bond-downdelay 200 bond-lacp-rate fast bond-xmit-hash-policy layer3+4 bond-members eno1 eno2
这其中注意三个配置项: bond-mode
、bond-xmit-hash-policy
、 bond-members
。可以通过 man 5 interfaces-bond
查看每个配置项的说明。
其中, bond-members
比较好理解,就是你需要聚合的网口,比如这里的 eno1
和 eno2
。 bond-mode
则是链路聚合的模式,可以有六个取值,如下:
- balance-rr (0),
- active-backup (1),
- balance-xor (2),
- broadcast (3),
- 802.3ad (4),
- balance-tlb (5),
- balance-alb (6).
默认值是 balance-rr
,你可以从 Linux Ethernet Bonding Driver HOWTO 的 mode
找到对这些候选值的完整解释。比如 balance-rr (0) ,它是通常所说的“静态链路聚合”或“端口聚合”,也是最简单的模式,并且不需要交换机特别支持。
bond-xmit-hash-policy
相对就复杂一些,–但也不是非要配置,默认值是 0
。它是选择哪一个算法来决定走哪个物理网口,候选值有:
- layer2 (0),
- layer3+4 (1)
- layer2+3 (2)
- encap2+3 (3)
- encap3+4 (4)
上面 2
代表 OSI 网络通信模型的第二层,即数据链路层(Data Link Layer),在这里指代 MAC 地址。 3
是指第三层,即网络层(Network Layer),指代 IP 地址。 4
指第四层,即传输层(Transport Layer),指代端口。Layer2 (0)
意思是只考虑 MAC 地址来决定走哪个物理网口,layer3+4 (1) 则是考虑 IP 地址和端口,layer2+3 (2) 则是考虑 MAC 地址和 IP 地址。因为我需要在两个 Gen8 之间操作文件,所以我选择 layer3+4
。
Mannual Configure
上面是修改配置文件,实现开机后自动生效。但是,如果你只想简单看看效果,那么完全可以调用 CLI 命令来设置 LACP。
首先,创建接口:
ip link add bond0 type bond
然后,设置聚合模式, 4
为 LACP (802.3ad),即动态链路聚合模式。–默认是 0
,即 Round-robin (balance-rr) :
echo 4 > /sys/class/net/bond0/bonding/mode
接着,添加从属接口:
ip link set eno1 master bond0
ip link set eno2 master bond0
最后,使其工作:
ip link set bond0 up #启用接口
dhclient bond0 #分配IP
ip addr show #确认输出
Configure Switch
由于上文在 Debian 上配置的是 LACP,所以在交换机上也需要做相应的设置,但不同设备的设置方法不同,建议咨询客服。但务必选择(轻)管理型交换机,并且要支持 LACP。 最便宜的交换机,大概在100-150元,是不支持管理的,也就无法设置 LACP。稍贵些的,大概在200-250元,支持管理,但是只能做静态链路聚合。支持 LACP 的那种,价格区间大概在300-350元。我使用的是一个新兴的品牌兮克,型号是SKS3200-8E1X。功能倒是稳定,就是它的 Web 管理系统很不完善。
设置完成后,可以查看:
ip addr show bond0
部分信息如下:
10: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 94:18:82:37:2c:48 brd ff:ff:ff:ff:ff:ff inet 192.168.1.175/24 brd 192.168.1.255 scope global bond0 valid_lft forever preferred_lft forever 略
Summary
整个过程中,你需要使用 ip 系列 CLI 命令,需要了解链路聚合的大概概念,以及 Linux 的 Bonding
模块,如果还有疑问,可以参考 Debian 的官方文档 interfaces-bond(5)。最后,跑一下测试,在其中一台 Gen8 上运行两个不同端口的 iperf3 服务端,再通过 另外一台 Gen8 和路由器向其发送请求。然后,再使用 iperf3 向另外一台 Gen8 和路由器发起请求。
执行 ifstat -b
,测试结果如下,接近网卡的理论性能上线,下行带宽接近2Gbps,上行也接近1.8Gbps:
