Google Cloud DNS 更改记录资源更新时间

Google Cloud DNS changing Record Resource update time

我目前正在尝试使用 Google Cloud DNS 将具有临时 IP 的 Compute Engine VM 映射到主机名,此操作在 VM 启动时进行。我通过 shell 脚本执行此操作,如下所示:

gcloud dns record-sets transaction start -z=MY_ZONE
gcloud dns record-sets transaction remove --zone MY_ZONE \
    --name subd.domain.com \
    --type A "1.2.3.4" \ #the old external ip for the VM
    --ttl 300
gcloud dns record-sets transaction add --zone MY_ZONE \
    --name subd.domain.com \
    --type A "5.6.7.8" \ #the new external ip for the VM
    --ttl 300
gcloud dns record-sets transaction execute -z=MY_ZONE

在脚本 运行 之后,我可以看到 Cloud DNS UI 中的记录已成功更改,"A" RR 具有新的外部 IP。

现在的情况是,这些更改需要很长时间才能真正生效。在更改 returns 后访问主机名 "subd.domain.com" 一个持续很长时间的 "NXDOMAIN" 状态,只有在那之后它才最终将域映射到新 IP。

这种情况给我提出了两个问题:

#1为什么DNS要经过NXDOMAIN阶段?这些更改不应该作为 Update(由于 运行 在交易中进行此操作)而不是作为 Remove 然后 Create.

#2 什么决定了这次记录更新上线的时间?

我将根据几十年的 DNS 经验提出这个建议。不要将 DNS 视为您的按需数据库。 DNS 生态系统并非旨在支持您尝试做的事情。链中的每个 link 缓存 DNS 条目。您无法控制此过程。在您的示例中,您的 TTL 是 300 秒。在您上面的下一个服务器使您的条目过期之前,至少需要 5 分钟。许多缓存会忽略您的 TTL,并将其设置为数小时甚至数天。您需要将 DNS 设置设计为 "eventually consistent" 而不是 "instantly consistent"。最终意味着几小时或几天。

在规划 DNS 更改时,我计划至少 48 小时让更改生效。这意味着我们在旧 DNS 条目上维护服务,同时新 DNS 条目生效。

DNS 更改以几种不同的方式传播(传播)。这些不同的方式随着 DNS 的发展而发展,可以在各种 RFC (https://www.isc.org/community/rfcs/dns/) 中找到。

在您的示例中,您试图更改 "domain.com" DNS 区域中资源的 A 记录(IP 地址映射到名称)。您显示的方法首先删除旧记录,然后使用 "transaction" 添加新记录。使用 "transaction" 的风格是 Google 的云 DNS 产品所特有的,不是文档化的 RFC 的一部分,并且可能(也可能不会)影响成功解析完成的速度。 (旁注,一个事务,即使它包含多个 DNS 更改,在我的测试中也只会将 SOA 序列增加 1)

首先,让我简单回顾一下技术。

有几台服务器充当该区域 (domain.com) 记录的 "authoritative" 源。那些具有权威性的服务器是在该区域的 NS 记录中列出的服务器。这些是当有人在浏览器中尝试浏览该名称或有人试图对其进行 ping 等时将响应请求的服务器。当有人 ping 或有人试图在浏览器中访问这些服务器时,访问这些服务器的方式是高度可变的超出此答案(google for "client DNS resolution")

通常,Google Cloud DNS 将为您提供四个权威服务器,其名称类似于任何新创建的区域:

  • ns-cloud-a1.googledomains.com
  • ns-cloud-a2.googledomains.com
  • ns-cloud-a3.googledomains.com
  • ns-cloud-a4.googledomains.com

DNS 名称查询实用程序,例如 "dig" 或 "nslookup" 可用于单独查询每个权威服务器的状态。

现在,当您 运行 "gcloud dns ..." 命令删除 and/or 添加记录时,它没有使用记录的 DNS 方法来促进将记录传输到所有权威服务器。从我的测试中我能知道的最好的是它首先用你的更改更新一些中央数据库,然后启动一个过程来更新(可能使用 DNS 样式通知?)服务器本身。这可以从 Google Cloud DNS UI 有时能够在任何权威服务器实际注册您的交易更改之前显示您的更新这一事实看出。

接下来,由于更改是由一组权威服务器发送 and/or 拉取的,因此似乎需要一段时间才能在每台服务器上完全一致。 (Zach Bjornson 在 http://blog.zachbjornson.com/2018/08/14/dns-propagation.html 发布了使用 GCP 和 AWS 收敛 DNS 记录添加时间的分析,以及自己执行分析的代码。)

他的一张图表显示了达到一致性的时间: Time for GCP DNS Servers to Update

虽然上面列出的四台服务器 (ns-cloud-xxx...) 中的每一台都只有一个 IP 地址,但它们是任播 IP,这意味着它们可以存在于多个数据中心的多个网络中。因此,虽然 ns-cloud-a1.googledomains.com 解析为 216.239.32.106,但该 IP 可能存在于迈阿密、坦帕、奥兰多、亚特兰大和其他几个位置的服务器上。当您尝试与它通信时,您的流所经过的网络会将您带到最近的网络(感谢@BGP!)。在我的测试中(运行ning 每秒针对每个已发布的 googledomains.com 域名服务器挖掘 20 次 运行ning 与您发布的事务类似的事务),似乎更改慢慢地收敛,也就是说前几秒是旧IP(被删除的那个),然后dig requests开始显示变了但可能只有一个每 40 或 50 个显示新 IP 的请求。在接下来的一分钟左右,返回新 IP 的频率越来越高,直到 100% 的请求都显示新 IP。

在我的有限测试中,我从未收到测试记录的 NXDOMAIN,所有(几千个)请求都为请求的记录返回了旧 IP 或新 IP。

至此,所有的权威服务器都已经收敛到"subd.domain.com"的A记录的新IP地址。 DNS 解析器或客户端可能有某种本地缓存,用于最大限度地减少对频繁请求的记录的网络请求。其中一些客户端会遵守所请求记录的 TTL (time-to-live),但有些可能不会(恕我直言,我没有看到与实现的一致性)。 TTL 是一个 "suggestion",请求记录的人可以遵循该 TTL,以确保他们在最小化网络流量和确保记录值的准确性之间取得良好的平衡。所以,现在,客户端可能为 TTL 缓存了旧记录,因此它可能需要在尝试再次请求记录之前过期。在您的示例中,300 的 TTL 是 300 秒,即 5 分钟,因此您最多可以等待 5 分钟。