Azure UDR 到 VPN 网关:一个目的地,而不是所有出口
把一条 Azure 前缀指向 VPN 网关,而不搬动全部出口流量。先读有效路由,绑定工作负载子网,再把回程路径补齐。
你为一个外部前缀添加用户定义路由,把它指向 VPN 网关,流量却仍然从 Azure 的互联网路径出去。或者它正确地出去了,而回应再也回不来。两种结果都来自同一个错误:把 Azure 的下一跳当成整个设计。路由表只决定数据包在 Azure 内部走哪个出口。隧道之后它遇到什么、回应如何返回,是你要补上的后半部分。
下一跳是网关,不是设备的 IP
UDR 把匹配的前缀发给一个下一跳类型,而 VirtualNetworkGateway 是类型,不是地址。人们把网关的专用 IP 粘贴进 VirtualAppliance 路由,然后奇怪为什么匹配不上,因为那个类型期望的是网卡或内部负载均衡器。微软的路由文档也把网关下一跳限制在网关本身是 VPN 网关的虚拟网络。ExpressRoute、Route Server 和 Virtual WAN 中心不能用这个选项寻址。
写路由之前,先确认虚拟网络到底有什么。如果设计经由中心路由,这条路由属于中心的负责团队,而不是你正在编辑的 spoke。
修改任何东西之前,先读有效路由
Azure 把系统路由、BGP 学到的前缀和 UDR 合并成每块网卡的有效路由表,最长匹配前缀胜出,不管它来自哪里。同一前缀下,UDR 胜过 BGP 路由。正是这个顺序,让早先实验中遗留的过期 UDR 能悄悄覆盖你刚刚通过隧道学到的前缀。
先看有效路由表,再决定是新增还是替换一条路由:
az network nic show-effective-route-table \
--resource-group rg-net --name vm-web-nic -o table除了前缀,也要读来源列。前缀正确而来源错误的路由,告诉你该改哪个对象,也让你避免再加一条会输给它的路由。
按真实前缀和子网写路由
使用实际要访问的服务提供的真实前缀,而不是从论坛帖子里抄来的公网段。在考虑把全部出口都搬走的默认路由之前,先从一项获批的服务开始。然后把路由表关联到工作负载的子网。网关子网有自己的要求,把你的表关联到那里会弄坏网关,而不是引导工作负载。
创建路由,然后把路由表绑定到承载工作负载的子网:
az network route-table route create --resource-group rg-net --route-table-name rt-egress \
--name to-partner --address-prefix 203.0.113.0/24 --next-hop-type VirtualNetworkGateway
az network vnet subnet update --resource-group rg-net --vnet-name vnet-app \
--name snet-web --route-table rt-egress传播也很重要。在那个路由表上启用 BGP 传播后,学到的前缀会和你写的并列出现,更具体的学习前缀可能打败更宽的 UDR。只有当你希望这组 UDR 对该子网具有权威性时,才关闭传播。
把本地那一半做完,否则流在那里就断了
本地网关必须接受 Azure 源地址、把它转发到目标,并允许该应用。它的后续路径可能是互联网出口或另一个专用跳点,但这个决定属于方案,不属于 Azure 路由表。常见的失败是回程。互联网目标不会把 Azure 专用源地址路由回你,于是回应走它自己的默认网关然后消失,或者根本出不去。
两种设计都能解决,它们不能互换。 在出口转换源地址 这样目标会回复本地网络拥有的公网地址。或者保留源地址,建立经过路由的返回关系,让回应沿隧道回来。选一种,并写下应用会看到哪个地址。
选择器和允许列表与这些是分开的。选一个 Azure 下一跳不会放宽 VPN 流量选择器,也不会改变外部服务的源地址允许列表。
用目标实际观察到的源地址验证
从真实工作负载发请求,而不是从另一个子网的跳板机发,然后读目标观察到的源地址。这一个值就能告诉你两种回程设计里哪一种是生效的。接着检查回应路径,并确认到虚拟机的普通管理流量还能用,因为误加的默认路由会先表现为 SSH 会话断掉,很久之后才表现为应用坏掉。
经由选定前缀的转发比强制隧道窄得多。保持窄,回滚就是删掉一条路由。