Azure 私有 DNS 走 VPN:托管的入站终结点还是转发器
两种设计都能通过隧道应答专用区域。请比较托管的入站终结点与转发器虚拟机,然后检查两种方案都必须存在的路径。
本地服务器通过专用地址能访问 Azure 虚拟机,却仍解析不了它的专用主机名,于是人们开始怀疑隧道出了问题。隧道没问题。缺的是 DNS 边界:本地一侧没人知道某个 Azure 专用区域应该由 VNet 内的解析器来应答。两种设计都能补上这个缺口,区别只在于你最终要运维什么,而不在于查询能不能通。
隧道只承载查询,不承载区域知识
站点到站点连接只是给数据包一条跨两条网络的路由。它不会告诉本地 DNS 服务器哪个命名空间属于 Azure、哪个地址应该负责应答,所以查询要么走到公网再空手而归,要么根本出不了本地解析器。
修法分成两半,界限很清楚。一半是 VNet 内的解析器,负责接收经隧道到达的查询。另一半是本地一侧的条件转发器,把恰好一个命名空间交给那个解析器。少任何一半都不成立。
后文假定区域是 cloud.corp.example,所有地址都只作示例。
方案 A:托管的入站终结点
Azure DNS Private Resolver 提供入站终结点,用来接收来自 VNet 之外的 DNS 查询。把它部署到专用的委派子网,把专用区域链接到该 VNet,再记下服务分配的入站地址。
然后在本地 DNS 服务器上,为这个确切的命名空间建一条指向该地址的条件转发器:
Namespace: cloud.corp.example
Forward to: 10.20.2.4
微软的混合 DNS 流程同时写明了区域链接和转发器步骤。走托管这条路,没有需要打补丁的 DNS 软件,终结点地址在整个资源生命周期内保持稳定。
代价是你多了一个解析器资源、它的子网委派和相应费用,即使查询量很小,这些也是实打实的。
方案 B:VNet 内自建转发器虚拟机
较早的做法是在 VNet 里一台普通虚拟机上跑 DNS 软件,比如 Windows DNS、BIND 或 dnsmasq,专用区域要么本地托管,要么转发给 168.63.129.16 上 Azure 提供的解析器。本地条件转发器指向那台虚拟机的专用地址。
对已经在运维 DNS 服务器的团队来说,这个方案很熟悉,也能承载日志、分离视图应答之类的额外逻辑。但它同时继承了 DNS 服务器的全部运维职责:打补丁、为可用性准备第二台实例、监控,以及虚拟机被替换、地址变化时的重建路径。
普通 VNet 主机在装好并允许应答之前并不是 DNS 代理,而这正是人们克隆虚拟机时最容易跳过的一步。
哪种更适合你的运维
比较的重点不是哪种更快,而是你到底想不想运维 DNS 软件,以及查询量是否撑得起一个按终结点和按查询计费的托管资源。
| Question | Managed inbound endpoint | Forwarder VM |
|---|---|---|
| Software to patch | None | The DNS service on every instance |
| Address stability | Fixed for the resource lifetime | Tied to the VM or its reserved address |
| Availability work | Handled by the service | Second instance, health checks, failover |
| Extra logic | Limited to resolver features | Whatever the DNS software supports |
无论最后是哪一行决定,本地转发规则看起来都一样。这部分在两种设计里都必须存在,也是最常被漏掉的一环——当有人报告 Azure 内部能解析、办公室却不能时,缺的通常就是它。
按顺序检查路径
确认区域已链接到承载解析器的 VNet,并确认本地转发器写的是命名空间而不是父域。为 corp.example 建的转发器不会匹配 cloud.corp.example,除非解析器自己再做委派;这种不匹配会产生一个干净的否定应答,看起来就像记录缺失。
接着确认查询能到达终结点:本地源需要到解析器地址的路由和回程路径,在策略允许的地方应同时放行 UDP 和 TCP 的 53 端口。NSG 补不出缺失的区域记录,正确的区域也答不了一个根本到不了的查询。
排障时把请求的 FQDN 和所选解析器放在一起,并把超时和否定应答区分开。超时是路径或策略问题;否定应答说明查询到了,但命名空间没对上。工作顺序是:链接区域、添加条件转发器、双向放行 53 端口、从本地测一个名字,最后才去看应用自身的授权。