Linux 中的链路聚合(端口绑定)

CompTIABeginner
立即练习

介绍

在本实验中,你将学习如何在 Linux 环境中实现链路聚合(Link Aggregation),也称为端口绑定(port bonding)。这项强大的技术允许你将多个物理网络接口合并为一个逻辑接口,从而提高网络吞吐量并提供容错能力。你将通过实践掌握配置和管理绑定连接所需的核心 Linux 网络命令。

遵循分步流程,你将首先使用 ip a 命令识别系统中可用的网络接口。为了进行安全且实用的演示,我们将创建两个虚拟“dummy”接口,dummy1dummy2,以模拟多接口环境。然后,你将创建一个新的虚拟 bond 接口 bond0,并将这两个 dummy 接口“奴役”(enslave)到它上面。随后,你将为新创建的 bond0 接口分配一个静态 IP 地址以启用通信。最后,你将验证整个配置并检查活动 bond 的状态,以确保其正常运行。

使用 ip a 命令识别可用的网络接口

在此步骤中,你将开始识别 LabEx VM 上可用的网络接口。在将多个网络接口合并为一个绑定的链路之前,你首先需要知道它们的名称。在 Linux 上,执行此任务的现代且推荐的命令是 ip aip addr show 的简写)。

此命令会显示系统上的所有网络接口,以及它们的 IP 地址、MAC 地址和操作状态。

首先,打开你的终端。它应该已经打开并且位于 ~/project 目录中。现在,运行 ip a 命令来列出所有网络接口:

ip a

你将看到一个列出多个接口的输出。你应该关注几个关键细节:

  • lo: 这是回环接口(loopback interface),是系统与自身通信的虚拟接口。在绑定时我们将忽略它。
  • eth0: 这是主以太网接口。为了确保我们与实验环境的连接保持稳定,我们将不使用它。
  • docker0: 这是 Docker 创建的一个虚拟网桥。它当前处于 DOWN 状态,不适合本次实验。
  • dummy1, dummy2: 这是我们为本次实验添加的两个 dummy 虚拟接口,用于模拟额外的两块网卡。这些将是我们一起绑定的接口。
  • state UP: 这表示接口处于活动状态。

你的输出将与此类似。请注意你的 dummy 接口 dummy1dummy2 的名称,因为在接下来的步骤中你需要用到它们。

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
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:16:3e:00:20:a3 brd ff:ff:ff:ff:ff:ff
    altname enp0s5
    altname ens5
    inet 172.16.50.188/24 metric 100 brd 172.16.50.255 scope global dynamic eth0
       valid_lft 1892159680sec preferred_lft 1892159680sec
    inet6 fe80::216:3eff:fe00:20a3/64 scope link
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:2c:eb:c9:91 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
4: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether 2a:47:04:07:1a:ea brd ff:ff:ff:ff:ff:ff
    inet6 fe80::5caf:4ff:fe97:69bd/64 scope link
       valid_lft forever preferred_lft forever
5: dummy2: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether 2e:5f:12:08:3a:eb brd ff:ff:ff:ff:ff:ff
    inet6 fe80::5caf:4ff:fe97:69be/64 scope link
       valid_lft forever preferred_lft forever

从上面的输出中,我们已经确定了两个适合我们绑定配置的接口:dummy1dummy2。在接下来的步骤中,你将使用这些接口名称来创建一个新的绑定接口。

创建并启用 Bond 接口 'bond0'

在此步骤中,你将创建逻辑“bond”接口,它将作为你的网卡的 master。这需要两个主要操作:加载必要的 Linux 内核模块(module)以支持绑定,然后创建并激活接口本身。

首先,你需要确保 bonding 内核模块已加载。此模块包含使内核能够管理绑定接口的代码。你可以使用 modprobe 命令加载它。

sudo modprobe bonding

为了确认模块已成功加载,你可以使用 lsmod 命令(它会列出所有已加载的内核模块)并结合 grep 来过滤出“bonding”。

lsmod | grep bonding

你应该会看到输出表明 bonding 模块正在使用中:

bonding               196608  0

现在内核已准备就绪,你可以创建新的逻辑接口了。我们将它命名为 bond0。使用 ip link 命令添加一个类型为 bond 的新虚拟链路。

sudo ip link add bond0 type bond

此命令会创建接口,但默认情况下它处于“down”状态。你需要将其“up”(启用),使其处于活动状态,这与启用物理网卡类似。

sudo ip link set dev bond0 up

现在你可以再次使用 ip a 命令来验证你的新 bond0 接口是否存在且处于活动状态,但这次要指定接口名称。

ip a show bond0

输出将显示 bond0 接口,其状态为 DOWN,并且尚未分配 IP 地址。这将在后续步骤中进行配置。

6: bond0: <NO-CARRIER,BROADCAST,MULTICAST,MASTER,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff

你现在已成功创建并启用了 master bond0 接口。下一步是将你的 dummy 接口作为 slave 添加到它上面。

将接口添加为 'bond0' 的从属接口

在此步骤中,你将把之前识别的虚拟接口(dummy1dummy2)“奴役”(enslave)到 bond0 master 接口。将接口“奴役”意味着你将其置于绑定接口的控制之下。一旦被奴役,物理接口就不再需要自己的 IP 地址;所有流量都将通过 bond0 进行管理。

这种使用 dummy 接口的方法是完全安全的,它允许你学习绑定过程而不会有丢失网络连接的风险。

首先,将 dummy1 接口添加到 bond 中。在将其添加为 slave 之前,你需要将其禁用(take it down)。

sudo ip link set dev dummy1 down
sudo ip link set dev dummy1 master bond0

接下来,对 dummy2 接口执行相同的操作。

sudo ip link set dev dummy2 down
sudo ip link set dev dummy2 master bond0

现在我们来启用 bond 接口并为其分配一个 IP 地址。我们将使用一个不同的子网,以避免与现有的 eth0 配置发生冲突:

sudo ip addr add 192.168.100.10/24 dev bond0
sudo ip link set dev bond0 up

让我们验证一下 dummy1dummy2 是否已成功奴役到 bond0

ip a

在输出中查看 dummy1dummy2bond0 的条目。你将看到 dummy1dummy2 都列出,并在其描述中包含 master bond0,这证实它们已成功奴役。另外,请注意 bond0 接口现在是 UP 状态,并且拥有我们分配的 IP 地址。

4: dummy1: <BROADCAST,NOARP,SLAVE,UP,LOWER_UP> mtu 1500 qdisc noqueue master bond0 state UP group default qlen 1000
    link/ether 2a:47:04:07:1a:ea brd ff:ff:ff:ff:ff:ff
5: dummy2: <BROADCAST,NOARP,SLAVE,UP,LOWER_UP> mtu 1500 qdisc noqueue master bond0 state UP group default qlen 1000
    link/ether 2e:5f:12:08:3a:eb brd ff:ff:ff:ff:ff:ff
6: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 2a:47:04:07:1a:ea brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.10/24 scope global bond0
       valid_lft forever preferred_lft forever
    inet6 fe80::2847:4ff:fe07:1aea/64 scope link
       valid_lft forever preferred_lft forever

在接口现在作为 slave 工作之后,下一步是配置 bond0 接口本身的网络设置。

测试 Bond 接口连通性

在此步骤中,你将测试 bond 接口以确保其正常工作。由于我们已经创建了一个功能性的 bond,包含两个 dummy 接口并为其分配了 IP 地址,现在我们可以测试其基本功能了。

首先,让我们验证 bond 接口是否已启用并具有正确的 IP 地址:

ip a show bond0

你应该会看到 bond0 接口及其分配的 IP 地址(192.168.100.10/24),并且接口状态应显示为 UP

6: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 2a:47:04:07:1a:ea brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.10/24 scope global bond0
       valid_lft forever preferred_lft forever

现在让我们通过 ping 自身的 IP 地址来测试 bond 接口,以验证接口是否响应:

ping -c 3 192.168.100.10

