本页课程原文(点开阅读)

BMP 路由观测

课程(6 节,按顺序学)

① 为什么 show 命令不够用

入门 · 约 8 分钟

本课目标:搞清 BMP 要解决的到底是什么问题——不是「多一种看 BGP 的方式」,而是设备上根本回答不了的那几类问题。

先看一个具体的问题

「这条路由为什么不在我的 BGP 表里?」

★ 它只有两个可能的答案,而排障方向完全相反:
· 邻居压根没发 → 去找对方
· 邻居发了,我的入向策略丢了 → 查自己的 route-map

★★★ 而在设备上,show bgp 对这两种给出的输出一模一样:都是「没有这条路由」。

★★ 想在设备上区分,代价是什么

得开 soft-reconfiguration inbound,才能 show bgp neighbor x received-routes。

★★ 而那等于把 Adj-RIB-In 再存一份:4 个全表邻居大约多花 1.4 GB 内存。

★★★ 更要命的是时效性:它必须在出问题之前就开好。事后再配,你看到的是配上之后的状态,而那个想查的时刻已经过去了。

★★ 还有一整类问题 show 根本答不了

★★★ show 给的是当前状态的快照,所以:

· 「半小时前那条路由抖了几次」→ 没有记录
· 「对端发来的原始 MED 是多少」→ 策略改完就没了
· 「昨天下午为什么断了 5 分钟」→ 日志滚掉了

★ 而且你还得恰好登在那台设备上、恰好在那个时刻。

BMP 做的是什么

把设备的 BGP 表持续地、原样地、在设备之外记录下来。关键是它送的不止一张表:

· Adj-RIB-In pre-policy —— 邻居原样发来的(★★★ 最有价值的一张)
· Adj-RIB-In post-policy —— 过完策略剩下的
· Adj-RIB-Out pre/post(RFC 8671)—— 我发出去的
· Local-RIB(RFC 9069)—— 选完最优路径的

★★★ pre 和 post 的差集,就精确等于你的策略干了什么。

实验重点

  • ★★★ 「路由为什么不在表里」只有两个答案,而 show bgp 对它们的输出一模一样。
  • ★★ 在设备上区分要付 soft-reconfiguration 的内存(约 1.4 GB),而且必须事先开好。
  • ★ BMP 的本质是持续的流,而 show 是当下的快照——这是它们的根本区别。

② ★★★ pre 减 post,就是你的策略干的事

入门 · 约 10 分钟

本课目标:掌握本模块最核心的一个操作:拿 pre-policy 减 post-policy,直接读出「这条路由的命运」和「该去查谁」。

三种可能的差集结果

★★★ 一条路由在 pre / post 两个视图里的组合只有三种有意义的情况:

· pre 有、post 没有 → 你的策略丢的 → 查自己
· 两个都没有 → 邻居没发 → 找对方
· 都有但属性不一样 → 策略悄悄改了它(最难查的一种)

★ 剩下一种「都有且一致」就是正常放行,没什么可说的。

★★★ 亲手对比②和③两个场景

★★★ 这两个场景症状完全一样(表里没有 10.20.0.0/16),但原因相反:

· ②policy-drop:pre 里有 → 是你自己的 deny 丢的
· ③never-sent:pre 里也没有 → 邻居压根没发

★★ 连着看一遍,就明白为什么没有 BMP 时这两种会让双方互相甩锅——你说「你没发」,对方说「我发了」,而谁都拿不出证据。

★ 差集还告诉你「是哪一行规则」

策略是有顺序的:第一条匹配上的规则决定命运,后面的不再看。

★ 所以差集页会直接指出是 route-map 里的哪一行干的——而现网里「规则顺序写错」是个真实的高频错误:一条本该在后面的宽匹配放到了前面,把它后面所有精确规则都盖住了。

这件事的实际价值

★★ 在对等互联和上游排障里,有 BMP 的一方话语权完全不同:

· 没有 pre-policy 时,你只能说「我这边没看到」——这不构成证据
· 有 pre-policy 时,你能说「你在 14:32 发过来的就是这个属性组合」

★ 这也是为什么大型网络和 IX 几乎都上了 BMP。

实验重点

  • ★★★ pre 有 post 没有 = 你丢的;两个都没有 = 邻居没发。这两种在 show bgp 里长得一样。
  • ★★ 策略是「第一条匹配的赢」,所以差集页会指出是哪一行规则决定的。
  • ★ pre-policy 视图是排对等互联纠纷时唯一拿得出手的证据。

