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 里。