你应该会看到成功的 ping 响应,这证实了 bond 接口正在工作。

我们还可以验证我们的 slave 接口是否已正确附加到 bond:

ip a | grep "master bond0"

此命令将显示被奴役到 bond0 的接口。你应该会看到 dummy1dummy2 都被列出:

4: dummy1: <BROADCAST,NOARP,SLAVE,UP,LOWER_UP> mtu 1500 qdisc noqueue master bond0 state UP group default qlen 1000
5: dummy2: <BROADCAST,NOARP,SLAVE,UP,LOWER_UP> mtu 1500 qdisc noqueue master bond0 state UP group default qlen 1000

为了进行额外的验证,让我们检查一下 bond 接口是否出现在路由表中:

ip route | grep bond0

你应该会看到通过 bond0 接口的 192.168.100.0/24 网络路由条目。

教学提示: 此设置完美地演示了 bonding 的核心概念。在具有多个物理接口的生产环境中,你将根据所选择的 bonding 模式看到实际的网络流量负载均衡和冗余。

使用 cat /proc/net/bonding/bond0 验证 Bond 状态

在最后这个步骤中,你将通过直接检查 bond 的状态文件来进行最详细的验证。Linux 内核通过 /proc 文件系统中的一个特殊文件暴露每个绑定接口的实时信息。对于一个名为 bond0 的接口,该文件位于 /proc/net/bonding/bond0

使用 cat 命令查看此文件可以全面了解 bond 的配置,包括其模式、slave 接口的状态以及流量计数器。

在你的终端中,运行以下命令:

cat /proc/net/bonding/bond0

这将显示一个详细的报告。输出将与以下内容类似,现在显示了两个 slave 接口:

Ethernet Channel Bonding Driver: vX.X.X (Month Day, Year)

Bonding Mode: load balancing (round-robin)
Primary Slave: None
Currently Active Slave: dummy1
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 0
Down Delay (ms): 0
Peer Notification Delay (ms): 0

Slave Interface: dummy1
MII Status: up
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 2a:47:04:07:1a:ea
Slave queue ID: 0

Slave Interface: dummy2
MII Status: up
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 2e:5f:12:08:3a:eb
Slave queue ID: 0

让我们分解一下此输出中的关键信息:

  • Bonding Mode: 这显示了用于分发流量的策略。由于我们没有指定,它默认为 load balancing (round-robin),该策略按顺序在可用的 slave 之间传输数据包。
  • MII Status: 这显示了绑定链路的整体状态。up 表示它处于活动状态。
  • Slave Interface: 你可以看到 dummy1dummy2 的部分。它们都显示 MII Statusup,确认它们是活动的并且是 bond 的一部分。请注意,对于 dummy 接口,SpeedDuplex 可能显示为 Unknown 或默认值。

恭喜!你已成功在 Linux 上配置了绑定的网络接口,将两个 dummy 接口合并为一个逻辑接口。

总结

在此次实验中,你学习了在 Linux 环境中实现链路聚合(端口绑定)的基本概念。该过程首先使用 ip a 命令识别可用的网络接口,包括两个预先配置的虚拟接口 dummy1dummy2。识别后,你创建了一个名为 bond0 的新虚拟 bond 接口,启用它,然后将两个 dummy 接口添加为 slave,以演示完整的绑定过程。

这种方法提供了一种完全安全有效的方式,可以在远程环境中学习 bonding 概念,而不会冒连接丢失的风险。

关键学习点包括:

  • 创建两个 dummy 接口以模拟多接口环境。
  • 加载 bonding 内核模块。
  • 理解网络绑定中的主从关系。
  • 将多个接口绑定到一个 bond master。
  • 安全地为 bond 接口分配 IP 地址。
  • 验证最终的 bond 配置和状态。

实验最后通过 cat /proc/net/bonding/bond0 检查了 bond 的详细状态,该命令提供了关于 bond 配置、模式及其所有 slave 接口状态的全面信息。在实际场景中,此验证步骤对于确认绑定设置是否按预期工作至关重要。