③ ★★ 被改属性,比被丢掉更难查

进阶 · 约 9 分钟

本课目标:理解为什么「路由还在但属性变了」是最隐蔽的一类问题,以及为什么它在设备上完全无法排查。

先说为什么它更难

被丢掉至少有个明确的异常现象:路由不在表里,你会去查。

★★★ 而被改属性什么现象都没有:
· 路由在表里 ✓
· 状态正常 ✓
· 只是选路结果和你预期的不一样

★ 于是人会去怀疑「是不是对方改了」「是不是 BGP 选路规则我理解错了」,而真相是自己那条 set local-pref 匹配范围写宽了。

★★★ 关键:show 显示的是改完之后的值

★★★ show bgp 里的 local-pref、MED、AS 路径,都是过完入向策略之后的。

★★ 所以在设备上你根本看不到原始值是多少——既不知道对方发来的是什么,也就无法判断「这个差异是不是我自己造成的」。

★ 这类问题属于「show 根本回答不了」那一档,不是「开个 soft-reconfiguration 就行」。

★★ 几种典型的隐蔽改动

· 改 local-pref → 选路结果变了,而路由看着好好的
· AS 路径前置 → 改完就分不清哪几跳是真实路径
· 改 community → ★★ 影响会传播到下游别人家里,而对方只看到改完的值,看不到你改了什么
· 改 MED → 同一个上游的多条入口之间的选择被悄悄改变

★ 最后一条尤其难查,因为它只在多入口场景下才显现。

实验重点

  • ★★★ 被改属性没有任何异常现象——路由在、状态正常,只是选路结果不对。
  • ★★ show bgp 显示的是改完之后的值,所以原始值在设备上根本看不到。
  • ★ 改 community 的影响会传播到下游,而下游只能看到改完的结果。

④ ★★ 订哪几张 RIB,以及初始同步的代价

进阶 · 约 9 分钟

本课目标:搞清订阅设计的取舍:pre-policy 是必须的,而每多订一张 RIB,全表 dump 的量就翻一倍。

★★★ 只订 post-policy = 白上 BMP

★★★ 这是现网最常见的一个配置疏漏,而它不报错:

BMP 配上了、会话建立了、数据在流、界面一切正常——但那个最有价值的问题还是答不了。

★★ 你付了全部代价(全表 dump、带宽、监控站的存储),只拿到一个 show bgp 的远程副本。

★ 所以订阅设计的第一条规则:pre-policy 必须订。

★ 每多订一张,量就翻一倍

同时订 pre 和 post,意味着同一张表要传两遍。加上 Adj-RIB-Out 就是四遍。

★ 所以合理的取舍是:
· pre-policy —— 必须(否则没意义)
· post-policy —— 可以省,设备上 show bgp 差不多就是它
· Adj-RIB-Out —— 只在排「我到底发没发给对方」时才需要
· Local-RIB —— 想让站点直接看到最优路径时才需要

★★ 初始同步的真实代价

BMP 会话一建立,设备要把每个邻居的整张表全量吐一遍。

★ 4 个全表邻居、单张 RIB:约 380 万条、540 MB、按 2 万条/秒要 3 分钟。同时订 pre+post 就是双倍。

★★★ 而这段时间控制面一直在忙。现网风险:在业务高峰给一台满载的边界路由器新开 BMP,有可能把控制面顶上去,进而影响 BGP 本身——监控又一次成了故障的原因。

怎么降低风险

★ 三条实用建议:

· 低峰期开启(这就是文档里那句话的真正原因)
· 一次只加一个邻居,别一口气全开
· 先确认平台支不支持给 BMP 限速(有些能设生成速率上限)

★★ 另外别忘了站点那一侧:全表 dump 的瞬时速率可能是稳态的几十倍,站点得扛得住那个峰值。

实验重点

  • ★★★ 只订 post-policy 等于白上 BMP —— 而它不报错,所以很容易一直这么跑着。
  • ★★ 每多订一张 RIB,全表 dump 的量就翻一倍。
  • ★ 初始同步会占满控制面几分钟,所以要低峰期、逐个邻居地开。

⑤ ★★★ 邻居为什么断的:归因与历史

排障 · 约 9 分钟

本课目标:学会用 Peer Down 的原因码直接定位排障方向,以及理解为什么「抖过又稳了」在设备上完全看不出来。

★★★ 原因码直接给出排障方向

BMP 的 Peer Down 消息带着断开原因,而它直接决定往哪查:

