
做服务器高可用改造时H3C交换机的S-MLAG配合Linux bond4是我目前比较推荐的一套组合。这个方案可以让服务器用两张物理网卡分别上联两台独立的交换机任何一台交换机宕机、任何一根网线故障服务器IP不漂移、业务连接不断。听起来很美好但我在实际配置和验证过程中踩了不少坑尤其是交换机侧跨设备链路聚合的配置细节、服务器bond4与交换机LACP协商的匹配关系以及拔线测试时的各种意外。这篇文章就把从设计思路、拓扑规划、命令配置到故障切换实测的过程完整记录下来给准备做服务器双上联高可用的同行一个可以直接参考的案例。如果你是网络运维、系统工程师或者正在纠结服务器到底该用bond4还是主备bond的人这篇应该能帮你省下不少排查时间。1. S-MLAG与IRF的选择题为什么服务器双上联最终选了S-MLAG1.1 服务器高可用最初看起来很简单服务器侧做高可用最基础的需求是一块网卡挂了业务不能断。于是大部分人会先做网卡bond也就是把服务器上的两到四块物理网卡绑定成一个逻辑网卡IP只配在bond口上。但问题很快就来了如果这两块网卡都插在同一台交换机上那这台交换机一旦宕机或者升级重启服务器再高的网卡冗余也白搭。要解决交换机层面的单点就必须把服务器的两根网线分别插到两台不同的交换机上。麻烦在于传统的链路聚合静态聚合或者LACP动态聚合定义在单台交换机上聚合口的所有成员口必须属于同一台设备。想让服务器的bond跨两台交换机最初我只能想到堆叠把两台交换机用IRF堆叠成一台逻辑设备跨设备的端口就可以放到同一个聚合口里了。1.2 IRF堆叠在高可用交付中的三个暗坑IRF堆叠确实能解决跨设备链路聚合的问题但在真实交付场景里它并不永远是最优解。我在多个项目里遇到过同样的情况总结下来主要是三个坑。第一个是控制面耦合。IRF堆叠后两台设备共享控制平面版本必须严格一致配置同步也是整机级同步。一旦出现版本Bug往往两台同时中招反而把高可用变成了高故障率。而且在运维审计角度堆叠后所有配置都从主设备下发从设备完全透明出了问题复盘非常难受。第二个是升级窗口长。IRF堆叠升级时为了避免脑裂通常需要整机升级或者主备逐台升级操作过程中要求很苛刻——主备切换、版本回退、配置兼容性检查任何一个环节出错都可能引发业务中断。生产环境的维护窗口往往只有三四个小时这个压力很大。第三个是组网限制。IRF要求参与堆叠的设备型号、硬件版本、软件版本尽量一致。如果现场本来就有两台不同型号的H3C交换机或者一批旧设备一台新设备想堆叠就得更换硬件成本一下就上去了。1.3 S-MLAGDRNI如何实现跨设备聚合且控制面独立S-MLAG在H3C Comware V7平台上对应功能叫DRNI分布式中继解决的就是上面这几个问题。它的核心思路是两台交换机依然保持各自独立的控制平面不需要统一版本也不需要型号完全一致但通过一条专门的peer-link链路把两台设备连接起来让服务器侧看起来像是对接了一台逻辑交换机。具体工作机制大致是这样的两台设备各自配置一个相同的DRNI系统MAC和系统优先级让下游服务器认为它们是一个LACP系统中的两个端口同时通过keepalive链路互相检测对方的存活状态peer-link用于同步必要的MAC表项、ARP表项以及转发跨设备流量。这样做的好处很明显控制平面隔离一台设备升级或者宕机另一台不受影响可以逐台升级、逐台重启设备型号不完全一致也能接受。对服务器bond来说它感知不到对端是两台独立设备只认为自己的两块网卡聚合到了一个逻辑交换机上。所以我在这个项目里最终选择了S-MLAG而不是IRF。当然S-MLAG也不是万能的它适合的场景比较偏向服务器双上联、跨设备二层聚合这类需求。如果你需要的是高性能转发、统一管理、单台设备配置同步那IRF可能更合适。后面我还会提到一些S-MLAG的局限性。2. bond4与LACP服务器侧高可用真正依赖的握手2.1 七种bond模式速览Linux下bond模式一共有7种数字从0到6。很多系统工程师在配置bond时习惯直接抄模板但我强烈建议至少知道自己选的是哪种模式因为服务器bond模式必须和交换机侧配置匹配否则就是看起来通了一拔线就断。下面这个表是我在方案选型时经常用的对照表模式名称基本原理是否需要交换机配合适用场景mode0balance-rr轮询按包分发不需要但可能乱序基本不用mode1active-backup主备模式只有一块网卡工作不需要简单高可用mode2balance-xor按源/目的MAC做异或选路不需要但交换机需能看到同一个MAC很少用mode3broadcast所有包从所有网卡发出不推荐基本不用mode4802.3ad动态链路聚合LACP协商必须配合交换机动态聚合主流高可用方案mode5balance-tlb发送负载均衡接收由网卡自主决定不需要老环境mode6balance-albTLB接收负载均衡不需要老环境高可用场景我首选mode4也就是802.3ad动态链路聚合。原因很简单它通过LACP协议和交换机实时协商链路状态交换机知道自己有几个成员口在线、链路质量如何拔线和恢复都能快速感知。mode1虽然简单但主备切换时备份网卡完全不工作浪费了一台交换机的冗余能力而且没有LACP的主动通知很多时候是靠网卡link down才触发切换收敛速度慢。2.2 bond4为何要求交换机侧也必须是动态聚合bond4工作的基础是LACP协议。服务器上的bond口会周期性地向对端发送LACPDU帧帧里携带了本端的系统MAC、系统优先级、端口号、端口优先级、操作Key等信息。交换机收到LACPDU后会根据这些参数判断哪些端口可以聚合成一个聚合口然后回复自己的LACPDU。双方都认为端口被选中Selected聚合才算建立成功。这里最关键的一点是bond4要求交换机侧配置的是动态聚合LACP模式而不是静态聚合。静态聚合下交换机会强制把所有成员口加入聚合口根本不理会LACP协商结果。服务器这边发出去的LACPDU交换机可能只做透传甚至直接忽略结果是服务器侧看到对端Partner信息是空的聚合口一直处于down状态或者一面倒认为链路不可用。我见过很多新人把交换机的Bridge-Aggregation配置成静态聚合默认就去对接服务器的bond4结果bond0显示MII Status: down半天下不去。排查了半天才发现是聚合模式不匹配。2.3 哈希策略决定负载均衡效果bond4本身只负责链路协商和故障切换真正的负载均衡靠哈希算法完成。Linux bond的xmit_hash_policy有三个常见选项layer2、layer23、layer34。layer2按源MAC和目的MAC做异或选路对于服务器到核心交换机的流量来说MAC基本固定很容易所有流量都哈希到同一条链路。layer23加上源IP和目的IP做计算比layer2好一些但还是容易受地址影响。layer34在IP基础上再加上源端口和目的端口对于TCP/UDP多连接的业务来说均衡效果最好也是我最常用的配置。需要特别说明的是无论哪种哈希策略单条TCP流始终只能走一条物理链路。也就是说如果业务本身只有一个大连接在传输bond4并不能把它拆成两份分别走两台交换机。这个限制是LACP聚合的天然特性不是配置问题做方案时一定要和业务方讲清楚。3. 拓扑设计与H3C交换机侧配置实录3.1 推荐拓扑与接口规划我这次改造的典型拓扑是两台接入交换机Leaf-1和Leaf-2下挂若干台Linux服务器。每台服务器用两块万兆网卡分别上联两台交换机服务器上做bond4交换机侧做S-MLAG跨设备聚合。关键链路的规划如下链路用途说明服务器eno1 - Leaf-1业务成员链路加入业务聚合口服务器eno2 - Leaf-2业务成员链路加入业务聚合口Leaf-1 - Leaf-2 peer-linkDRNI控制/数据通道建议至少两根物理线聚合成一个peer-linkLeaf-1 - Leaf-2 keepalive心跳检测独立三层链路建议单独规划互联地址注意peer-link和keepalive是两条完全不同的链路。peer-link承载的是两台设备之间的MAC表项同步、跨设备流量转发带宽要求高keepalive只传心跳报文带宽要求低但必须物理独立。如果keepalive和peer-link走了同一条物理线路一旦这条线路故障两台设备同时失去对端状态S-MLAG会立刻进入分裂状态直接翻车。3.2 S-MLAGDRNI核心配置过程下面以H3C Comware V7平台为例给出DRNI的配置思路。不同型号、不同版本命令细节可能会有差异我实际配置时也遇到过有的版本把DRNI写成M-LAG的情况落地前一定以设备对应版本手册为准。Leaf-1上的核心配置大致如下system-view sysname Leaf-1 # 配置DRNI系统参数两台设备必须一致 drni system-mac 0000-fc00-0001 drni system-priority 100 # 本机在DRNI系统中的编号两台设备分别配1和2 drni system-number 1 # 创建peer-link聚合口 interface Bridge-Aggregation 1 description DRNI-PEER-LINK port link-type trunk port trunk permit vlan all port drni peer-link quit # 将peer-link物理成员加入 interface Ten-GigabitEthernet1/0/1 port link-type trunk port trunk permit vlan all port link-aggregation group 1 quit # 创建业务聚合口interlace编号两台设备要一致 interface Bridge-Aggregation 10 description DRNI-SERVER-BOND port link-type access port access vlan 100 port drni interlace 10 quit # 将服务器上联口加入业务聚合口 interface Ten-GigabitEthernet1/0/2 port link-type access port access vlan 100 port link-aggregation group 10 quit # keepalive心跳配置示例使用Vlan-interface interface Vlan-interface 300 ip address 10.10.10.1 30 quit drni keepalive destination 10.10.10.2 source 10.10.10.1Leaf-2上的配置基本一样差异只有两处drni system-number 2以及keepalive的源目地址互换。这里要强调一个容易忽略的点业务聚合口的port drni interlace 10这条命令目的是让两台设备上编号相同的业务聚合口建立对应关系。如果Leaf-1上配了interlace 10Leaf-2上却配成interlace 20那LACP协商会成功但实际转发流量会出问题因为服务器认为自己在和一个聚合系统通信但两台交换机各自维护各自的DRNI实例对应关系错位。3.3 两台交换机上必须保持一致的参数清单S-MLAG配置完成后我最担心的不是命令敲错而是两台设备上的隐含参数不一致。下面这些是我在实际排障中一条条核对过的DRNI system-mac和system-priority必须完全一致否则对端服务器通过LACP看到的系统身份不一致聚合口无法选中。业务聚合口在两台设备上的VLAN配置必须一致。如果Leaf-1上成员口是access vlan 100Leaf-2上配成access vlan 200LACP协商依然可能成功但服务器发出来的流量进了两个不同的VLAN同VLAN内二层不通排查起来非常隐蔽。成员口建议关闭STP边缘检测或者配置为边缘端口否则交换机刚启动时STP收敛需要几十秒服务器那边bond已经认为链路down过一轮了。上联到核心的接口、路由配置、ACL策略只要会影响服务器所在VLAN转发也尽量保持一致避免出现故障切换后能通但策略放行不一致导致部分流量被丢弃的诡异问题。我在现场做配置复查时习惯写一个对照清单两台设备逐条diff不要相信自己记忆力。4. 服务器侧bond4配置与验证手段4.1 动手前先确认网卡与驱动服务器侧配置bond4之前我建议先看一眼网卡驱动和固件版本。因为LACP协商依赖网卡对多播帧和LACPDU的处理能力某些老旧网卡驱动在收到LACPDU时不把它上送到协议栈而是直接丢弃导致bond口一直无法和交换机握手。用下面几条命令做基础检查lspci | grep -i ethernet ethtool -i eno1 ethtool eno1 | grep -i link detected如果确认网卡和驱动没问题再开始配置bond。否则你可能会陷入交换机配置没问题、服务器配置没问题、但就是聚合不起来的循环里最后才发现是驱动Bug。4.2 ifcfg方式配置bond0CentOS/RHEL系以我最常用的CentOS 7/8环境为例使用ifcfg文件配置bond0。先加载bonding模块并设置默认参数编辑/etc/modprobe.d/bonding.confalias bond0 bonding options bonding miimon100 mode4 lacp_rate1 xmit_hash_policylayer34然后创建/etc/sysconfig/network-scripts/ifcfg-bond0DEVICEbond0 NAMEbond0 TYPEBond BONDING_MASTERyes BOOTPROTOnone ONBOOTyes IPADDR10.1.1.10 PREFIX24 BONDING_OPTSmode4 miimon100 lacp_rate1 xmit_hash_policylayer34接着修改两张物理网卡的配置文件。以eno1为例DEVICEeno1 NAMEeno1 TYPEEthernet BOOTPROTOnone ONBOOTyes MASTERbond0 SLAVEyeseno2配置同理。最后重启网络服务systemctl restart network这里需要提醒一点如果服务器上跑的是NetworkManager建议直接在NetworkManager里用nmcli创建bond或者在这些ifcfg文件里加上NM_CONTROLLEDno。否则NetworkManager可能会在重启后把ifcfg配置接管过去导致bond起不来。另外如果对切换延迟容忍度低可以把lacp_rate1再显式写一遍让LACP走快速模式1秒发一次LACPDU交换机侧也把LACP超时时间配成fast。两边必须匹配否则效果打折。4.3 状态验证读懂几个关键输出配置完成后先别急着上业务。我习惯用这几条命令做体检cat /proc/net/bonding/bond0 ip -d link show bond0 ethtool eno1 | grep -i link detected tcpdump -i eno1 -e -n -vv ether[0:2] 0x8809看/proc/net/bonding/bond0的输出时重点看几个字段Bonding Mode: IEEE 802.3ad Dynamic link aggregation确认确实工作在mode4。LACP rate: fast确认快速LACP模式生效。Aggregator ID和Partner Mac Address如果能看到具体的聚合器ID和交换机侧MAC说明LACP协商已经完成。Slave Interface列表里两块网卡的MII Status都是up且Link Failure Count没有持续增长。tcpdump抓LACP帧可以确认LACPDU确实在链路上跑。如果抓不到任何ethertype为0x8809的帧那就是bond4没有真正使能LACP或者网卡驱动把LACPDU丢了。5. 故障切换实测如何科学地拔线和升级5.1 故障注入矩阵配置完成只是一个开始真正让我放心的是故障切换实测。我习惯按下面的矩阵逐项测试每一项都要记录切换时间和服务影响。故障注入方式预期现象业务影响拔掉服务器到Leaf-1的网线bond0从两块网卡变成一块工作IP不变ping只有短暂丢包通常1秒以内在Leaf-1上shutdown业务口同拔线但交换机侧LACP会主动通知服务器感知更快通常更短直接poweroff Leaf-1peer-link失效、keepalive检测到对端故障Leaf-2继续提供服务可能有一次秒级震荡逐台重启Leaf-1升级场景服务器bond保持在线Leaf-1重启完毕后自动重新聚合业务不中断这里要说一下科学拔线的含义很多人在测试时直接用手拽网线这其实是最不标准的方式。因为物理拔线过程中铜缆可能会有接触不良的抖动导致链路反复up/down服务器bond会误判为多次故障触发不必要的切换和回切。我建议优先用交换机侧shutdown接口、服务器侧ip link set eno1 down这种方式做可控故障注入最后再模拟物理拔线。5.2 收敛时间如何估算与调优故障切换时间主要由三部分组成链路状态检测时间、LACP协商时间、服务器协议栈收敛时间。链路状态检测Linux bond里配置的miimon100表示每100毫秒检查一次链路状态拔线后MII检测到link down的时间大概在100到200毫秒。LACP协商如果配了lacp_rate1交换机侧也配了fast超时LACP检测到成员口消失的时间在1秒左右。协议栈收敛服务器上IP、路由表、ARP表项基本不变化所以这部分时间很短。综合下来物理拔线场景下业务ping丢包普遍在几个包以内。如果配置了slow LACP默认30秒超时拔线后可能要10秒以上才能完成切换这个差异在生产环境里是致命的。所以我对mode4的建议很明确lacp_rate必须用fast交换机侧LACP超时也必须配fast。5.3 一次真实升级复盘印象最深的一次是Leaf-1做版本升级。因为DRNI场景下两台设备控制平面独立我可以在维护窗口内先升级Leaf-1再升级Leaf-2理论上业务无感知。实际操作时Leaf-1重启期间服务器bond0的所有活跃流量都走到了Leaf-2上ping测试只丢了1个包。leaf-1启动完成后bond0自动把eno1加回聚合器流量重新分散到两条链路。全程不需要重启服务器不需要动IP配置。但那次也暴露了一个问题Leaf-1刚起来时业务聚合口的STP还在收敛服务器侧eno1的MII状态是up但交换机侧端口还没开始转发导致部分流量超时。后来我在成员口上配置了STP边缘端口再测试就稳定了。这个细节强烈建议提前处理否则升级窗口内的秒级中断会让你很被动。6. 避坑指南从握手失败到控制台被锁的完整排障链路6.1 现象bond0一直显示down或聚合口没有active成员这种是最常见的问题。服务器侧bond0显示类似下面这种状态Bonding Mode: IEEE 802.3ad Dynamic link aggregation MII Status: down排查顺序我建议是先看物理、再看交换机、最后看协议用ethtool eno1确认服务器网卡的link是up的。在交换机上display link-aggregation verbose看成员口是否在聚合组里、Aggregation状态是否为Selected。如果交换机侧没有任何聚合组检查成员口是否加入了正确的Bridge-Aggregation以及聚合适配模式是不是动态。我遇到过一次比较隐蔽的情况交换机上同一个物理口既被加进了peer-link聚合组又手工配置了access vlan 100导致端口配置冲突服务器侧怎么都协商不上。后来把物理口从peer-link聚合组里移除重新加到业务聚合组才解决。6.2 交换机侧成员口一直未选中的根因如果交换机聚合口能看到成员口但状态不是Selected通常有以下几种原因成员口的链路类型在交换机侧是trunk但VLAN放行列表和DRNI对端不一致导致LACP报文的VLAN封装对不上。两台设备上的业务聚合口interlace编号不一致DRNI认为这是两个不同的逻辑接口。STP把成员口阻塞了尤其是刚配置完、生成树还没收敛时。这时可以display stp interface Ten-GigabitEthernet1/0/2看端口状态确实被阻塞就检查STP配置。解决思路是不要只看聚合口状态要把二层链路、VLAN、STP逐层查一遍。聚合协商成功只代表物理上能聚合不代表转发路径通畅。6.3 控制台密码忘记与设备恢复现场这个坑虽然和S-MLAG没有直接关系但凡是接手旧的H3C设备几乎都会遇到。现场有台S7506交接时控制台密码已经丢了根本进不了系统只能做恢复。我的处理流程是确认设备上已有配置是否需要保留。如果能通过网管或历史配置文件获取到运行配置先想办法备份一份如果完全无法登录只能从重启阶段恢复。通过console口连接设备重启设备在启动阶段根据提示按CtrlB进入BootROM菜单不同型号按键和菜单提示不同。在BootROM菜单里选择跳过配置文件加载或者清除console登录密码的选项进入系统后重新设置密码。如果只是忘了密码但配置还要用选择跳过console认证而不是恢复出厂配置否则配置全丢重建成本非常高。操作完成后保存新配置并立即导出一份配置备份。需要说明的是这种恢复手段一定要用于自己有权管理的设备并且在操作前确认设备已经不在业务路径上或者业务影响可控。设备在跑业务时千万不要随意重启。6.4 S-MLAG双主/单活的本质与防范S-MLAG最怕的是两台设备同时认为自己是主设备进入双活分裂状态。正常情况下keepalive链路和peer-link链路都在两台设备能感知对端存在。但一旦keepalive链路故障同时peer-link因某种原因震荡两台设备可能都认为对端挂了各自独立运作转发行为就会冲突。防范措施有几点keepalive必须走独立物理链路不要和业务口共用peer-link建议至少双物理口聚合降低单点风险有条件的情况下在汇聚层做相应的策略兜底避免双主时形成环路。我在一次排障中还遇到过双主后peer-link不自动恢复的情况原因是对端设备重启后DRNI状态没有完全清掉。解决办法是两台设备都执行reset drni相关复位操作让DRNI重新建立。这个操作有业务中断风险一定要在维护窗口做。6.5 单流哈希不均与带宽上限问题很多业务方对bond4有误解以为两块万兆网卡bond后吞吐就是20G。实际上单条TCP流只能走一块网卡最多10G。只有并发连接数足够多、哈希分布足够均匀时总吞吐才能接近20G。如果你测出来bond0的总流量一直卡在10G上不去先别怀疑链路有问题用ethtool -S查看每块物理网卡的收发计数看流量是不是集中在一块网卡上。如果确认是哈希不均可以尝试调整xmit_hash_policy或者在应用层增加并发连接。不要指望bond4能把单流拆开这是协议限制。6.6 容易踩的配置一致性坑汇总最后把我在多个项目里积累的一致性清单放这里每次S-MLAG交付前逐项过一遍两台设备的DRNI system-mac、system-priority、system-number配置正确。两台设备的业务聚合口interlace编号一致。服务器成员口在两台设备上的VLAN配置完全一致。peer-link放通了所有需要的VLAN且peer-link本身聚合正常。keepalive链路物理独立能互相ping通。两台设备的STP模式、成员口边缘端口配置一致。服务器侧lacp_rate和交换机侧LACP超时时间匹配。升级维护前确认两台设备的启动文件、版本兼容性避免逐台升级时出现一台起不来的情况。这套组合用到现在最深的体会是S-MLAG本身不复杂复杂的是跨设备一致性。交换机侧两台设备只要在VLAN、聚合编号、STP、LACP参数上有一处不一致故障切换时就会产生各种隐蔽的丢包和震荡。而服务器侧的bond4相对稳定一旦配置正确后续几乎不用管。如果你也准备在生产环境上这套方案强烈建议先搭一套测试环境把故障注入矩阵完整跑一遍再安排业务割接。我在每个新项目里都会这样做这比任何配置检查都更能发现问题。