多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Spine-Leaf网络4+12架构BGP/EVPN收敛性能实测:故障注入到亚秒级恢复

Spine-Leaf网络4+12架构BGP/EVPN收敛性能实测:故障注入到亚秒级恢复 4台Spine、12台Leaf全部运行BGP/EVPN协议栈我从故障注入到流量恢复完整跑了一轮收敛性能测试。这篇文章里没有理论空谈只有被我验证过的配置、测试方法和踩坑记录。如果你正在规划机房Spine-Leaf架构改造或者准备上线前做一次故障演练这篇内容应该能帮你少走不少弯路。先解释一下标题里的“终极考验”是什么意思。412在这个规模下其实不是最极端的大型网络但真正难的是让这16台设备在几十万条路由、多Peer并发失效、路由振荡同时发生的情况下还能在可控时间内完成收敛。我在实验室搭了一套接近这个规模的BGP/EVPN环境并且故意把所有默认参数摆在台上跑了一遍结果并不好看。这篇就是把整个测试过程、优化思路、实测数据和后来排查出的问题全部拆开讲清楚。1. 为什么是“412”这场终极考验到底在考什么1.1 412架构与常规两层/三层网络的本质区别传统网络常用的核心-汇聚-接入三层结构有一个绕不开的痛点东西向流量要经过核心层转发故障时依赖STP或者VRRP这类机制切换收敛时间在超大规模场景下非常不可控。Spine-Leaf架构把网络彻底扁平化任意Leaf之间最多经过一台Spine所以4台Spine天然构成4条等价路径。只要BGP/EVPN的选路逻辑足够稳流量就能在故障后快速重新哈希到可用链路上。BGP/EVPN在这个架构里的位置也很明确Leaf作为VXLAN Tunnel Endpoint终结业务VRF并通告MAC/IP路由Spine只做路由反射和转发不感知VXLAN。这样做的设计意图是让Spine保持无状态Leaf承担所有业务逻辑整个控制面才具备横向扩展能力。但问题也随之而来——Leaf与4台Spine建立BGP会话Spine又要同时反射来自12个Leaf的路由当一个Leaf的上行链路故障时4台Spine会同时收到Withdraw消息再把路由撤销反射给其他11个Leaf。这个“一对多传播”的过程才是412架构下收敛压力的真正来源。1.2 BGP/EVPN收敛的完整时序拆解别一上来就看“收敛时间”这个总数字先把收敛过程拆成四段后面所有优化都是围绕这四段展开的。故障检测时间从物理链路中断到控制面感知到故障。本地端口down时物理层告警很快但如果故障发生在中间链路本地端口状态完全正常这时候只能靠BGP Hold Timer或BFD来兜底。控制面传播时间BGP进程生成Update/Withdraw消息通过eBGP或iBGP会话扩散到所有相关Peer。这里最大的坑是BGP的MRAI定时器它会把路由更新强行压制一段时间。协议处理时间接收端BGP进程收到Update后的RIB处理、选路计算、下一跳递归解析。路由条目越多这条链路越慢。数据面刷新时间协议栈把新路由下发到转发芯片更新FIB表、ECMP哈希组成员还要处理MAC表老化。这一步往往比BGP进程慢也是最容易被忽略的瓶颈。四个阶段的时间差异非常大。默认配置下如果没有BFDBGP Hold Timer通常要到90秒甚至180秒级别才触发故障判定也就是最坏情况下要等几十秒才开始感知故障。如果开启了BFD这个时间可以压到300毫秒以内。数据面刷新的速度则取决于硬件平台有的设备FIB下发很快有的则需要几百毫秒。这就是为什么同样一个412环境有人测试出来收敛时间不到1秒有人却看到几十秒业务中断差异往往不在设备品牌而在定时器和功能开关的配置上。2. 把考场规则定明白拓扑、AS规划与“收敛完成”标准2.1 拓扑设计与AS/RT规划这次测试的环境是逻辑拓扑4台Spine、12台Leaf全部连通在一个Spine-Leaf CLOS网络里。Leaf上分别创建业务VRF并通过EVPN Type-2和Type-5路由对外通告MAC/IP以及前缀路由。为了让路由规模真正接近“超大规模”压测每台Leaf上模拟了20个业务VRF整网BGP-EVPN路由条目规模跑到35万条左右。AS号规划我非常建议提前想清楚。这次测试采用的是Leaf独立AS方案角色数量AS号说明Spine465000统一AS仅作为路由反射器不跑VXLANLeaf1265501-65512每台Leaf独立AS便于故障隔离与流量策略控制所有Leaf与所有Spine之间建立eBGP会话Spine之间不建立BGP连接。Leaf独立AS的好处是Spine反射路由给其他Leaf时不会出现AS Path环路问题不需要在Leaf上额外开allowas-in。如果Leaf数量特别大比如几百台也可以让Leaf共用同一个AS号再用allowas-in放行但那样AS Path的环路处理和路由振荡时的路径计算会更复杂。412这个规模下Leaf独立AS是最直接、最可控的方案。RTRoute Target规划直接决定哪些Leaf能收到哪些路由。测试中每个业务VRF分配独立的RT比如VRF-A的RT是65000:1001只在需要互通的一组Leaf之间双向import/export。收敛测试时如果RT规划混乱路由会被过度传播实验数据很难解释清楚。2.2 收敛判定标准控制面、数据面、端到端三合一做收敛测试最怕自欺欺人必须提前定义“收敛完成”的判定标准。我这次同时验证三个层面只有三者全部满足才认为收敛结束控制面收敛所有Leaf的BGP会话恢复Established状态show bgp l2vpn evpn summary里的待处理Prefix数量归零BGP RIB中需要撤销或更新的路由条目全部处理完。数据面收敛从源Leaf到目的Leaf持续打流记录从“首包丢失”到“最后一包丢失”的时间窗口窗口结束后流量恢复。端到端业务恢复在Leaf内Ping远端VTEP地址以及VRF内的网关、虚机IP确认往返时延降到故障前P99基线以内并且连续测试1分钟无新增丢包。只盯着BGP状态绝对不行。我见过很多情况下BGP已经收敛完成但数据面流量还在丢因为MAC表项老化、ECMP哈希组成员重算等动作要额外花时间。把这三个指标分开记录才能准确定位收敛瓶颈。2.3 先算一笔账默认配置下的收敛时间预算默认配置下收敛时间大概是多少我直接给一个粗略公式总收敛时间 ≈ 故障检测时间 控制面传播时间 协议处理时间 数据面刷新时间假设没有BFD只靠BGP默认Hold Timer。通常BGP Hold Time是90秒、Keepalive 30秒最坏情况下要等Hold Timer超时才能判定对等体失效也就是接近90秒。即便链路物理中断让设备本地端口优先感知downBGP对等体的状态切换也要走完状态机通常也要几秒级别。控制面传播方面BGP的MRAI默认值在eBGP/EVPN场景下一般是30秒这意味着即便故障已经检测到BGP也可能把撤消路由的消息压住最多30秒。把这些加起来默认配置下一次单链路故障的收敛时间跑到30秒到90秒一点都不奇怪。开启BFD之后故障检测可以降到300毫秒以内把BGP的advertisement-interval调成0控制面传播的压制效应消失数据面刷新在优化过的平台上通常在几十到几百毫秒。这样总收敛时间就有机会压到1秒以内。后面的实测结果也验证了这个预算模型。3. 实测部署BFD、MRAI与路由策略的调优全过程3.1 先解决EBGP路径环路的两个常见方案在Spine-Leaf架构里如果Leaf共享同一个ASSpine反射路由回去时Leaf会因为“AS Path里看到自己”而丢弃路由。我这次选择的Leaf独立AS方案天然绕开了这个问题。但如果你面对的是Leaf数量非常多、无法逐台分配独立AS的大规模池化场景也可以用另一种思路Leaf共用AS配合allowas-in放行来自本AS的路由。两条路线各有取舍。Leaf独立AS的缺点是AS号消耗较大运维侧的AS规划要更细致Leaf共用AS加allowas-in的优点是AS号占用小设备配置更统一但故障路由振荡时AS Path里反复出现的相同AS号会增加路径选择判断的复杂度。从收敛性能角度看412规模下Leaf独立AS带来的路径处理开销和路由传播不确定性更小所以我建议至少在这个规模的测试中采用独立AS。3.2 快速感知与快速传播的配置思路核心的收敛优化集中在三个点BFD快速故障感知、BGP定时器调优、控制面保护。以下配置以主流通用命令风格为例不同设备差异主要集中在关键字大小写和策略名上思路是通用的。BFD是最关键的一步。我将BFD间隔设置到100ms最小接收间隔100ms乘数因子取3。这样故障最坏可以在300ms左右被感知如果设备支持物理层告警联动还可以更快。# 全局启用BFD bfd interval 100 min_rx 100 multiplier 3 # BGP邻居关联BFD并降低BGP本身的状态保持时间 router bgp 65000 neighbor LEAF peer-group neighbor LEAF remote-as 655xx neighbor LEAF fall-over bfd neighbor LEAF timers 1 3 neighbor LEAF advertisement-interval 0这里有几个容易踩的细节。timers 1 3的含义是Keepalive 1秒、Hold Time 3秒这已经是比较激进的配置有些设备对这个值有下限要求配置前先用show命令确认支持范围。advertisement-interval 0的作用是取消BGP更新消息的MRAI压制让Withdraw和Update消息能立刻发出。还有一个容易被忽略的点务必确认BGP邻居启用了send-community extended否则EVPN的RT属性传不出去路由反射后Leaf无法正确导入到VRF。控制面保护同样重要。开启CoPP策略优先保证BGP、BFD报文的CPU处理带宽。配置示例control-plane service-policy input COPP-PROTECTCOPP策略里重点放行TCP端口179的BGP报文和BFD报文其他低优先级流量适当限速。路由振荡压测时如果没有CoPPBGP进程CPU会被突发的路由更新打满BFD报文延迟又会反过来触发新的故障判断形成恶性循环。3.3 测试工具与流量注入方法我使用了三种互补的观测手段。第一是持续Ping用ping 10.10.1.2 -i 0.1 -s 1400保持每100毫秒一个探测报文统计从首丢到恢复的时间窗口。第二是用iperf3打UDP流观察实际业务流量的中断窗口命令类似iperf3 -c 10.10.1.2 -u -b 1G -t 3600 -i 1。第三是在Leaf上抓BGP Update报文记录Withdraw和Update消息的发出时间戳tcpdump -nn -s 0 -i any tcp port 179 -w /tmp/bgp.cap抓包的目的是精确测量控制面收敛时间不能只看业务丢包窗口。把抓包结果和流量中断窗口放在同一条时间线上对比就能看出控制面已经收敛但数据面仍在丢包的时间差距这个差值非常重要。3.4 实测结果对比记录就直接看这张表我在同一套环境中做了两轮测试第一轮是默认配置第二轮是开启BFD、调低MRAI并启用CoPP后的优化配置。测试规模是整网35万条BGP-EVPN路由、12台Leaf、20个VRF。测试场景默认配置收敛时间优化后收敛时间核心瓶颈单Leaf上联主链路shutdown4.2秒 / 丢包约200个320ms / 丢包2个默认MRAI压制 无BFD单Leaf到Spine链路瞬断拔线模拟6秒以上 / 丢包超过300个512ms / 丢包3个BGP Hold Timer感知过慢两台Spine同时失效15秒以上 / 流量近乎中断1.1秒 / 丢包8个多Peer并发失效协议处理CPU打满1000条路由振荡/秒CPU 85%收敛恶化到1.8秒CPU 45%收敛约700ms控制面无防护Update风暴冲击CPU这些数据说明一个很现实的问题设备本身的转发能力其实很强真正拖慢收敛的不是芯片而是控制面的故障感知速度和协议消息传播的默认等待时间。优化BGP定时器和BFD之后单链路故障的收敛时间直接进入亚秒级。4. 极限场景实录链路瞬断、双点故障与路由振荡压测4.1 单链路瞬断最基础的收敛测试单链路瞬断是整个测试的基石。我在Leaf-1的上联口执行shutdown前先在源Leaf和目的Leaf之间跑起了持续Ping和iperf3流量同时抓取源Leaf侧BGP报文。故障注入的一瞬间流量立刻出现连续丢包。第一次测试使用的是默认BGP配置结果是BGP状态机要等Hold Timer超时才开始处理数据面切换远远滞后中断窗口超过4秒。优化配置后同一故障的丢包窗口压缩到320毫秒只丢了2个Ping报文而且抓包显示BGP Withdraw在BFD检测到的300毫秒左右就已经发送出去数据面恢复只比控制面收敛晚了十几毫秒。这里有一个非常值得记录的细节即便控制面在320毫秒内完成了大部分工作ECMP重哈希仍然需要一点额外时间因为转发芯片要把不可用的下一跳从哈希组成员里摘除重新建立哈希映射。这也是为什么我建议不要把测试标准设成“看到BGP状态变化”就算收敛一定要结合数据面流量观察。4.2 双点故障同时注入412的冗余极限单点故障对Spine-Leaf架构来说不算什么真正的压力来自于多点并发失效。我做了两个很有代表性的场景。第一个是同时shutdown一台Leaf的上联口和另一台Leaf的某条关键链路模拟两个点同时故障。第二个是同时shutdown两台Spine把整网路径压缩到只剩一半冗余。双Spine失效时所有Leaf都会同时感知到两个BGP对等体消失BGP进程需要在短时间内处理几乎所有路由的下一跳变更。优化配置下的收敛时间从单点故障的320毫秒直接拉长到1.1秒丢包数量也增加到8个。原因不是BGP协议本身变慢而是CPU需要并发处理大量消息和FIB批量更新控制面变成了瓶颈。这个结果很有参考价值如果生产环境的冗余设计只依赖两台Spine那么一台Spine故障后紧接着另一台抖动业务中断可能就不是毫秒级而是秒级。所以在412架构里我强烈建议把Spine数量保持4台及以上并且让每台Leaf的流量负载均衡分布在所有Spine上。这样可以降低单台Spine故障后剩余Spine的流量冲击也让控制面在多点失效时有更多缓冲时间。4.3 路由振荡压测控制面是否被直接“打死”单链路故障和双点故障都还好理解路由振荡才是更容易让控制面崩溃的场景。我写了一个循环脚本在Leaf上反复添加和删除1000条EVPN Type-5路由频率大约是每秒1000条更新模拟外部路由抖动持续传入。这种情况下BGP进程需要持续处理Update、Withdraw、RIB重算和FIB下发动作CPU负载快速飙升。默认配置下结果不好看设备CPU摸到85%BGP收敛时间恶化到1.8秒路由振荡期间BFD报文因为CPU排队延迟变大甚至有BGP会话被反复重置的现象。开启CoPP之后事情立刻好转。BGP和BFD报文的CPU处理优先级被保证其他低优先级更新被限速CPU稳定在45%左右收敛时间回落到700毫秒。还有一个有效手段是给大规模Route Target设置更精确的导出策略或者对振荡路由启用route-map过滤减少无效Update进入核心转发路径。我还测试了一个额外场景启用BGP路由抖动惩罚dampening。结果发现虽然振荡本身在几轮后被抑制但收敛时间被显著拉长因为设备需要等待被惩罚的路由进入稳定状态才能重新接受。在412这种业务可靠性要求高的环境里我建议谨慎开启dampening或者把惩罚阈值调得非常宽松否则它会把“快速收敛”这根弦直接拧断。5. 常见问题与排查实录这些坑我替你踩过了5.1 BGP状态全绿流量却黑了测试过程中遇到过最神秘的现象就是BGP数据库里路都还在、状态全部Established但实际业务流量已经指向了一个不可达的下一跳。排查思路要从下一跳递归解析入手故障Leaf的上联链路虽然down了但BGP在ECMP组里保留了一条指向故障Leaf VTEP地址的路由导致流量被Ping到黑洞里。处理方法是开启BGP下一跳跟踪让协议在下一跳不可达时立即触发路由失效告警而不是等到物理链路直接与BGP状态机挂钩。同时在Leaf上做FIB状态核验确认ECMP组成员与实际可用端口一致。这类问题往往只依赖抓包看不出来必须在测试过程中持续对比show bgp和show forwarding两张表。5.2 BGP已发Update端到端还在丢包有一次抓包时间线显示Withdraw消息很快就发出去了控制面在400毫秒内就完成了收敛但流量中断窗口却持续到了800毫秒。排查后发现问题出在MAC表项老化上。VXLAN隧道的远端MAC表项需要等老化时间超时才能被新路由覆盖在故障切换的瞬间数据面还在沿用旧MAC转发表项。这类排查最有用的命令是查看每个VRF的MAC表项数量以及对应的端口信息对比故障前后哪些表项没有及时刷新。另一个办法是在故障注入前手动清空相关VRF的MAC表虽然生产环境不能这么做但测试环境中可以更清楚地观察数据面收敛的真实速度。这说明BGP控制面收敛和数据面收敛之间存在的隔阂不能简单用一个总收敛时间数字带过。5.3 BFD把BGP会话抖到反复重置BFD参数设置太激进也会出问题。某次测试我把BFD间隔调到30ms乘数因子还是3结果CPU稍一繁忙就让BFD报文延迟触发BFD会话抖动BGP跟随BFD反复重置反而形成了振荡。后来把间隔调回100ms乘数因子保持3BGP会话才稳定下来。这里的关键是理解BFD的最小间隔要和设备CPU转发能力匹配。大规模路由环境下BGP进程本身要消耗很多CPUBFD报文偶尔延迟几毫秒很正常如果间隔太小就会误判。我给的建议是控制面震荡测试中BFD间隔不要低于100ms乘数因子不要小于3除非你有非常强的信心保证CPU余量充足。生产环境更是如此BFD参数不是越小越好稳定才是第一位。5.4 一份可以直接用的排查速查表问题现象可能原因排查命令解决方案BGP全绿但流量黑洞下一跳递归解析未跟踪到位show bgp l2vpn evpn和show ip route对照下一跳开启BGP下一跳跟踪清理ECMP失效成员控制面已收敛但数据面丢包MAC/FIB表项老化滞后show mac address-table对比表项数量预先老化或缩短MAC老化时间检查硬件FIB下发BFD反复重置BGP会话BFD间隔过小CPU处理延迟超时show bfd neighbor查看协商状态放宽BFD间隔或BFD与控制面联动设置为不敏感模式路由振荡CPU冲高大量Update/Withdraw冲击BGP进程show process cpu查看BGP进程占用启用CoPP、细化RT导出过滤、谨慎使用dampening收敛时间远超预期MRAI定时器未调低show bgp neighbors查看advertisement-interval设置advertisement-interval 0并检查是否对所有Peer生效最后再分享一条我从这场测试中学到的东西收敛性能这件事设备厂商给的宣称值没有任何参考意义因为真正的瓶颈往往藏在控制面定时器、CPU排队和FIB下发路径里。别急着把故障注入结果归咎于“设备不行”先把BFD、MRAI、CoPP这些基础项全部检查一遍再谈极限性能——多数情况下问题出现在配置细节里而不是硬件能力上。
返回列表