资讯动态

H3C异地出口容灾实战:IP上一跳保持原理与配置

发布时间:2026/10/17 9:18:24 来源:尧图企业网站定制
1. 异地出口容灾到底在解决什么问题做过数据中心网络运维的人大概都经历过这种心跳时刻主出口链路突然抖动BGP邻居断了下面挂着的几十个业务网段瞬间不可达监控大屏一片红电话开始响。如果只是单机房单出口那还好办切备用链路就行。但现实往往是——业务已经做了双活甚至多活两个数据中心分布在不同的城市每个站点都有自己的出口这时候问题就变得复杂了。异地出口容灾的核心诉求其实就一句话当主站点的出口不可用时流量能不能自动、快速地绕到备站点的出口出去而且绕过去之后还能原路回来。听起来简单做起来处处是坑。最常见的坑就是流量绕过去了但回程流量找不到路或者回程流量走了另一条路导致TCP会话中断。这就是所谓的非对称路由问题也是异地出口容灾里最让人头疼的事情。我接触过的场景里很多团队一开始觉得不就是跑个BGP嘛两边都宣告一下不就行了结果上线之后发现业务时通时断抓包一看去程走A站点出口回程从B站点回来防火墙会话表对不上直接丢包。这种问题在纯路由层面看是正常的因为路由表里两条路都可达设备选哪条都符合协议规范。但对业务来说这就是灾难。H3C的IP上一跳保持技术就是专门用来治这个病的。它的核心思路是让从某个出口出去的流量回程的时候还能回到同一个出口哪怕中间经过了异地转发。这样防火墙、NAT、会话保持这些有状态设备就不会因为路径不一致而懵掉。这个技术不是H3C独有的概念但H3C在Comware平台上把它做得比较完整配置起来也相对直观。这篇文章适合谁看如果你正在规划或维护跨数据中心的出口容灾方案手上有H3C的设备或者你用的是其他厂商但想理解这类技术的底层逻辑那接下来的内容应该能帮到你。我会从整体设计思路讲起然后拆解IP上一跳保持的工作原理再给出一套可以照着搭的实验配置最后把我踩过的坑和排查技巧都倒出来。2. 整体方案设计与技术选型思路2.1 为什么不能只靠BGP多出口宣告很多人第一反应是两个站点都跟运营商跑BGP主站点宣告所有业务网段备站点也宣告同样的网段通过AS_PATH或者Local_Preference来控制选路。主出口断了备站点的宣告自然生效流量就切过去了。这个思路在去程方向是没问题的BGP收敛之后外部流量确实会从备站点进来。但问题出在回程。假设主站点有个业务网段10.1.1.0/24它从主出口出去访问外部某个服务。当主出口故障后这个网段被备站点宣告出去外部流量从备站点进来经过DCI数据中心互联链路转发到主站点的服务器。服务器回包的时候它查自己的路由表发现默认路由指向主站点的出口路由器但主出口已经断了包就丢了。或者更隐蔽的情况主站点出口路由器还有一条默认路由指向备站点包能出去但出去之后源IP是主站点的外部设备回包时又查路由发现这个源IP应该从主站点走但主站点不通又绕到备站点……来回折腾会话就断了。所以单纯靠BGP宣告解决不了回程路径一致性的问题。你需要一种机制让回程流量能够感知到去程是从哪个出口出去的并且强制它回到同一个出口。这就是IP上一跳保持要干的事。2.2 IP上一跳保持的核心逻辑IP上一跳保持英文叫IP Last-Hop Hold有些文档里也叫上一跳保持或者出口路径保持。它的基本逻辑是这样的当流量从某个出口离开数据中心时出口设备会在转发路径上记住这个流量的来源信息。当回程流量到达备站点出口时备站点出口会检查这个流量对应的会话或者路由信息发现它应该从主站点出口回去于是通过DCI链路把流量转回主站点再从主站点出口发出去。这里的关键在于记住这个动作怎么实现。H3C的实现方式通常结合了路由策略和会话保持两种手段。路由策略层面通过BGP的Community属性或者路由标记让备站点知道哪些网段是主站点优先的。会话保持层面通过出口设备的会话表同步或者源IP路由查找确保回程流量走对路。我个人的理解是这个技术本质上是在路由层面模拟了一种粘性。正常情况下路由是逐跳独立的每个设备只看目的地。但IP上一跳保持打破了这种独立性它让回程路径依赖于去程路径的选择。这在分布式系统里其实是一种会话亲和性的体现只不过实现层从应用层下沉到了网络层。2.3 方案选型为什么选H3C这套市面上能做异地出口容灾的方案不少我大致列一下常见的几种对比一下各自的优劣方案类型核心机制优点缺点纯BGP多宣告双站点宣告相同网段配置简单无额外协议回程路径不可控非对称路由严重策略路由PBR基于源IP强制下一跳控制精细配置量大维护复杂扩展性差隧道回注通过隧道把回程流量拉回主站点路径确定隧道开销大故障点增加IP上一跳保持路由标记会话感知路径一致性好对业务透明需要设备支持配置有一定门槛SD-WAN方案集中控制器编排自动化程度高成本高依赖控制器可用性选H3C的IP上一跳保持主要看中几点一是Comware平台对这个特性的支持比较成熟命令行配置清晰二是它不需要额外买控制器或者隧道设备利用现有的DCI链路就能做三是对业务完全透明服务器和外部设备都不需要改任何配置。当然它也不是银弹后面我会讲什么场景下它搞不定。2.4 网络拓扑设计要点在动手配置之前拓扑设计是第一步。我建议的典型拓扑是这样的两个数据中心分别叫DC-A和DC-B各自有一个出口路由器或者防火墙兼做出口中间通过一条DCI链路互联。DC-A是主站点DC-B是备站点。两个站点都跟各自的本地上游运营商跑BGP。关键设计点有几个第一DCI链路的带宽要足够因为故障时所有流量都要绕行带宽至少要是主出口峰值的1.5倍以上不然切过去也是拥塞。第二两个站点的出口设备要支持IP上一跳保持特性而且软件版本要一致或者兼容不然命令对不上。第三DCI链路的IGP要跑起来确保两个站点之间的路由可达性这是回注流量的基础。第四要规划好BGP的Community属性用来标记哪些路由是主站点优先的。提示DCI链路建议用独立的物理接口或者VLAN不要跟业务流量混跑避免故障时互相影响。如果条件允许DCI链路本身也做冗余比如两条不同物理路径的链路做聚合。3. IP上一跳保持的核心细节与实操要点3.1 路由标记与Community规划IP上一跳保持的第一步是让备站点知道哪些流量需要回注到主站点。H3C的实现里通常用BGP Community属性来做这个标记。具体做法是主站点出口在向备站点发送BGP路由时给所有本站点内的业务网段打上一个特定的Community值比如65001:100。备站点收到这些路由后通过路由策略识别这个Community然后把这些路由的下一跳指向DCI链路对端的主站点出口。这里有个细节要注意Community的值本身没有固定标准你可以自己规划但建议用私有AS号段避免跟运营商冲突。比如你用65001作为私有AS那Community可以规划成65001:100表示主站点业务网段65001:200表示备站点业务网段。这样双向都清晰。配置的时候主站点出口的BGP出方向策略大概长这样# 主站点出口路由器 route-policy TO_DC_B permit node 10 if-match ip address prefix-list BUSINESS_NETS apply community 65001:100 # bgp 65001 peer 10.0.0.2 as-number 65001 peer 10.0.0.2 route-policy TO_DC_B export备站点这边入方向策略识别Community并设置下一跳# 备站点出口路由器 route-policy FROM_DC_A permit node 10 if-match community 65001:100 apply ip-address next-hop 10.0.0.1 # bgp 65001 peer 10.0.0.1 as-number 65001 peer 10.0.0.1 route-policy FROM_DC_A import这样备站点就知道凡是带了65001:100标记的路由下一跳都指向主站点出口。当主出口正常时这些路由不会被优选因为主站点自己宣告的路由Local_Preference更高所以不影响正常转发。当主出口故障时主站点的BGP宣告撤销备站点从DCI链路学到的这些路由就生效了而且下一跳指向主站点回程流量就能回到主站点出口。3.2 会话保持与状态同步光有路由标记还不够因为路由是无状态的。如果主出口故障瞬间已经建立的TCP会话怎么办路由切换需要时间BGP收敛通常要几秒到几十秒这期间会话可能已经超时了。所以IP上一跳保持通常还要配合会话同步机制。H3C的出口设备比如防火墙或者支持会话的路由器可以做会话表的热备份。两个站点的出口设备之间建立一条会话同步通道主站点的会话表实时或者准实时地同步到备站点。当主出口故障时备站点已经有完整的会话表流量切过来之后直接命中会话不需要重新建连。会话同步的配置要点同步通道建议用独立的接口或者VLAN走DCI链路但要跟业务流量做QoS隔离避免同步流量被业务流量挤掉。同步周期要根据业务对中断的容忍度来定金融类业务可能要求毫秒级普通业务秒级就够了。另外同步的会话表项要有老化机制不然备站点的会话表会无限膨胀。注意会话同步不是万能的。如果主站点是整机故障会话表可能来不及同步最后几条。所以关键业务还是要靠应用层的重连机制兜底网络层只能做到尽量不中断。3.3 DCI链路的IGP与BGP协同DCI链路本身要跑IGP确保两个站点之间的Loopback地址和互联地址可达。我一般用OSPF或者ISIS看团队习惯。IGP的收敛速度要调优比如把Hello间隔和Dead间隔调小加快故障检测。但也不要太小不然网络抖动会导致频繁切换。BGP这边两个站点之间跑IBGP或者EBGP都行。IBGP的话要注意全互联或者路由反射器的问题两个站点还好直接全互联就行。EBGP的话要配next-hop-self不然下一跳不可达。我个人的偏好是用IBGP因为同一个AS内管理起来简单Community属性传递也方便。这里有个容易忽略的点BGP的收敛速度要和IGP匹配。如果IGP已经检测到故障了但BGP还在等Hold Timer超时那切换就会慢。可以配BGP的BFD联动让BFD快速检测链路故障然后触发BGP立即撤销路由。BFD的间隔可以设到300ms左右检测时间1秒以内对大多数业务够用了。3.4 出口设备的NAT与安全策略如果出口设备做了NAT那IP上一跳保持还要考虑NAT会话的同步。主站点出口做了源NAT外部看到的是主站点出口的公网IP。当流量切到备站点出口时如果备站点也做NAT那源IP就变了外部设备的回包会发到备站点的公网IP但备站点没有对应的NAT会话包就丢了。所以NAT会话也必须同步或者备站点出口配置成不NAT直接转发让流量回到主站点再做NAT。安全策略也是同理。如果出口防火墙有安全策略备站点也要有相同的策略不然流量切过来会被拒绝。策略的同步可以手工配也可以用管理平台批量下发。我建议至少每季度核对一次两边的策略一致性不然时间长了肯定会漂移。4. 完整实操过程与关键环节实现4.1 实验环境搭建为了把整个流程讲清楚我搭了一个最小化的实验环境。用三台设备模拟DC-A出口路由器R1、DC-B出口路由器R2、外部路由器R3。R1和R2之间跑OSPF和IBGPR1和R3之间跑EBGP模拟主出口R2和R3之间也跑EBGP模拟备出口。业务网段用10.1.1.0/24挂在R1下面。IP地址规划如下设备接口IP地址说明R1G0/010.1.1.1/24业务网关R1G0/110.0.0.1/30DCI链路R1G0/2200.1.1.1/30主出口R2G0/110.0.0.2/30DCI链路R2G0/2200.1.2.1/30备出口R3G0/0200.1.1.2/30对R1R3G0/1200.1.2.2/30对R2R1的Loopback0是1.1.1.1/32R2的Loopback0是2.2.2.2/32R3的Loopback0是3.3.3.3/32。AS号规划R1和R2用65001R3用65002。4.2 基础路由配置先配IGP让R1和R2的Loopback互通# R1 ospf 1 router-id 1.1.1.1 area 0.0.0.0 network 10.0.0.0 0.0.0.3 network 1.1.1.1 0.0.0.0 # # R2 ospf 1 router-id 2.2.2.2 area 0.0.0.0 network 10.0.0.0 0.0.0.3 network 2.2.2.2 0.0.0.0然后配BGP。R1和R2之间IBGPR1和R3之间EBGPR2和R3之间EBGP# R1 bgp 65001 peer 2.2.2.2 as-number 65001 peer 2.2.2.2 connect-interface Loopback0 peer 200.1.1.2 as-number 65002 # ipv4-family unicast network 10.1.1.0 255.255.255.0 peer 2.2.2.2 enable peer 200.1.1.2 enable # # R2 bgp 65001 peer 1.1.1.1 as-number 65001 peer 1.1.1.1 connect-interface Loopback0 peer 200.1.2.2 as-number 65002 # ipv4-family unicast peer 1.1.1.1 enable peer 200.1.2.2 enable # # R3 bgp 65002 peer 200.1.1.1 as-number 65001 peer 200.1.2.1 as-number 65001 # ipv4-family unicast peer 200.1.1.1 enable peer 200.1.2.1 enable这时候R3应该能从R1和R2都学到10.1.1.0/24。正常情况下R3会优选R1过来的路由因为AS_PATH更短或者Local_Preference更高。你可以通过调整Local_Preference来明确主备关系比如在R1上对R3的邻居设置更高的Local_Preference。4.3 IP上一跳保持配置现在到了核心部分。我们要让R2在从R1学到10.1.1.0/24时打上Community标记并且设置下一跳为R1。这样当R1的出口故障时R2宣告给R3的路由生效R3的回程流量会到R2R2再根据下一跳把流量转回R1。先在R1上配置出方向策略给业务网段打Community# R1 ip prefix-list BUSINESS_NETS index 10 permit 10.1.1.0 24 # route-policy TO_R2 permit node 10 if-match ip address prefix-list BUSINESS_NETS apply community 65001:100 # bgp 65001 ipv4-family unicast peer 2.2.2.2 route-policy TO_R2 export然后在R2上配置入方向策略识别Community并设置下一跳# R2 route-policy FROM_R1 permit node 10 if-match community 65001:100 apply ip-address next-hop 10.0.0.1 # bgp 65001 ipv4-family unicast peer 1.1.1.1 route-policy FROM_R1 import这里有个关键点apply ip-address next-hop 10.0.0.1这个动作是让R2在转发去往10.1.1.0/24的流量时下一跳指向R1的DCI接口地址。这样即使R2从R3收到了回程流量它也会把流量转给R1由R1再发给业务服务器。但这里还有个问题R2从R1学到的路由默认是不会宣告给R3的因为IBGP学到的路由不会传给EBGP邻居水平分割。所以我们需要在R2上配置peer 200.1.2.2 advertise-community并且确保R2把从R1学到的路由宣告给R3。这需要R2上有对应的路由策略允许宣告。# R2 route-policy TO_R3 permit node 10 if-match community 65001:100 # bgp 65001 ipv4-family unicast peer 200.1.2.2 route-policy TO_R3 export peer 200.1.2.2 advertise-community这样R2就会把带了65001:100标记的路由宣告给R3。R3收到后如果R1的路由失效就会优选R2的路由回程流量发到R2R2再转给R1。4.4 验证与切换测试配置完成后先验证正常状态。在R3上看BGP路由表应该看到10.1.1.0/24有两条路径优选R1的。在R2上看路由表10.1.1.0/24的下一跳应该是10.0.0.1。然后模拟主出口故障在R1上关闭G0/2接口或者断开R1和R3之间的链路。观察R3的路由表变化应该在几秒内切换到R2的路径。然后在R3上ping 10.1.1.1应该能通。在R2上抓包应该能看到回程流量从R3进来然后从G0/1转发给R1。再模拟主站点整机故障在R1上关闭所有接口或者直接断电。这时候R2从R1学到的路由会撤销但R2之前已经宣告给R3的路由可能还在。如果R2没有及时撤销R3会把流量发给R2但R2发现下一跳10.0.0.1不可达流量就丢了。所以需要配置BFD或者路由快速收敛机制让R2尽快感知到R1的故障并撤销路由。# R2上配置BFD联动 bfd multi-hop enable # bgp 65001 peer 1.1.1.1 bfd enableBFD检测到R1不可达后R2会立即撤销从R1学到的路由并停止向R3宣告这些路由。R3收到撤销消息后会切换到其他路径如果有的话或者丢弃流量。这时候如果R2自己有备份路径比如R2直接有默认路由出去那流量可以从R2出去但源IP还是10.1.1.0/24回程可能会有问题。所以整机故障的场景通常需要备站点也宣告业务网段并且做好NAT和会话同步。5. 常见问题与排查技巧实录5.1 回程流量不通的排查思路这是最常见的问题。现象是去程流量能到服务器服务器也回了包但包在某个地方丢了。排查的时候我一般按这个顺序来第一步在R3上看路由表确认10.1.1.0/24的下一跳是不是R2。如果是R1那说明切换没生效检查BGP状态和路由策略。第二步在R2上看路由表确认10.1.1.0/24的下一跳是不是10.0.0.1。如果不是检查入方向策略有没有匹配上Community。第三步在R2上抓包看回程流量有没有进来进来之后有没有转发出去。如果进来了没出去可能是路由表里没有对应的下一跳或者ARP没解析。第四步在R1上抓包看流量有没有从DCI链路进来进来之后有没有发给服务器。如果没进来检查R1和R2之间的IGP是否正常。我遇到过一种情况R2上路由表是对的但流量就是不通。后来发现是R2的apply ip-address next-hop只对BGP路由生效但R2上还有一条静态路由优先级更高把流量抢走了。所以排查的时候一定要看display ip routing-table的完整输出确认实际生效的路由是哪条。5.2 Community属性丢失问题Community属性在BGP传递过程中可能会丢失尤其是跨EBGP的时候。如果R2向R3宣告路由时没有带advertise-communityR3就看不到Community后续的路由策略就没法匹配。所以配置的时候一定要确认每个EBGP邻居都开了advertise-community。另外有些运营商会在入方向过滤掉私有Community如果你的DCI链路要经过运营商的网络那Community可能传不过去。这种情况下可以考虑用其他标记方式比如AS_PATH prepend或者MED但效果不如Community直观。5.3 会话中断与TCP超时即使路由切换很快已经建立的TCP会话也可能因为路径变化而中断。TCP对路径变化是敏感的如果RTT突然变大或者出现乱序TCP可能会触发重传甚至重置连接。所以IP上一跳保持只能保证新会话走对路老会话能不能存活取决于会话同步和TCP的容忍度。我的经验是对于长连接业务比如数据库连接、消息队列一定要做会话同步而且同步周期要短。对于短连接业务比如HTTP API路由切换快一点就行应用层重试能兜住。另外可以在出口设备上调整TCP的keepalive参数让会话在路径切换时不容易被判定为超时。5.4 常见问题速查表现象可能原因排查命令解决方法回程流量不通下一跳未设置display bgp routing-table检查入方向策略的apply ip-address next-hopCommunity丢失未开advertise-communitydisplay bgp peer verbose在EBGP邻居上开启切换慢BFD未配置display bfd session配置BFD联动调小检测间隔会话中断会话未同步display session table配置会话同步缩短同步周期路由环路下一跳指向自己tracert检查DCI链路两端的下一跳配置NAT后源IP变化NAT未同步display nat session备站点不做NAT或同步NAT会话5.5 几个容易踩的坑第一个坑DCI链路带宽不足。故障切换后所有流量都走DCI如果带宽不够丢包率飙升业务体验比中断还差。我建议DCI带宽至少是主出口峰值的1.5倍而且要做QoS保证关键业务优先。第二个坑路由震荡。如果BFD检测间隔太短网络轻微抖动就触发切换来回震荡会导致路由表频繁变化CPU飙升。BFD间隔建议300ms到500ms检测次数3次这样既能快速检测又不会太敏感。第三个坑安全策略不一致。主站点放行的策略备站点没放行切换后流量被拒绝。这个只能靠定期核对或者用自动化工具做策略比对。第四个坑忽略IPv6。现在很多业务是双栈的IPv4的IP上一跳保持配好了IPv6没配切换后IPv6业务全断。所以配置的时候要IPv4和IPv6一起做别漏了。6. 方案扩展与个人经验体会这套方案在实际环境里跑了一段时间后我发现还有几个可以优化的方向。一个是自动化切换现在虽然BFD能触发路由切换但NAT会话同步、安全策略切换还是手工的如果能把整个切换流程编排起来故障恢复时间能进一步缩短。另一个是多出口场景如果不止两个站点而是三个甚至更多那Community的规划会更复杂可能需要引入路由反射器或者集中控制器。我个人在实际操作中的体会是IP上一跳保持这个技术配置本身不难难的是对整个转发路径的理解。你得清楚流量从哪来、到哪去、中间经过哪些设备、每个设备上做了什么动作。任何一个环节没考虑到切换后就可能出问题。所以我在做这类项目的时候一定会先画一张完整的流量路径图把去程和回程都标清楚然后再动手配。最后再分享一个小技巧测试的时候不要只测pingping只能验证连通性验证不了会话保持。要用真实的业务流量测比如建一个TCP长连接然后模拟故障看连接会不会断。如果断了抓包分析是路由问题还是会话问题。只有真实业务测通了才能放心上线。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