接入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 本地回环接口外,还有 eno1eno2 两个以太网接口。那么,就再查看当前网络接口:

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
    略

可以确认 eno1eno2 正常运行。

注意:接下来将修改网络配置,一旦生效,会使得你失去当前网络连接。如果你是远程操作,务必注意。但是,如果你通过 iLo 的远程控制台,那就没有这个担心了。

在 /etc/network/interfaces 中,修改配置如下,–可以移除 eno1eno2 的单独配置信息:

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-modebond-xmit-hash-policybond-members 。可以通过 man 5 interfaces-bond 查看每个配置项的说明。
其中, bond-members 比较好理解,就是你需要聚合的网口,比如这里的 eno1eno2bond-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 HOWTOmode 找到对这些候选值的完整解释。比如 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:

Leave a comment

Your comment