做网络这些年,我碰到最多的一个"看起来简单但总有人栽跟头"的需求,就是链路聚合。平时不显山不露水,等交换机上联口流量冲到90%、监控面板一片红色告警的时候,很多人第一反应是"换万兆板卡"或者"再拉一根光纤,把两个口手工绑一块儿"。可现实是,两根网线直接插在两台交换机之间,STP会立刻把其中一条Block掉,带宽一点都没多出来,还给自己埋了个"拓扑怎么变了"的坑。真正该做的,是让两条甚至多条物理链路在逻辑上捆成一个接口,转发时把它们当成一个口来用,故障时互相接管——这就是链路聚合(Link Aggregation)。华为交换机上叫Eth-Trunk,Cisco里叫EtherChannel,Linux服务器网卡绑定里叫Bonding,IEEE的标准编号是802.3ad/802.1AX。
这篇文章会从原理讲清楚它到底怎么工作,再重点讲华为交换机上的配置过程、调试命令和验收入门,最后把我在现网碰到的几个坑摊开来说。适合正好要配核心/汇聚上联、做服务器双网卡冗余,或者想把聚合链路彻底搞明白再动手的同行。
1. 先说清楚:链路聚合到底解决什么问题
1.1 带宽翻倍只是表面收益,真正值钱的是冗余和拓扑简化
链路聚合最直白的收益确实是带宽:两条千兆口聚合,理想情况下能承载接近2000M的并发流量,四条就是4000M,前提是流量能被哈希算法相对均匀地撒到每个成员口上。但这里要先把一个概念钉死:聚合不会让单条业务流超过单个物理口的速率。它压平的是"多条会话并发时,整体带宽被一根链路卡住"的瓶颈,而不是"单条TCP流能跑到两根线的速度"。
不过,做过生产网络的人都知道,真正让链路聚合不可替代的不是带宽,而是故障切换。一条成员链路断了——光模块失效、光纤被踩断、对端端口down——聚合口感知后会把原本要发往该口的流量重新哈希到剩余成员口上,这个切换过程对终端设备基本无感。你正在跑的数据库备份、视频会议、虚拟机迁移流量,不会因为一根线断掉就整条链路中断。
这种冗余还有一个容易被忽略的价值:它把"多条物理链路"抽象成了一个"逻辑拓扑"。STP、路由协议、MAC地址表在看Eth-Trunk这个逻辑口的时候,都把它当成一个接口来对待。原本两台交换机之间插两根线,STP要花时间收敛、要Block一条、还要担心根桥变化;做了聚合之后,两根线是一个逻辑口,逻辑上没有环,STP自然用不着Block任何一条。这才是聚合真正优雅的地方:你获得了多条链路的吞吐和冗余,代价只是多配一个接口,反而把原来复杂的拓扑收敛问题消掉了。
1.2 和"多链路负载均衡"划清界限
很多刚入行的朋友容易把链路聚合和"多链路负载均衡"当成一码事,其实技术边界很清楚。
如果两台交换机之间直接连了两根线、不做任何聚合,STP会Block一条,剩下一条转发,多余那条只是备用。有些方案会想用策略路由或者流量镜像去分摊两条物理链路,但那既不标准也不可靠,STP在拓扑变化时还会重新收敛,流量路径跳来跳去,排查问题的时候头都要大。
链路聚合的标准做法是:成员口只是"物理实体",真正的端口类型、VLAN、三层地址全部落在Eth-Trunk逻辑口上。转发的时候,交换机根据报文里的头部字段算出一个哈希值,再根据哈希值决定从哪个成员口出去,整个过程对协议栈和业务完全透明。
所以判断"我该不该用聚合",我有个很实用的标尺:如果两台设备之间需要多条物理链路同时工作,又不想引入环路、不想让STP天天参与计算,就上聚合。如果你只是想让某一条业务流"跑得更快",聚合解决不了,得靠多流并发,或者直接升级链路速率。认清这个边界,后面配置才不会用错方向。
2. 聚合口内部是怎么工作的:分发、保序与哈希
2.1 一个Eth-Trunk口背后的多成员口调度
先建立一个最小模型。假设在一台接入交换机上创建了Eth-Trunk 1,往里面塞了GE0/0/1到GE0/0/4四个口。对系统来说,这四根物理线被抽象成一个"逻辑管道"。帧从内部业务(比如VLANIF网关转发)送到Eth-Trunk 1时,交换芯片要做一个决定:把它交给GE0/0/1还是GE0/0/2,还是其他哪个口出去。
这个决定不是随机做的,而是根据报文头部特征算出一个哈希值,再拿哈希值去映射成员口。核心诉求有两个:
**同一会话必须永远走同一个成员口。**TCP要保证顺序,如果同一个连接的前后报文从不同物理口出去,在网络里就可能走了不同的转发路径,到达对端时乱序,结果就是TCP疯狂重传、吞吐率暴跌。哈希算法保证了"相同特征报文 → 相同哈希值 → 相同成员口",从根上避免同一会话被拆散。
**不同会话尽量均匀散布到不同成员口。**要让整体带宽被充分利用,就得让会话在成员口之间尽量"雨露均沾"。这就需要哈希因子选得对,让不同会话的哈希值尽可能分散在整个映射空间里。
华为交换机的实现里,Eth-Trunk有一个内部成员编号参与哈希计算,这个编号相当于给每个成员口在"哈希表"里固定了一个位置。同一个Eth-Trunk内部,成员口ID越靠前,占据的哈希索引区间越靠前;不同Eth-Trunk之间,还会加入Eth-Trunk自己的接口索引,避免多个Trunk的流量在全局哈希上重叠出新的不均匀。
2.2 哈希因子怎么选,负载才分得匀
哈希因子是可配置的。华为交换机上常见的负载分担模式有这几档:
- 按源MAC(src-mac)
- 按目的MAC(dst-mac)
- 按源+目的MAC(src-dst-mac)
- 按源IP(src-ip)
- 按目的IP(dst-ip)
- 按源+目的IP(src-dst-ip)
- 按源+目的IP+四层端口(src-dst-ip-port)
选哪一个,取决于网络里"会话"的粒度。如果终端产生的流量主要是"一堆PC访问一台服务器",源MAC和源IP都很分散,用src-mac或src-ip效果都还行;如果是服务器之间的东西向流量,客户端相对固定,而目的端是多台服务器,那要选dst-mac或dst-ip,让目的地址分散到哈希空间里;如果设备部署在NAT边界或者充当网关,进出方向的源/目的地址经常被转换,那就得上四层端口参与,src-dst-ip-port是最细粒度的选择,代价是交换芯片计算量大一点,对绝大多数交换机来说性能不是问题。
我个人的经验是:接入/汇聚场景直接用src-dst-mac就行,因为二层转发时报文的三层头还没到芯片重点关注的阶段;核心/网关设备建议换成src-dst-ip或src-dst-ip-port,粒度细,不容易出现"一个大流量目的IP独占一个成员口"的尴尬。华为很多框式交换机还支持本地优先转发之类的特性,跨板卡场景下能减少跨板带宽占用,配置前查一下型号支持情况。
注意:负载不均衡不一定是"配错了"。单条TCP流(比如用iPerf打流测试)打满一个口、其他口空着,这在哈希逻辑上是正常的。要验证聚合带宽,得同时发起多条并发流,才能看到多个成员口都被摊到。
2.3 顺序一致性:为什么同一个会话不能劈腿
前面提到"同流同径",这句话的真正含义比表面更深。哈希能保证"同一会话尽量走同一成员口",可如果会话数量少,或者会话特征在哈希空间里恰好重叠——比如大量流量的源IP和目的IP完全相同——确实会有多个会话被分到同一个成员口。这不是错误,是哈希的统计学本质:只要需求是"保序优先",就不可能做到逐包轮询那样绝对均匀。
顺带说一个底层细节:顺序一致性不仅影响TCP。QoS队列、链路层重传、甚至某些应用层的状态检测防火墙,都默认"同一条流的报文按序到达"。如果交换芯片为了追求完美负载均衡而做逐包分发,接收端因为乱序丢包重传,反而会把真正有效的吞吐拉低。这也是为什么所有正经交换机厂商在聚合实现上都选"基于流的哈希",而不是"基于包的轮询"。
还有一种特殊情况值得留意:聚合口下如果接了无线AC或者其他会做"会话绑定"的设备,哈希因子选不好,可能导致某些AP的CAPWAP隧道流量全部挤在同一条物理链路上。这种场景要用会话数最分散的哈希模式,并且先做流量模型预估,别指望四根链路一定分摊到每条50%。不同厂商的哈希算法细节有差异,不存在一个"放之四海而皆准"的最佳因子,现场调的时候记得多打几路并发流实测。
3. 静态聚合与LACP动态聚合,到底怎么选
3.1 手动聚合模式:简单直接,但"两端一致"得自己盯着
华为交换机上,Eth-Trunk默认的聚合模式一般是手动负载分担(mode manual load-balance)。这种模式下,本端设备只要把几个物理口加入Eth-Trunk,就认为它们是一个逻辑口,不需要和对端协商,也不发任何聚合协议报文。
手动模式的好处是简单、兼容性好,对端设备只要也能配置"手工聚合",两边约好就行。很多老旧设备、网络打印机、部分存储设备的以太网口,支持的就是这种手工绑组。坏处也明显:
- 对端端口状态完全靠人工保证。如果对端有一根线没插、端口被shutdown、或者对端根本没配置聚合,本端感知不到,依然会把报文往那个成员口分发,丢包丢得莫名其妙。
- 如果对端端口是通的,但对端交换机没有把对应成员口加进聚合口,就可能出现MAC漂移、广播环路之类的诡异现象。
所以手动模式只建议在"对端设备不支持LACP"或者"网络规模很小、链路拓扑长期不变"的场景用。比如某些摄像头NVR的绑定口、老款防火墙的双WAN口,它们就只认手工聚合。其余场景,能用LACP就用LACP,省心得多。
| 对比项 | 手动负载分担模式 | LACP模式 |
|---|---|---|
| 协商机制 | 无协议协商,两端手工保证一致 | 通过LACPDU自动协商 |
| 故障感知 | 本端只能感知本端物理口状态 | 双方都可通过LACPDU感知对端状态 |
| 成员口失效处理 | 靠本端物理口状态,对端无感知 | 协商失败端口自动转为Unselected |
| 适用场景 | 对端不支持LACP、设备老旧、链路长期固定 | 核心/汇聚、服务器双网卡、需要快速切换的生产网络 |
| 华为配置命令 | mode manual load-balance | mode lacp-static |
3.2 LACP的握手机制和关键参数
LACP就是IEEE 802.3ad/802.1AX定义的链路聚合控制协议。启用LACP后,设备会周期性地在成员口上发送LACPDU报文,报文里携带自己的系统优先级(System Priority)、系统MAC、端口优先级(Port Priority)、端口号、操作Key等信息。对端收到LACPDU后,根据这些信息判断哪些端口能凑成一条聚合链路,这个过程叫协商。
协商通过的口进入Selected状态,可以转发数据;不满足条件的口处于Unselected状态,只监听LACPDU不发数据。华为设备上还常看到一个Standby(备用)状态,对应max active-linknumber配置产生的"超额成员口"。协商状态的机理由LACP状态机控制,底层还有Detached、Waiting、Collecting、Distributing等状态切换,日常排障不需要记那么细,但看到Selected/Unselected/Standby一定要能分清。
LACP的关键参数有三个,配置时必须理解:
系统优先级:全局参数,默认32768,数值越小优先级越高。两端都启LACP时,系统优先级更高的一端掌握"选谁当活动链路"的话语权。常用于双设备对接时,让主设备优先确定活动口,避免两端各执一词。
端口优先级:成员口上的参数,默认也是32768,数值越小越优先。当活动链路数超过上限时,优先级低的口会被踢到Standby备用状态。
LACP超时时间:分Fast(1秒发送间隔,重传3次)和Slow(30秒发送间隔)。快速超时能让故障感知大约在3秒内完成,对业务影响很小;慢速超时控制报文开销少,但故障切换要等几十秒,这在生产环境通常不可接受。所以核心/汇聚之间建议用Fast,服务器双网卡绑定也最好配合Fast。
3.3 主备场景下的活动链路上限设计
LACP模式还支持max active-linknumber。我可以把八个口都加入Eth-Trunk 1,但只让其中四个作为活动口转发,剩下四个作为备用链路待命。当某个活动口故障时,系统会按端口优先级挑一个备用口顶上。
这个特性非常实用。华为交换机堆叠(iStack/CSS)之后,跨设备之间做Eth-Trunk,上行到两层核心,用max active-linknumber把主框的两个口设为高优先级做活动链路,主框出问题的时候备用口自动顶上,业务切换会很平滑。LACP还有一个lacp preempt enable,开启后,恢复的高优先级口会重新抢占活动状态;不开启的话,即使原来那个口恢复了,也要等当前活动口故障才切换过去。这更适合追求"稳定优先、不折腾"的网络设备。
4. 华为交换机上从建Trunk到业务放行的配置过程
4.1 配置前的端口清理与VLAN梳理
很多用户配置失败,不是因为命令不会打,而是没做配置前的"资源梳理"。动手前我建议先做四件检查:
- 物理端口是否被占用:执行
display current-configuration interface GigabitEthernet0/0/1,确认端口上没有独立的VLAN配置、没有绑定其他业务。 - 端口状态是否正常:执行
display interface brief,确认端口都是Up,速率、双工一致。 - VLAN规划是否清晰:聚合口要放行哪些VLAN,两侧交换机要完全一致。
- 对端设备是否具备聚合能力:对端是另一台交换机,要确认它对Eth-Trunk模式的兼容性;对端是服务器,要确认网卡Teaming支持LACP还是静态绑定。
把这些信息列成一张表再动手,比配到一半回去查配置快得多。最忌讳的就是端口上还跑着业务,你这边直接把它塞进Eth-Trunk,那边流量就断了。
4.2 创建Eth-Trunk、选定模式、加入成员口的完整命令
以两台华为S系列交换机互连为例,目标是让GE0/0/1到GE0/0/4四条口聚合,作为Trunk口放行VLAN 10、20、30。下面是LACP模式(推荐)的完整配置流程:
system-view sysname SW-A # 全局设置系统优先级,数值越低优先级越高(可选,默认32768) lacp system-priority 100 interface Eth-Trunk 1 mode lacp-static max active-linknumber 4 load-balance src-dst-ip port link-type trunk port trunk allow-pass vlan 10 20 30 q接下来把成员口加进聚合口,有两种方式:
# 方式一:直接在Eth-Trunk视图下批量加入 interface Eth-Trunk 1 trunkport GigabitEthernet0/0/1 to 0/0/4 q # 方式二:逐个在物理口视图下指定归属 interface GigabitEthernet0/0/1 eth-trunk 1 q interface GigabitEthernet0/0/2 eth-trunk 1 q方式一更省事,但如果你希望对不同成员口设置不同的LACP端口优先级,就必须用方式二逐个进物理口设置。比如:
interface GigabitEthernet0/0/1 eth-trunk 1 lacp port-priority 100 q interface GigabitEthernet0/0/2 eth-trunk 1 lacp port-priority 200 q对端SW-B也要做几乎一样的配置,模式、放行VLAN、成员口数量保持一致。两台都配完后,在SW-A上执行display eth-trunk 1,能看到成员口处于Selected状态,Eth-Trunk变成Up,这条聚合链路就算建起来了。
如果是手动聚合模式,把命令mode lacp-static换成mode manual load-balance就行,其余配置一样。注意手动模式没有LACPDU协商,对端也必须是手动模式;一端手动、一端LACP,聚合口是起不来的。
4.3 三层聚合口与服务器对接的补充姿势
上面是典型二层Trunk场景。如果两台设备之间要做三层互联或者做网关冗余,可以直接给Eth-Trunk配IP:
interface Eth-Trunk 1 mode lacp-static ip address 10.0.10.1 255.255.255.252 q三层聚合在华为VRRP/堆叠双活网关场景下非常常见:两台核心各出一条Eth-Trunk接到下层,下层再做同样的聚合,形成无环又双活的南北向链路。这里有个细节:只要进了Eth-Trunk,物理口上的独立配置就会失效,端口类型、VLAN列表、IP地址都必须配置在Eth-Trunk逻辑口上,别跟在物理口后面补一堆命令,白忙活。
如果对端是Linux服务器,网卡绑定模式得跟交换机对齐。服务器上bond mode 4(802.3ad)对应交换机的LACP模式;mode 0(balance-rr)是逐包轮询,跟交换机的Eth-Trunk哈希语义不同,不建议直接对接。Windows服务器的NIC Teaming里,Static Teaming对应手动聚合,Dynamic Teaming对应LACP。只要模式不对称,服务器侧可能显示链路Up但数据不通,这个坑在虚拟化环境特别常见。
4.4 跨框/堆叠场景下的Eth-Trunk配置提示
聚合还有一个很多人都忽略的价值:它天然适合堆叠系统。华为的iStack/CSS把多台设备虚拟化成一台后,Eth-Trunk的成员口可以分散在不同物理框上。假设SW-A和SW-B做了堆叠,Eth-Trunk 1的成员口一部分在A框、一部分在B框,对端再做同样的跨设备聚合,就组成了"跨设备链路聚合"。
这种场景配置上没啥特别之处——堆叠系统里,所有框的接口统一编址为XGE1/0/1、XGE2/0/1这样的全局接口,直接trunkport XGE1/0/1 to XGE2/0/4就行。但它带来一个关键价值:单框故障时,另一框上的成员口仍然能转发,聚合链路不会整条中断。很多双核心方案里,跨设备聚合的意义就在这——从"链路冗余"升级到了"设备冗余"。如果两台设备不做堆叠又想实现类似效果,就得用M-LAG这种多框链路聚合技术,原理上还是LACP,但实现细节更复杂,配置前要找对应型号的版本手册确认支持情况。
5. 配置完成后的验证与真实踩坑经历
5.1 display命令怎么读出有效信息
配置完不等于配置对,验证环节不能省。最常用的命令就是display eth-trunk 1,输出里最重要的几栏是Port、Status、Priority。Status是Selected说明该成员口正常参与转发;Status是Unselected表示协商没成功;如果你配了max active-linknumber,多出来的成员口状态会是Standby,这是正常现象,不是故障。
<SW-A> display eth-trunk 1 Eth-Trunk1's state information: WorkingMode: LACP Hash arithmetic: According to SIP-XOR-DIP LACP MUX Enable: Yes System Priority: 100 System ID: 0018-8201-0001 Least Active-linknumber: 1 Max Active-linknumber: 4 Operate Status: up Number Of Active Ports: 4 ... Port Status Priority Key GE0/0/1 Selected 100 1 GE0/0/2 Selected 100 1 GE0/0/3 Selected 200 1 GE0/0/4 Selected 200 1再看负载分担是否生效,可以执行display load-balance eth-trunk 1(部分版本命令是display eth-trunk 1 load-balance),确认当前哈希算法是你设的那个,别配完发现芯片默认跑的还是src-mac。
然后做数据面验证。终端ping通对端网关只代表基本连通,要验证多链路分摊,建议用iPerf或者多台终端并发跑大流量,再到交换机上看display interface Eth-Trunk 1的总流量速率和各成员口的速率。理想情况是几个成员口都有流量,而不是全部压在一个口上。
5.2 掉线切换实测:拔掉一根成员口会发生什么
聚合最核心的卖点是冗余,所以上线前我认为必须做一次"破坏性测试":跑着业务流量时,随机拔掉一根成员口的光纤或光模块,观察业务是否中断、切换耗时多少。
LACP快速超时模式下,故障感知一般在3秒左右,加上哈希重分布的时间,业务基本无感,顶多TCP出现少量重传。如果你做测试时拔线后业务断了好几十秒,先别急着怀疑聚合没生效——先看LACP超时时间是不是默认的Slow,再看对端服务器网卡绑定有没有开启快速故障检测。
测试完记得把线插回去,观察插回状态。插回后如果是手动模式,链路恢复立即生效;LACP模式下,如果没开lacp preempt enable,恢复的成员口要等状态机重新协商,过程中业务不会断,只是这个口暂时不参与转发,看到成员口还是Standby也不用慌,等协商周期走完再看一眼。
5.3 我在现网踩过的坑和排查清单
坑一:模式不一致,Eth-Trunk起不来。有一次现场物理链路全通,但聚合口显示Down。两端比对半天,发现一边交换机版本默认Eth-Trunk模式是manual,另一边被人改成了lacp-static,协商自然失败。把模式改成一致后秒起。从此我养成了习惯:凡是聚合相关,第一件事先两端各执行一次display eth-trunk 1看WorkingMode。
坑二:只把成员口配成Trunk,忘了在Eth-Trunk上放VLAN。新同事第一次配,先挨个把四个物理口配了port link-type trunk、port trunk allow-pass vlan all,再建Eth-Trunk加成员口。结果流量不通。原因很简单:物理口一旦加入Eth-Trunk,物理口上的独立配置全部失效,端口类型、VLAN列表必须配置在Eth-Trunk口上。这也是判断"你把Eth-Trunk用对了没有"的试金石。
坑三:以为带宽翻倍就是任意单流翻倍。客户投诉"你们聚合后网速没变",我用iPerf单线程测试,发现确实只有一条链路在跑。跟客户解释清楚后,改成并发16线程打流,四个成员口全动起来了,带宽接近4倍。最关键的就是这个认知:聚合提升的是"多会话并发总带宽",不是"单会话速率",单条TCP流的带宽上限依然是单物理口速率。
坑四:堆叠场景下LACP优先级没规划好。跨设备聚合时,默认端口优先级全是32768,设备挂掉后备用口顶上没有任何问题;但如果你希望"主框的口永远优先转发",就必须给主框成员口设更小的端口优先级,并开启lacp preempt。否则正常情况下流量会随意分布在哪框的口上,跨框转发带宽占用高不说,故障恢复后的路径也不可控。
坑五:服务器网卡Teaming模式跟交换机对不上。虚拟化集群扩容时,新服务器网卡绑定用了Dynamic Teaming,交换机这端却是手动聚合,两边都显示Up,但流量一上来就丢包。把交换机改为LACP模式后恢复。服务器侧LACP跟交换机侧LACP才是"门当户对",静态绑定只能对应手动聚合。
最后整理一个排查清单,现场遇到问题照着查,比瞎猜快:
| 现象 | 可能原因 | 排查思路 |
|---|---|---|
| Eth-Trunk整体Down | 两端模式不一致 | 两端各自display eth-trunk看WorkingMode |
| 成员口状态Unselected | 速率/双工不一致、LACP协商失败 | 查接口物理状态,两端速率双工必须一致 |
| 链路Up但业务不通 | VLAN放行列表不一致 | 比对两端port trunk allow-pass |
| 流量集中在单个成员口 | 哈希因子粒度不够 | 调整load-balance模式,多路并发测试 |
| 拔线后业务中断几十秒 | LACP慢超时或对端未开快速检测 | 检查lacp timeout配置,服务器侧开启快速故障检测 |
| 插回线后链路不恢复转发 | 未开启lacp preempt | 按需开启抢占,或手动shutdown/undo shutdown |
链路聚合是一门"配通容易、用好难"的技术。大多数人在现场卡住的点,往往不是命令记不住,而是没弄清"我到底想让这条聚合链路完成什么"——是要带宽的"多进多出",还是要冗余的"故障切换",或者两者都要。把这个想清楚,模式怎么选、哈希因子怎么调、活动链路上限定多少、要不要开抢占,答案自然就出来了。我自己每次动核心链路的聚合配置之前,一定会把接口拓扑图画一遍,标清哪根线接哪台设备的哪个口,再对着图清空原有端口配置、重新建Trunk。这个习惯帮我避掉过好几次"拔错了线"的险情。如果你也正在调聚合,建议先做一次破坏性测试,别等到业务高峰期才第一次验证故障切换。