多路访问网络里的DR/BDR选举,是OSPF里最不起眼、却最容易在割接窗口里翻车的一块。我这几年调过不少园区核心和运营商接入的OSPF域,真正因为路由算法本身出问题的少,大多数“邻居起不来”“路由学不全”“流量绕远路”的根子,都埋在DR/BDR的选举结果和预期不一致上。这篇文章就围绕思科设备上多路访问网络的DR及BDR选举配置展开,把选举规则、优先级和Router ID的配合、配置步骤、验证命令、特殊网络类型下的处理,以及我踩过的坑一次讲透。不管你是刚接触OSPF、能敲几条network命令的新手,还是已经做过几个项目、但对选举细节还停留在“优先级高的当DR”这种模糊认知上的老手,都能从下面找到能直接抄作业的配置和排查思路。
1. 多路访问网络为什么非要选DR/BDR
1.1 全互联邻接的代价有多大
先把问题摆出来。以太网、帧中继这类多路访问网络的特点是:同一个网段里挂着的路由器,彼此之间都能二层直达。如果OSPF不做任何优化,让每台路由器都和同网段的其他所有路由器建立完整的邻接关系,那么n台路由器就要维护n(n-1)/2条邻接。四台路由器是6条,十台就是45条。每条邻接背后都是一整套Hello、数据库描述、链路状态请求、链路状态更新的交互,还要各自泛洪LSA。路由器CPU和内存扛不扛得住是一回事,更麻烦的是链路状态数据库的同步会变得又慢又乱,任何一次拓扑变化都会在这个网段里引发大量重复的泛洪。
我见过一个典型的反面场景:某办公区接入层用一台三层交换机下挂八台路由器跑OSPF,没做任何网络类型调整,也没关注选举,结果每次重启一台设备,整个网段的路由收敛要接近一分钟。抓包一看,八台设备两两建立Full邻接,LSA泛洪在网段里反复来回。后来把网络类型和选举理顺,收敛时间直接压到几秒。
OSPF的解决办法很直接:在这个网段里选一个“代言人”和一个“备用代言人”,也就是DR(Designated Router,指定路由器)和BDR(Backup Designated Router,备份指定路由器)。其余路由器叫DRother,它们只和DR、BDR建立Full邻接,DRother之间停留在2-Way状态,不交换完整的链路状态信息。这样一来,Full邻接的数量从n(n-1)/2降到2n-3,泛洪的路径也从网状变成星型。
1.2 DR和BDR各自承担什么活
DR的核心职责是代表这个多路访问网络生成Network LSA(Type 2 LSA),把网段里所有路由器的情况汇总成一条描述,向整个区域泛洪。所有DRother把各自的链路状态更新用组播地址224.0.0.6发给DR和BDR,DR再统一用224.0.0.5发给网段内所有OSPF路由器。这个组播地址的分工是很多人忽略的细节:224.0.0.5是AllSPFRouters,所有跑OSPF的接口都监听;224.0.0.6是AllDRouters,只有DR和BDR监听。DRother发更新走224.0.0.6,就是为了避免网段内每台设备都收到重复的更新。
BDR则是热备。它和DR一样,与所有DRother建立Full邻接,同步完整的链路状态数据库,随时准备接管。DR一旦失效,BDR在几秒内顶上,重新生成Network LSA,网段内的邻接关系不会断。这里有个容易被误解的点:BDR不是“只备份不干活”,它平时也在接收和同步所有LSA,只是不生成Network LSA。所以BDR的负载并不比DR低多少,规划时不能把它当成闲置资源。
注意:DR/BDR是“按网段、按区域”存在的概念,不是按路由器存在。一台路由器有多个接口跑OSPF,可能在一个网段是DR,在另一个网段是DRother,在第三个网段是BDR,互不影响。
2. 选举规则拆解:优先级、Router ID与等待计时器
2.1 选举的判定层级其实只有四层
很多人把DR/BDR选举想得很复杂,实际上规则非常干脆,按顺序逐层比较,一旦分出胜负就停止:
- 接口优先级:范围0到255,默认1。数值越大越优先。优先级为0的接口直接放弃选举资格,连BDR都不当。
- Router ID:优先级相同时,Router ID数值大的胜出。
- 只有BDR参与DR的补位:DR选举先于BDR,选出DR后再在剩下的有资格的路由器里选BDR。
- 非抢占:已经存在的DR/BDR不会被后来者挤掉,除非它失效或者被人为清除。
这个顺序里,第一层优先级是最可控的,也是实际工程中最常用的手段。第二层Router ID则经常被忽视:默认情况下Router ID的选举顺序是手工配置的router-id优先,其次是最大的Loopback接口地址,最后是最大的物理接口地址。如果不手工指定,很可能出现“我明明想要某台设备当DR,结果它Router ID偏小,优先级又和人家一样”的尴尬。
我给一个实操建议:只要网络里有多台设备跑OSPF,就养成手工写router-id的习惯,用Loopback0的地址或者规划好的整数地址,比如1.1.1.1、2.2.2.2这种。这样选举结果可预测,排查时也不用去翻接口地址。
2.2 非抢占特性和等待计时器
这是DR/BDR选举里最容易踩的两个坑。
非抢占的意思是:假设网段里先启动了一台优先级为1的路由器,它成了DR;后来启动一台优先级为100的路由器,它不会把原来的DR挤下去,自己只能当DRother。很多人在实验室里做完“改优先级”的实验,发现show命令里DR还是老设备,就以为配置没生效。其实配置是生效的,只是OSPF的选举结果不会因为新设备加入而重新洗牌。要让新优先级生效,必须让选举重来一次,手段包括清除OSPF进程、重启接口、或者在接口下先shutdown再no shutdown。
等待计时器(Wait Timer)则决定了选举什么时候开始。在广播网络和NBMA网络里,路由器启动后不会立刻选举,而是等一个等于Dead Interval的时间,广播网络默认40秒,NBMA默认120秒。这段时间里,邻居状态停留在2-Way。等待计时器的设计意图是给网段内所有路由器一个集结的时间,避免先启动的设备“抢跑”当上DR,后启动的高优先级设备再引发不必要的重新选举。
我在实际割接中遇到过这样的情况:变更窗口里先重启了核心交换机,它起来后抢成了DR;二十分钟后再重启备机,备机优先级更高,但因为非抢占,它只能当DRother。结果整个网段的流量路径和设计文档对不上。后来我们的标准做法是:凡是涉及DR/BDR变更的割接,所有相关设备一起重启,或者干脆在变更前用clear ip ospf process把选举结果归零,变更后第一时间用show ip ospf neighbor核对。
3. 实操配置:把DR/BDR钉在指定设备上
3.1 先规划拓扑和地址,再动配置
我拿一个最常见的三台路由器接同一台二层交换机的场景来演示。三台设备分别叫R1、R2、R3,接口都是GigabitEthernet0/0,同处10.0.0.0/24网段,都划进OSPF区域0。规划目标是:R1当DR,R2当BDR,R3当DRother。为什么这么规划?因为R1是性能最好的核心设备,R2是它的热备,R3是接入设备,只负责把直连网段通告进来。这个角色划分要在配置之前就定好,不要等选举完了看谁当上再补文档。
地址规划如下:
| 设备 | 接口 | IP地址 | Router ID | OSPF优先级 |
|---|---|---|---|---|
| R1 | Gi0/0 | 10.0.0.1/24 | 1.1.1.1 | 100 |
| R2 | Gi0/0 | 10.0.0.2/24 | 2.2.2.2 | 50 |
| R3 | Gi0/0 | 10.0.0.3/24 | 3.3.3.3 | 1 |
这里的优先级取值是有讲究的。默认值是1,R3保持默认即可。R1给100、R2给50,中间留出足够的空间,以后如果临时插入一台设备想让它当DR,给个101就行,不用把现有配置全改一遍。我不建议把优先级直接拉到255,那样以后没有调整余地。
3.2 接口优先级和Router ID的配置方法
配置分两步:全局的router-id和接口的优先级。先看R1的完整配置:
R1(config)# interface Loopback0 R1(config-if)# ip address 1.1.1.1 255.255.255.255 R1(config-if)# exit R1(config)# router ospf 1 R1(config-router)# router-id 1.1.1.1 R1(config-router)# network 10.0.0.0 0.0.0.255 area 0 R1(config-router)# network 1.1.1.1 0.0.0.0 area 0 R1(config-router)# exit R1(config)# interface GigabitEthernet0/0 R1(config-if)# ip address 10.0.0.1 255.255.255.0 R1(config-if)# ip ospf priority 100 R1(config-if)# no shutdownR2和R3的配置结构一样,只改地址、Router ID和优先级。这里的关键命令是接口下的ip ospf priority 100,它只影响该接口所在网段的选举,不影响其他接口。Router ID则建议显式写在router ospf进程下,别依赖自动选举。
提示:如果设备已经跑起来OSPF再去改router-id,新值不会立刻生效,必须执行
clear ip ospf process并确认。改优先级也一样,接口下的优先级改完,现有选举结果不会自动重算。
配置完成后,用show ip ospf interface GigabitEthernet0/0确认优先级和网络类型:
R1# show ip ospf interface GigabitEthernet0/0 GigabitEthernet0/0 is up, line protocol is up Internet Address 10.0.0.1/24, Area 0 Process ID 1, Router ID 1.1.1.1, Network Type BROADCAST, Cost: 1 Transmit Delay is 1 sec, State DR, Priority 100 Designated Router (ID) 1.1.1.1, Interface address 10.0.0.1 Backup Designated router (ID) 2.2.2.2, Interface address 10.0.0.2 Timer intervals configured, Hello 10, Dead 40, Wait 40, Retransmit 5输出里的State DR、Priority 100、Designated Router和Backup Designated Router这几行,就是验证选举结果的核心。能看到Wait 40,说明等待计时器等于Dead Interval,这是广播网络的默认行为。
3.3 用邻居表交叉验证选举结果
接口视图看的是本机视角,邻居表看的是全局视角,两个要对照着看:
R1# show ip ospf neighbor Neighbor ID Pri State Dead Time Address Interface 2.2.2.2 50 FULL/BDR 00:00:36 10.0.0.2 GigabitEthernet0/0 3.3.3.3 1 FULL/DROTHER 00:00:31 10.0.0.3 GigabitEthernet0/0在R1(DR)上,R2显示FULL/BDR,R3显示FULL/DROTHER。切到R3上看,会看到R1是FULL/DR,R2是FULL/BDR,而如果网段里还有第四台DRother,R3和它之间会是2WAY/DROTHER。这个2-Way状态是正常的,不是故障,很多人第一次看到就慌,以为邻居没起来。
我一般还会补一条show ip ospf neighbor detail,把优先级、Dead Time、接口地址都列出来,排查时比简表信息全。另外show ip ospf database里能看到DR生成的Network LSA,LSA的Link State ID就是DR接口地址,这也是一种反查手段。
3.4 想把某台设备排除出选举怎么办
有些场景下,比如一台低性能的接入路由器,我们根本不想让它参与DR/BDR选举,省得它占着BDR位置却扛不住泛洪。做法很简单,把接口优先级设为0:
R3(config)# interface GigabitEthernet0/0 R3(config-if)# ip ospf priority 0优先级0意味着永远不参与选举,状态固定为DRother。注意,优先级0和“优先级低”是两回事:优先级1的设备在DR和BDR都挂掉后还能补位,优先级0的设备永远不补位。所以核心网段里不要把关键设备的优先级误设成0。
4. 特殊场景:NBMA、点到点网络与手工邻居
4.1 帧中继NBMA下必须手工指定邻居
广播网络里设备能自动发现邻居,是因为Hello包走224.0.0.5组播,二层天然支持广播。帧中继这类NBMA网络默认不转发广播,OSPF的Hello包发不出去,邻居自然起不来。思科的处理方式是把接口网络类型改成non-broadcast,然后手工指定邻居:
R1(config)# interface Serial0/0 R1(config-if)# ip address 10.0.1.1 255.255.255.0 R1(config-if)# ip ospf network non-broadcast R1(config-if)# exit R1(config)# router ospf 1 R1(config-router)# neighbor 10.0.1.2 R1(config-router)# neighbor 10.0.1.3NBMA网络的Hello是30秒、Dead是120秒,等待计时器也是120秒,选举过程比广播网络慢得多。而且NBMA下DR/BDR的选举同样遵循优先级和Router ID规则,但因为邻居是手工指定的,一定要保证所有设备都配了邻居关系,否则单向邻居会导致选举结果残缺。我在一个老帧中继项目里见过只在一端配neighbor的情况,结果那台设备认为自己没有邻居,选举根本不发生,网段里一直没有DR,Network LSA也生成不出来。
注意:NBMA网络里如果中心节点是DR,分支之间要互访,流量必须经过中心节点。这时DR的位置就决定了流量路径,规划时要把中心节点的高优先级配好,别让某个分支抢了DR。
4.2 用点到点网络类型直接绕开选举
如果网段里其实只有两台设备,或者你根本不关心DR/BDR这套机制,最省事的办法是把接口网络类型改成point-to-point:
R1(config)# interface GigabitEthernet0/0 R1(config-if)# ip ospf network point-to-point改成点到点后,不再有DR/BDR选举,两台设备直接建立Full邻接,Hello 10秒、Dead 40秒,不生成Network LSA。这个做法在GRE隧道、点对点专线、以及一些云上互联场景里非常常见。我个人的习惯是:只要确认网段里只有两个OSPF参与者,优先用point-to-point,省掉选举带来的不确定性和收敛延迟。
还有一种情况是Loopback接口,它默认就是point-to-point类型,不受选举影响,通告出去的是/32主机路由。这也是为什么Router ID常用Loopback地址:稳定、不参与选举、不会因为物理接口抖动而变。
4.3 广播网络里也能手工指定邻居吗
可以,但不推荐。广播网络下如果同时配了neighbor命令,OSPF会以单播方式发送Hello,但网络类型判断上仍可能按广播处理,容易出现一边组播一边单播、邻居状态卡在Init的情况。除非有特殊的访问控制需求,否则广播网络就让设备自动发现,别手工加neighbor。
5. 故障排查实录与避坑清单
5.1 选举结果和预期不符,按这个顺序查
第一类高频问题是“我改了优先级,为什么DR还是别人”。排查路径我整理成了一条线:
show ip ospf interface确认优先级真的改上去了,别只看配置文件。- 确认改完之后有没有触发重新选举。没clear进程、没重启接口,结果不会变。
- 确认等待计时器是否已经走完。设备刚起来40秒内,邻居还在2-Way,选举没开始。
- 确认Router ID是不是和预期一致,优先级相同时它说了算。
- 确认有没有设备优先级被误设为0,直接退出了选举。
第二类问题是“邻居卡在2-Way不动”。这时候先看对方是不是DRother:两个DRother之间停在2-Way是正常设计。如果对方应该是DR或BDR却还是2-Way,那就要查网络类型是否一致、MTU是否匹配、Hello/Dead计时器是否一致。网络类型一边是broadcast一边是point-to-point,邻居能到Init但永远到不了Full,这是很隐蔽的坑。
第三类问题是“DR频繁切换”。常见原因是接口抖动、Dead计时器超时、或者有人反复clear进程。频繁切换会导致Network LSA反复重新生成,整个区域的路由都在抖。遇到这种情况,先查物理链路和接口errordisable,再查有没有设备配置了相同的Router ID——Router ID冲突会导致选举结果混乱,这个坑非常深。
5.2 常见问题速查表
| 现象 | 可能原因 | 处理办法 |
|---|---|---|
| 改了优先级但DR没变 | 非抢占特性,选举未重来 | clear ip ospf process或重启接口 |
| 邻居一直2-Way | 双方都是DRother,正常 | 无需处理,确认角色即可 |
| 邻居卡Init | 组播不通、ACL拦截、网络类型不一致 | 检查ACL和ip ospf network |
| 没有DR产生 | NBMA未配neighbor、优先级全为0 | 补neighbor命令,检查优先级 |
| DR频繁切换 | 链路抖动、Dead超时、Router ID冲突 | 查物理层、查router-id唯一性 |
| 路由学不全 | DR/BDR选举异常导致Network LSA缺失 | show ip ospf database核对Type 2 LSA |
5.3 几条用血换来的经验
第一条,变更前先备份选举结果。把show ip ospf neighbor和show ip ospf interface的输出存下来,变更后逐行对比。别凭记忆判断“以前DR是谁”,记忆在凌晨三点的机房里最不可靠。
第二条,优先级规划要留余量。默认1,核心给100,备给50,这个梯度足够应付大多数调整。别用1、2、3这种紧挨着的值,以后想插一台设备都没法插。
第三条,Router ID必须全域唯一且手工指定。自动选举的Router ID在接口地址变更后会跟着变,一变就可能引发选举重算。我现在的标准模板里,router-id是必填项,和主机名一样属于开局配置。
第四条,别在业务高峰期做选举相关变更。clear ip ospf process会让整个进程重启,所有邻居重建,哪怕是毫秒级的抖动也可能导致短暂丢包。窗口期选在业务低谷,变更后观察至少十分钟的邻居状态和路由表。
第五条,文档里写清楚每个网段的DR/BDR角色。这不是形式主义。我接手过一个运行了三年的网络,文档里只写了“OSPF区域0”,没写任何选举规划,结果一次设备更换后DR跑到了一台接入设备上,网段流量全部绕行,查了两天才定位到原因。从那以后,我的交付文档里每个多路访问网段都有一张角色表,谁当DR、谁当BDR、优先级多少、Router ID多少,一目了然。
最后分享一个小技巧:如果你不确定某次选举会是什么结果,可以在实验环境里用三台虚拟路由器搭同样的拓扑,把优先级和Router ID配成和生产一致,先跑一遍。选举规则是确定性的,实验环境的结果和生产环境不会有偏差,这比在生产网上反复clear进程稳妥得多。