美国的工作负载通过 HA VPN 顺利到达办公网段,而同一 VPC 内的欧洲工作负载却完全不通。它的路由表中没有该网段的条目,没有隧道中断,也没有防火墙规则变更。隧道及其 BGP 会话双向正常。VPC 跨区域并不等于它学到的路由也跨区域,这个差别解释了全部现象。

这里混淆了两个属性:子网位于何处,以及学到的下一跳可以在何处使用。

区域范围从何而来

Cloud Router 按 VPC 的动态路由模式来决定学到路由的作用范围。在 regional 模式下,某个区域学到的路由只能被该区域的资源使用,所以欧洲的路由表是空的,而不是显示一条坏掉的下一跳。在 global 模式下,符合条件的学习路由会对 VPC 内所有区域的资源可用。改之前先读取当前值,因为默认是 regional。这个设置属于网络,不在隧道上,也不在路由器上。

这条查询命令是只读的,一行就能给出答案:

gcloud compute networks describe VPC_NAME --format='value(routingConfig.routingMode)'

VPC 是共享的时候,要在宿主项目中执行。网络属于那个项目,工作负载项目里的查看者角色可能连路由配置都看不到。从错误的项目拿到的快速答案,比没有答案更糟。

变更是一条命令和一个方向

切换是整个 VPC 的控制面改动,不是针对单台 VM 的绕行办法:gcloud compute networks update VPC_NAME --routing-mode=GLOBAL。它也是单向的,因为设为 global 的网络无法再回到 regional。执行前再核对一次项目和网络名称,因为这条命令不会请求确认。这个改动值得一条维护记录和网络负责人的批准,而不是在共享 VPC 上做快速试验。

该网络中的每个 Cloud Router、VPN 和 Interconnect 连接都会同时继承新的范围。这包括变更申请里没人提到的那些连接。以前从未有该路由的区域会在改动生效的那一刻开始收到它,所以这个切换没有分阶段发布。

全局是范围,不是保证

资格与优先级和范围是两回事。与更具体的网段冲突、在最优路径选择中落败或被策略过滤的路由,行为与之前完全一样。global 模式扩大的是路由可以在哪里使用,并不决定哪条路由胜出。学到的路由可以在范围内,却仍然输给同一 VPC 内的静态路由或更具体的路径。

这个区别很重要,因为日后很容易把问题归咎于模式改动。如果切换后欧洲子网仍然没有路由,问题在于路由是否存在、是否有资格,而不是范围是否生效。前缀冲突和下一跳健康是接下来要读的两件事。

对端的宣告方式也不同

宣告行为遵循同一设置。默认行为下,regional 模式的路由器宣告自己所在区域的子网,而 global 模式会更广泛地宣告 VPC 的子网。因此改变模式不只改变你自己的区域能用什么,也改变对端会安装什么。

自定义宣告列表不会随模式改变而扩大。如果本地路由器持有手写的网段列表,欧洲网段依旧不在其中。那种情况下回程依旧不通,即使去程路由已经存在。要检查对端安装了什么,而不是你导出了什么。

模式永远修不好的东西

全局路由不会提供公网访问、不会打通无关 VPC 之间的互通,也不会补上缺失的静态路由。它不改变防火墙规则或 IAM,所以被策略拒绝的连接依旧被拒绝。

这些故障从工作负载内部看起来一样,和路由范围毫无关系。

从远端区域测试到真实服务,然后确认回复确实从预期的隧道返回。记录模式、宣告配置和你测试的目标。如果测试仍然失败,再次改动模式之前,先比较远端路由器的 BGP 表和 VPC 路由列表。这样下一次跨区域报告就从事实出发,而不是从模式改动出发。

相关文章