BGP容灾机制GR与NSR深度解析:抓包验证路由不中断
BGP邻居断了按常理路由该撤就得撤业务应该立刻中断才对。但有些生产环境就是这么邪门——邻居明明down了业务流量却依旧四平八稳地跑。一开始我也觉得是玄学直到我抓着报文把GR和NSR两个机制彻底过了一遍才明白这背后根本不是魔法而是一套设计上就“故意不感知故障”的容灾逻辑。这篇文章就围绕这个平时的“黑科技”展开讲讲GRGraceful Restart和NSRNon-Stop Routing到底怎么工作以及怎么用抓包让它们显出原形。文中会涉及BGP状态机、协议报文、路由撤销机制也会给你可以直接照抄的抓包命令和配置片段。无论你是刚学BGP的运维新手还是在核心网泡了多年的路由老兵这篇都能给你一点新的视角。1. 先搞懂BGP邻居断了之后原以为会发生什么1.1 BGP不是一个人说话它是靠三个定时器续命的要理解GR和NSR的价值得先把“邻居断了”这件事的默认后果看透。BGP是基于TCP的端口179邻居之间要靠Keepalive报文维持存活。缺省情况下Keepalive每60秒发一次Hold Time是180秒。也就是说只要我在180秒内没收到你的任何报文我就认定你死了然后把所有从你学来的路由全部撤销同时主动断开TCP连接。这里有个很反直觉的点BGP认为邻居“down”不一定是物理链路断了也可能是对端设备重启、路由进程重启、或者把BGP进程关闭了。这种情况下对端设备很可能压根没来得及发送“我要死了”的Notification报文本地就直接超时判死。默认配置下从邻居实际断线到本地感知最长需要180秒。这还是在没有BFD联动的前提下生产环境为了快速收敛一般会配BFD把感知时间压到秒级甚至毫秒级。但问题是感知快不等于业务不中断。哪怕BFD瞬间感知到故障本地BGP依然会撤销所有从故障邻居学到的路由这些路由从路由表里消失转发面瞬间就没有了下一跳。如果这个邻居是你的核心出口底下所有业务直接黑屏。所以业界才折腾出GR和NSR核心思路就一句话要么假装没断要么在断的瞬间替你把活干了。1.2 状态机不是背的它是故障恢复的地图BGP的状态机大家都背过Idle、Connect、Active、OpenSent、OpenConfirm、Established。平时觉得它只是考试题但真正排查容灾问题时你会发现这些状态才是最直接的证据。正常情况下邻居稳定在Established。一旦出现故障状态机会跳回Idle或Connect同时撤销相关路由。而GR和NSR干预的恰恰就是“发现TCP断了但BGP状态机却不跳”或“设备内部主备切换但对外状态机不跳”这两个环节。抓包时看到报文序号变化也能辅助判断。比如正常Keepalive是周期性的如果长时间没报文然后突然出现TCP重传、RST那就是邻居在重启。GR场景中对端重启后重新建立TCP状态机快速跑一遍但路由撤销并不会发生因为本地还在“假装”对方活着。理解了默认的故障行为接下来看GR和NSR各自怎么“逆天改命”。2. GR优雅重启把“邻居重启”伪装成“几十秒的路由延迟”2.1 核心思想我不撤销路由我等你回来GR的全称是Graceful Restart翻译成优雅重启很贴切。它的适用场景非常明确对端设备因为软件升级、重启BGP进程、主控板倒换而短暂中断但转发面仍然在工作。这里的关键前提是“转发面没死”。比如一台分布式路由器主控板负责跑BGP线卡板负责转发。主控重启时线卡上的转发表项还在硬件还在按照旧的表项转发流量。只要本地BGP不撤销路由业务就不会断。GR就是在本地BGP感知到邻居断开时先不撤销路由而是把路由标记为“过期但是活着”然后静静等待邻居重新建立会话。所以GR本质上是控制面和转发面解耦的产物。它依赖两个角色Restarter重启方因为故障或人为操作导致BGP协议进程重启的设备。Helper协助方感知到对端断了但不撤销路由帮助对端保留路由信息的邻居设备。两者通过BGP Capability协商确定彼此是否支持GR。如果一个支持、一个不支持GR没法生效只能走标准撤销流程。2.2 抓包看GR的握手Open报文里的隐藏信息我们用Wireshark抓包分析一下GR的完整过程。先看正常的邻居建立流程重点是Open报文里携带的Capability。抓包过滤语法很简单tcp.port 179或者更精确地只看BGP报文bgp第一次建立邻居时双方发送Open报文。如果设备支持GR会在Open报文中携带一个Capability类型编码是64名字就叫Graceful Restart。报文里包含四个关键字段Restart State Bit标志位表示本端是不是在重启。Restart Time重启方期望Helper等多久默认通常是120秒。Stale Time路由标记为陈旧后保留的最大时间一般120秒。Address Family支持的地址族比如IPv4单播、IPv6单播、VPNv4等。抓包时看到类似这样的字段信息BGP Graceful Restart Capability (Type 64) Restart State Bit: 0 Restart Time: 120 Forwarding State Bit: 1 Address Family: IPv4 Unicast (1) Flags: 0x07 Address Family: IPv4 Unicast (1)这里的Forwarding State Bit是关键如果置1表示本端转发面能在重启期间保持转发。如果为0意味着重启期间转发面也会中断那么GR的意义就大打折扣。当对端重启并重新发起TCP连接时GR Helper就是你这边会识别到对方的Open报文中Restart State Bit为1然后立刻明白这哥们儿在重启我需要给它保留路由而不是像以前那样直接撤销。之后你会继续向它发送Update报文并且把原先从它学来的路由标记为Stale陈旧但不会从路由表中删除。这里有个容易忽略的细节GR期间Helper仍然会向Restarter发送路由但不会主动重新计算最优路径也不会因为收不到Keepalive就把路撤了。所有收敛动作都被“冻结”到计时器结束。2.3 End-of-RIBGR完成后最重要的信号当Restarter完成重启、重新建立BGP会话后双方开始同步路由。早期BGP没有明确通知“路由发完了”的机制GR协议规定了End-of-RIB标记设备发完所有Update后会发送一个空的Update报文里面没有NLRI只有End-of-RIB标志。抓包里看到这样的包BGP Update Message Withdrawn Routes Length: 0 Total Path Attribute Length: 0 Network Layer Reachability Information: 0 End-of-RIB Marker这就代表“我全量路由都发完了可以开始正常收敛”。在收到End-of-RIB之前Helper不会认为Restarter已经完成同步也不会把Stale路由丢掉。收到之后Helper会执行路由刷新把依然有效的路由保留把已经不存在的新路由替换掉然后去掉Stale标记。End-of-RIB在抓包中的出现时机非常关键。要验证GR是否成功就盯着两个点邻居重启期间你是否收到了对端发来的“撤销路由”的Update报文。如果GR生效你不会收到撤销报文只会收到TCP重连。重启结束后双方是否交换了End-of-RIB。如果抓包显示邻居断开的瞬间你立刻收到了大量Withdrawn路由那说明GR根本没有生效对端没有协商GR能力或者配置了但能力不匹配。2.4 GR的配置要点和坑华为设备配置GR很简单bgp 100 graceful-restart graceful-restart timer restart 120 graceful-restart timer stalepath 360思科设备以IOS XR为例router bgp 100 graceful-restart graceful-restart restart-time 120 graceful-restart stalepath-time 360配置不难但有几个坑必须注意。坑一全局GR和邻居级别GR不一致。有些设备支持在邻居级别关闭GR比如在华为上配了undo graceful-restart peer-reset会导致特定邻居不支持GR。抓包时Open报文里没有GR Capability那就是没协商上。坑二Restart Time和Stale Time设置不当。Restart Time必须大于设备实际重启时间否则Helper等不到对方回来就把路由清了。Stale Time一定要比Restart Time长因为Stale Time是路由在过期后还能保留的额外时长如果设得太短路由会被提前删除。提示GR期间因为路由没有撤销网络里可能出现短暂的路由环路或黑洞。毕竟是“用可用性换一致性”这也是GR不能无限期兜底的原因。一般建议Restart Time不要超过180秒。3. NSR不间断路由对端直接无感比GR更彻底3.1 为什么有了GR还需要NSRGR虽然好但它有一个先天短板它需要邻居设备配合。如果邻居设备比较老不支持GR Capability那么GR就完全失效故障瞬间路由撤销照旧。而且GR期间Restarter的重启过程对邻居仍然是可见的TCP会断状态机会跳只是邻居不撤销路由而已。NSR则完全换了一个思路。它的核心是在主备控制引擎之间做实时状态同步让备引擎随时拥有主引擎的全部BGP会话状态。当主引擎故障时备引擎立刻接管TCP连接不断、BGP状态机不跳、对端设备完全无感知。打个比方GR是邻居生病了你假装他还活着等他病好了继续聊。NSR则是这个人有个双胞胎弟弟哥哥病了弟弟一秒顶上去外人根本看不出换人了。3.2 NSR的同步原理同步的不是路由表而是会话状态NSR要真正实现“对端无感知”必须同步以下内容TCP连接状态包括序列号、确认号、窗口大小、TCP选项。因为TCP连接是对端可见的如果序列号对不上对端会立即发现异常然后重置连接。BGP状态机当前处于哪个状态、Open报文是否已发、Keepalive定时器剩余时间。收到的原始报文备引擎必须缓存最近的报文确保接管后能继续处理后续报文。输出队列还没发出去的Update报文如果丢了对端会认为路由表不完整。路由表信息这是最基础的备引擎必须拥有完整的BGP路由表包括协议状态、路径属性、惩罚信息等。这些同步一般通过设备内部的私有协议完成不需要占用数据面带宽。在抓包上NSR倒换的过程是非常干净的整个过程中不会有BGP报文丢失不会有TCP重传对端抓包看到的只是一段正常的Keepalive间隔。为了验证NSR生效可以做一个实验在两台设备之间建立BGP邻居然后在设备上执行主备倒换同时在对端设备上抓包。如果NSR生效你会看到TCP连接没有断开没有FIN或RST。BGP状态一直停留在Established没有重新建立过程。Keepalive报文依然按周期正常发送只是间隔可能因为瞬间切换出现几十毫秒的抖动。如果你抓包看到TCP窗口被重置或者出现了SYN重新握手那说明NSR没有兜住对端感知到了故障。3.3 NSR与GR怎么分工很多人以为NSR能完全替代GR其实两者是配合关系。NSR解决的是本设备主备倒换场景。本设备控制面故障备板接管对端无感知。GR解决的是对端设备重启场景。当对端设备重启时本设备作为Helper需要保留路由等待对端回来。所以一台设备上既需要配置NSR来保证自己倒换时不惊动别人也需要配置GR能力来在对端倒换时帮助对端留路由。华为设备NSR配置bgp 100 non-stop-routing思科IOS XR上NSR是默认开启的但需要开启BGP进程的NSFNon-Stop Forwarding配合router bgp 100 nsf nsf lifetime 90配置NSR时有个前置条件设备必须支持主控板1:1冗余并且主备之间的数据同步通道正常。如果同步通道中断NSR处于降级状态倒换时还是会断。4. 抓包实战把容灾过程从黑盒变成白盒4.1 抓包位置和工具选型要观察BGP容灾行为抓包位置很有讲究。推荐三个位置对端设备上直接抓对端的出接口流量。这是最干净的视角能看到TCP连接状态变化、BGP报文序列。因为我们要观察对端是否感知到重启对端视角最准。中间交换机上用端口镜像SPAN或者tap设备抓中间链路的报文。可以看到双向流量但需要交换机支持。本设备上通过loopback口抓包或者用本地报文捕获功能。这种方式容易漏掉控制面报文不如前两种直观。工具方面命令行环境用tcpdump图形化分析用Wireshark。tcpdump命令推荐tcpdump -i any tcp port 179 -s 0 -w bgp_gr.pcap这里-s 0抓完整报文避免截断导致Wireshark解析BGP字段失败。如果只想看BGP报文头不关心详细属性可以抓前256字节但建议抓完整。在Wireshark里有几个常用的过滤表达式bgp bgp.capabilities.code 64 bgp.update.withdrawn_routes bgp.update.end_of_rib bgp.keepalive tcp.flags.syn 1最有用的还是直接看bgp的完整列表结合时间轴观察报文间隔。4.2 抓包分析GR全过程一个真实的报文序列假设设备A和设备B建立BGP邻居A是RestarterB是Helper。触发A设备重启BGP进程在B设备侧抓包完整的报文序列大致如下阶段一故障前正常状态每隔60秒A和B互发Keepalive报文。报文间隔稳定TCP序列号连续性良好。阶段二A设备重启瞬间A设备BGP进程重启TCP连接断开。在B设备的抓包中会看到以下几种情况之一A发送FIN报文正常关闭TCP连接如果进程优雅退出。A直接无响应TCP超时B触发重传Keepalive重传几次后判定失败。如果配置了BFDBFD会话先断BGP快速失败。关键点如果是NSR场景这里不会有FIN或RSTTCP依然存活。如果是GR场景这里TCP会断但BGP不会立即撤销路由。阶段三GR保留期B设备把从A学来的路由标记为Stale。B设备继续通过TCP发送Keepalive虽然此时TCP已经断了收不到ACK但这些Keepalive会进入TCP重传队列。B设备不会发送任何撤销路由的Update报文。抓包上你会看到TCP连续重传Keepalive包这是GR Helper在“坚持等待”。阶段四A设备恢复A设备重新启动BGP进程主动发起TCP建立流程SYN、SYN-ACK、ACK。TCP建立成功后A和B交换Open报文里面GR Capability正常协商。因为协商成功B设备对A的Stale路由继续保留不撤销。阶段五路由同步与End-of-RIBA设备发送全量Update报文给B。B设备回复全量Update报文给A。双方发送完所有Update后发送空的Update报文End-of-RIB标志。B设备收到A的End-of-RIB后把Stale标记清除路由刷新完成GR流程结束。整个过程中B设备的转发表始终保持A的路由流量没有中断。4.3 抓包分析NSR抓不到才是正常的NSR的抓包分析思路跟GR完全不同。GR是“有事发生但没撤销路由”NSR是“压根没事发生”。所以在对端设备上抓NSR倒换你期望看到的是TCP连接一直正常序列号无跳跃。Keepalive报文按原有周期继续发送。没有任何TCP重传、SYN、FIN。BGP状态机始终Established。为了尽可能捕捉到异常建议在倒换期间提高抓包精度用-B 100提升缓冲区避免丢包。tcpdump -i eth0 -B 100 tcp port 179 -s 0 -w nsr_test.pcap如果倒换过程中出现TCP重传就要检查NSR同步状态了。常见的同步异常原因有备主控板没有完全同步BGP会话数据。设备上使用的BGP特性不受NSR支持比如部分动态BGP策略。同步通道拥塞或故障。注意NSR只解决控制面故障如果设备整机断电转发面也挂了NSR一样无能为力。这时需要靠网络层的冗余设计比如双设备、ECMP等。5. 常见问题与排查技巧实录5.1 抓包确认GR没生效排查步骤场景配置了GR但邻居重启后对端还是撤销了路由。这种问题在现网里十分常见我一般按这个顺序排查看Open报文里有没有GR Capability。抓包看邻居建立时的Open报文如果根本没这个字段说明有一端没开启GR或者设备型号不支持在当前地址族下使用GR。看Restart Time和Stale Time是否匹配。有的设备要求两端的Restart Time一致实际上不一致也能协商但要以Helper侧的设置为准。如果Restarter设置的Restart Time比Helper的Stale Time还长Helper会在Restarter回来之前就把Stale路由清掉。看邻居重启方式。GR只对BGP进程重启、主控板倒换这类“转发面幸存”的场景有效。如果是整机断电或者链路中断转发面已经不可用即使GR标记了路由数据包也发不出去业务照样断。查设备日志。华为设备上会有BGP/4/GR_HAPPEN之类的日志思科设备有BGP-5-ADJCHANGE加GR相关字段。日志能直接告诉你GR是否启动、为啥终止。5.2 NSR倒换后依然断连常见原因NSR配置正确但倒换瞬间对端还是检测到了异常。我踩过的坑主要有这几个坑一TCP选项不同步。NSR要求备引擎完全接管TCP连接状态包括序列号、时间戳、SACK等。如果主备板之间同步粒度不够倒换后对端发现TCP时间戳跳变会误判为虚假重传从而RST连接。遇到这种问题可以尝试在两端关闭TCP时间戳选项不建议生产长期关闭仅用于验证。坑二BGP能力协商信息没有同步。比如本端支持扩展消息、支持多协议扩展这些Open报文里的Capability也必须同步到备引擎。如果同步不全倒换后对端可能认为BGP会话异常重新发起协商。坑三路由表太大同步超时。有些设备在倒换前才把完整路由表同步给备板如果路由条目达到百万级同步时间可能超过BGP Hold Time。解决办法是开启增量同步或者提前预热备板。5.3 抓包工具常见问题Wireshark解析BGP失败只显示TCP多半是因为用了IP分片或者报文被截断。抓包时务必加-s 0或者设成65535保证报文完整。手机或虚拟机抓BGP包抓不到BGP报文一般走管理网或业务网口手机抓包只能看到应用层。真正的BGP抓包需要用设备命令行或者镜像口手机搞不定。过滤不到GR Capability确认Wireshark版本支持BGP扩展。老版本对Type 64的解析不全升级到最新版即可。tcpdump在设备上无法执行部分网络设备自带抓包工具比如华为的packet-capture、思科的monitor capture功能类似不能用传统的Linux命令。5.4 容灾效果验证清单最后分享一个我在现网做GR/NSR割接前必用的验证清单确认对端设备支持GR并且双方Open报文都携带GR Capability。确认GR Restart Time大于本设备最长重启时间包括BGP进程重启和OSPF协议收敛时间。确认Stale Time大于Restart Time并留有1.5倍以上余量。确认NSR主备同步状态为“Ready”或“Synced”。在测试窗口进行真实倒换在对端抓包确认无撤销路由、无TCP重置。抓包确认End-of-RIB出现并且Stale路由被正确刷新。业务验证从业务侧发送长ping或持续HTTP请求确认丢包率为0。提示切换测试千万别直接在生产上做先在实验室跑通整套流程。我见过太多人在现网“试一下”然后被GR的Stale Time不够长坑了半小时业务教训惨痛。6. 最后说点个人体会GR和NSR这两个名词在教科书上可能就是两行定义但真正踩过坑才知道它们的价值全在细节里。GR依赖的是邻居之间的“默契”NSR依赖的是设备内部的“备份”两者都和转发面的独立性密不可分。刚入行的时候我总觉得抓包是排障用的只有出了问题才打开Wireshark。后来慢慢发现抓包其实是验证容灾机制最直接的手段——有没有GR看Open报文就知道了NSR有没有生效看TCP序列号连续不连续就完了。网络不像应用系统看不到就摸不着但报文是始终诚实的。如果你正在做网络割接或者核心设备升级强烈建议在窗口前把抓包环境搭好先把正常情况下的BGP报文基线保存下来再触发一次测试切换对比两次报文的差异。这个方法看着笨但往往比任何文档都靠谱。容灾不是配几条命令就完事它得经过报文级别的验证才算真正落地。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →