ExpressRoute 加 VPN:你覆盖了哪些故障域?
第二条 IPsec 隧道只覆盖一个端点,而不是它下面的线路。先把每个故障域测算清楚,再决定是否允许未加密的回退路径。
在 ExpressRoute 专用对等互连上运行的 IPsec 隧道,只是为原本就存在的传输增加了加密。第二条隧道提升的是端点可用性,对两条隧道下方的运营商路径没有任何帮助。当仪表板显示两条绿色隧道、而设计评审问出另一个问题时,这个区别很容易被丢掉:这条连接必须扛住哪些故障?先回答这个问题,再统计隧道数量,因为绿色指示灯的数量是加密层的属性,而故障域的数量才是整条路径的属性。
从故障开始,而不是从绿色隧道开始
在画任何图之前,先写下四行:一个 VPN 端点或对等实例失效、一个本地路由器或首公里连接失效、共享的 ExpressRoute 路径失效,以及专用对等互连仍在承载流量时 IPsec 变得不可用。每一行都点明设计必须保住什么,而每一行都由不同的机制来回答。
| Failure | What must survive | What does not cover it |
|---|---|---|
| One VPN endpoint or instance | An alternate encryption endpoint and a route to it | A second tunnel terminating on the same instance |
| One local router or first mile | Independent local equipment and transport reachability | Any number of logical tunnels |
| The ExpressRoute path | A separately designed surviving underlay | An IPsec tunnel layered on the same circuit |
| IPsec unavailable, peering up | The intended encrypted-only or approved fallback policy | Assuming the tunnel is the only route |
Microsoft 记录了经 ExpressRoute 专用对等互连的专用 IP 站点到站点 VPN,以及与基于互联网的站点到站点连接所支持的共存。那种共存是另一种底层设计,并不会仅仅因为你又加了一个专用隧道端点就出现。
故障域 1:VPN 端点
一个网关上的两条隧道通常是终止在同一个 Azure 侧资源上的 active-active 配对。它们防的是单条隧道或单个实例出问题,防不了该资源变得不可用、被重新配置或容量耗尽。端点冗余意味着第二个受支持的端点,有它自己的路径和自己的配置,并且有一条能到达它的路由。
检查你实际部署了什么,而不是图里画了什么,因为门户对这些资源的分组方式会掩盖它们之间的关系:
az network vpn-connection show -g rg-connectivity -n vpn-to-hub --query '{conn:connectionStatus,tunnels:tunnelConnectionStatus}'
az network vnet-gateway show -g rg-connectivity -n gw-hub --query '{sku:sku.name,activeActive:enableBgp,peers:bgpSettings.peers}'
如果两条隧道都指向同一个带单个公网 IP 的网关,你拥有的是一种特定而有限的端点冗余。这可能正是需求所要求的,那就应该这样写清楚,而不是把它描述成一条冗余连接。
故障域 2:本地路径与运营商
加密之下是物理和商业现实:客户侧边缘设备、交叉连接、运营商网络和对等互连点。ExpressRoute 可用性指南明确指出,端到端冗余包含客户段和服务提供商段,而不只是 Microsoft 侧。两条共享同一台路由器、同一路供电或同一条首公里连接的逻辑路径,仍然共享着这份依赖。
设计通常就是在这一步过不了诚实的评审。来自同一运营商的两条线路、终止在同一栋楼、跑在同一批采购订单的设备上,并不是两个故障域。它们是一个故障域,两张账单。
把运营商问题写下来:这些路径中哪些在哪里分叉,共享段故障时有文档化的行为是什么?设计电话会上的口头保证,扛不住你正在为之设计的那次故障。
故障域 3:不经 IPsec 也能存活的路由
专用对等互连与 IPsec 可能为同一个应用程序前缀提供互相竞争的路由。如果受保护的路由消失,留下来的直接 ExpressRoute 路由也许仍然可用,只是没有隧道原本提供的加密层。这是否可接受属于策略决定,而它恰恰是最常被隐含掉的那个决定。
加密要求和可用性要求在这里可能真的冲突。「任何留下来的路由都算成功」是一句可用性陈述,它悄悄用「否」回答了加密问题。写清楚哪一个优先、针对哪些前缀、由谁批准。
az network vnet-gateway list-advertised-routes -g rg-connectivity -n gw-hub --peer 10.0.0.1
az network vnet-gateway list-learned-routes -g rg-connectivity -n gw-hub -o table
把学到的路由与你预期的前缀做对比。一条承载少量管理负载的回退路径,对那份负载也许完全够用,却离生产需求所需的容量差得很远,所以把容量假设与路由一起记录下来。
记录三行,而不是一个结论
把端点冗余、传输冗余和灾难恢复作为设计记录中彼此独立的条目,各自有各自的机制、各自的验证和各自的负责人。当事故复盘追问为什么连接扛住了网关重启却没扛住光纤切断时,三行能在一句话里答完;一个「冗余」勾选框做不到。
然后测试那些可以便宜地测试的行。让一条隧道失效,确认流量确实迁移并重新加密。撤回一条路由,确认留下来的正是你想要的那条,再确认它是否仍然加密。把你无法模拟的故障记录下来,因为未经测试的行只是假设,就应该按假设标注。
有用的产出是一张短表和每行一句话。如果某一行没有机制,那本身就是发现,而在设计评审里发现它,比在两条隧道本来都扛不住的运营商故障中发现要便宜得多。