本地服务器通过专用地址能访问 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 软件,以及查询量是否撑得起一个按终结点和按查询计费的托管资源。

QuestionManaged inbound endpointForwarder VM
Software to patchNoneThe DNS service on every instance
Address stabilityFixed for the resource lifetimeTied to the VM or its reserved address
Availability workHandled by the serviceSecond instance, health checks, failover
Extra logicLimited to resolver featuresWhatever the DNS software supports

无论最后是哪一行决定,本地转发规则看起来都一样。这部分在两种设计里都必须存在,也是最常被漏掉的一环——当有人报告 Azure 内部能解析、办公室却不能时,缺的通常就是它。

按顺序检查路径

确认区域已链接到承载解析器的 VNet,并确认本地转发器写的是命名空间而不是父域。为 corp.example 建的转发器不会匹配 cloud.corp.example,除非解析器自己再做委派;这种不匹配会产生一个干净的否定应答,看起来就像记录缺失。

接着确认查询能到达终结点:本地源需要到解析器地址的路由和回程路径,在策略允许的地方应同时放行 UDP 和 TCP 的 53 端口。NSG 补不出缺失的区域记录,正确的区域也答不了一个根本到不了的查询。

排障时把请求的 FQDN 和所选解析器放在一起,并把超时和否定应答区分开。超时是路径或策略问题;否定应答说明查询到了,但命名空间没对上。工作顺序是:链接区域、添加条件转发器、双向放行 53 端口、从本地测一个名字,最后才去看应用自身的授权。

相关文章