· 本端发了 NOTIFICATION → 我主动断的,查自己(原因码在手里)
· 本端 FSM 原因 → 通常是没收到对方的 keepalive,查链路和对方负载
· 对端发了 NOTIFICATION → 对方断的,而且对方的错误码你已经有了
· 对端直接消失 → 对方崩了/重启了,或者中间 TCP 被掐断

★★ 最后两种在设备上极难区分,而含义完全不同:一个是「对方有意见」,一个是「对方出事了」。

★★ 还有两种「其实不是故障」

· 邻居被删掉了(peer de-configured)→ 这是变更,不是故障
· 本端关了这路 BMP 监控 → BGP 会话本身好着呢,只是不监控了

★★★ 第二种特别容易误读成「邻居断了」——而实际上网络上什么都没发生。原因码能一眼分清。

★★ 而抖动历史是 show 完全给不了的

★★★ 一个抖了 14 次又稳定下来的邻居,在 show bgp summary 里和一个从来没抖过的完全一样:都是 Established。

★ 有些平台的 show bgp neighbor 里有 uptime 和一个连接计数器,但那只是个累计数——什么时候抖的、抖了多久、为什么抖,全都没有。

★★ 而「昨天下午业务有 5 分钟不通」这种工单,没有历史记录根本无法回答。

为什么这是本质区别

★★★ BMP 是持续的流,show 是当下的快照。

★ 快照能回答「现在怎么样」,永远回答不了「刚才发生了什么」。而排障要的恰恰是后者。

★★ 这也解释了为什么 BMP 数据要往时序库/日志系统里存:价值不在于「此刻的表」(那个 show 就有),而在于能往回翻。

实验重点

  • ★★★ Peer Down 原因码直接给出排障方向,还带着对方 NOTIFICATION 的原始字节。
  • ★★ 有两种原因其实不是故障(邻居被删、停止监控),容易被误报成故障。
  • ★★★ 抖过又稳的邻居在 show bgp summary 里和从没抖过的完全一样。

⑥ ★★ BMP 自己也会静默失效

排障 · 约 9 分钟

本课目标:认识 BMP 引入的失效模式:它是单向的,所以数据会悄悄丢;以及那个「配了但没用」的疏漏。

★★ BMP 是单向的

监控站从不向设备发请求,它只接收。所以没有任何流控机制可以「让设备慢一点」。

★ 站点处理不过来时,TCP 接收窗口缩小、反压顶到设备上,而设备面临一个选择:阻塞(可能影响 BGP)还是丢弃 BMP 数据。几乎所有实现都选择丢弃。

★★★ 于是又是那个熟悉的形状

★★★ 数据在悄悄少,而设备侧和站点侧都不报错:会话是 established 的,数据也在流,只是少了一些。

★★ 所以要监控的不是「BMP 会话是不是 established」,而是站点侧的接收速率和序列连续性——会话建立着、数据在丢,这两件事完全可以同时成立。

★ 这和 xFlow 的「导出报文丢了」、遥测的「推送连接断了」是同一类问题:「我发出去了」不等于「对方收到了」。

★★★ 另一种「配了但没用」

★★★ 比丢数据更常见的是只订了 post-policy:

一切指标都正常(会话 up、数据在流、路由表在更新),而那个最关键的问题还是答不了。★★ 直到你真的要排一个「路由为什么不在」的问题,才发现最有价值的那张表压根没订。

★ 所以 BMP 上线后应该做一次能力验证:随便挑一条被策略 deny 的路由,确认它确实出现在 pre 里。这一步不做,就不知道自己到底有没有那个能力。

三个模块的同一个主题

★★★ 可观测性这三个模块讲的是同一件事的三个面:

· xFlow:流量看不全(采样把小流和扫描抹掉了)
· 遥测:状态看不准(采样间隔决定了你能看见什么)
· BMP:路由变化无从追溯(show 只有当下)

★★ 而三个模块的失效模式也是同一个形状:最危险的不是报警,是沉默——图是平的、没有告警,而你已经瞎了。

实验重点

  • ★★ BMP 是单向的,站点跟不上时设备会丢弃 BMP 数据而不是阻塞 BGP,且不报错。
  • ★★★ 要监控站点侧的接收速率和序列连续性,而不是「会话是不是 established」。
  • ★ 上线后要做能力验证:挑一条被 deny 的路由,确认它确实出现在 pre-policy 里。
冀ICP备2026021556号-2|冀公网安备13068302000206号