我计划将大量网站(大约 100 个)迁移到新服务器,目前正处于迁移规划过程中。
每个网站的典型 DNS 区域都有两个指向 Web 服务器 IP 的 A 记录,一个用于主域example.com
,一个用于www
子域。
当我们全部设置完毕并准备好将新服务器投入生产时,更改 100x2 DNS 记录将非常耗时,因此我正在寻找一种方法来加快这一过程。在一些情况下,我读到有关创建一个 bash 脚本来迭代 DNS 记录并使用新 IP 执行查找替换的建议。在其他主题中,我读到有关添加带有新 IP 的 A 记录的建议,这样当当前服务器不再可用时,DNS 服务器会将请求指向下一个包含新 IP 的记录。
除此之外,是否有任何情况我可以用其他类型的 DNS 条目(即主机名)替换 A 记录,以便到时候我只需将主机名的 IP 更改为新 IP,并让所有网站指向新服务器?我确信“主机名”不是正确的术语,但我希望你们都明白我的意思。
答案1
您要查找的术语是别名记录,你的问题的答案既是肯定的,也是否定的。
首先,这里有一个关于 CNAME 如何在区域文件中工作的示例。
example.se IN SOA ns1.example.se. hostmaster.example.se. (
[....]
)
server1 A 10.1.2.3
www CNAME server1
现在您只需更新记录server1
即可将server1
和移动www
到新的 IP 地址。
CNAME 不必指向同一域内的地址;它也可以如下所示:
example.se IN SOA ns1.example.se. hostmaster.example.se. (
[....]
)
www CNAME server1.example.org.
server1
现在,当您更新区域中的A 记录时example.org
,的记录www.example.se
将随之更新,无需任何进一步的配置。
从您的角度来看,不好的部分是,这不适用于顶点记录 - 即“裸”域。换句话说,您可以将其变成www.example.com
CNAME,但不能将其变成 CNAME example.com
。这是因为当您使用 CNAME 记录时,您不能为该条目添加任何其他记录 - 这意味着您不能拥有邮件服务器记录或名称服务器记录......这意味着该域将停止工作。
最佳实践解决方案是使用某种配置管理软件(例如 puppet、chef 或 ansible)从模板生成区域文件。如果出于某种原因您无法做到这一点,那么我会使用脚本替换所有文件中的 IP 地址。
您还需要在迁移之前及时降低域的 TTL 值。(并且不要忘记更新区域文件的序列号 - 我已经更新了,这很尴尬......)
答案2
首先,答案取决于您的 DNS 是如何实现的。您是使用 bind、unbound 还是其他各种 DNS 服务器进行自托管?您的 DNS 服务器是使用文本文件进行配置,还是使用 GUI 界面(例如 Windows 服务器),还是使用脚本 API(例如 PowerShell),还是使用 Web 界面(如果您外包 DNS,则很常见)。外包 DNS 有时也有一个 REST API 可供您使用。
您可能希望使用脚本 API 进行更新,或者编辑文本文件,因为两者都可以轻松实现自动化。如果是文本文件,您甚至可以提前准备好,然后在进行迁移时将其复制到位。
顺便说一句,在你们的规模上进行这种类型的改变是为什么现在许多人都在使用 Chef、Ansible、Puppet、Salt 等 DevOps 工具……显然,这些都是需要规划的大型工具,所以这不会对这个特定需求有直接的帮助,但从长远来看,它可能会让你的生活更轻松。
其他一些重要注意事项:
检查您的 TTL。在迁移前大约一天或一周,将 TTL 更改为尽可能短的 TTL。迁移完成后增加 TTL。
不要忘记在 SOA 记录中增加序列号!API 和 Web 界面可能会自动为您执行此操作,也可能不会。如果您的 DNS 服务器使用文本文件,则必须记住执行此操作。
根据服务器的性质,看看是否可以同时运行新旧版本一段时间。如果可以,您可能不必一次完成所有 DNS 更新。
答案3
如果我理解正确的话,旧服务器只有一个 IP 地址,新服务器也只有一个 IP 地址。
因此,您可以做的是设置新服务器,并在其上将所有相关的 http/https/ftp/whatever 流量路由到旧 IP,然后更新 DNS 记录以显示新 IP。
如果您只有一个 IP,您可以使用简单的查找/替换一次性更改 DNS 中的所有 IP(不要忘记更新序列号),然后等待当前 TTL 用完。TTL 用完后,您只需删除新服务器上的路由并调整其他设置,这样它就可以直接为网站提供服务,而不是重定向。
在删除路由之前,网站显然应该已经移至新位置。这样做的好处是您不必依赖其他 DNS 服务器及时更新其记录,您只需“等待”即可。要缩短该时间,您可以减少 TTL,但请注意,有些 DNS 缓存会忽略 TTL 设置,这就是我不再依赖 TTL 的原因。
编辑/进一步解释: 为了使其更容易理解:
您也可以立即安装新服务器,配置一切并将所有站点移动到新 IP,然后将所有流量从旧服务器路由到新服务器。
例如,您的旧服务器有 IP,192.0.2.1
您的新服务器有 IP198.51.100.2
您的 DNS 指向192.0.2.1
所有站点(?),并且网络服务器根据请求的域名决定提供哪些内容,例如example.com
->/var/www/sites/example.com
和www.example.com
-> /var/www/sites/example.com
。
所以你只要把这个:
example.com -> 192.0.2.1
进入这个(一旦你将站点移动到198.51.100.2):
example.com -> 192.0.2.1 -> 198.51.100.2
然后将 DNS 记录更改为指向 198.51.100.2:
example.com -> 198.51.100.2
DNS 的问题在于更新永远不是即时的,所以对于某些客户端来说,example.com 仍会在一段可变的时间内指向 198.51.100.2(无论是您设置的 TTL,还是如果他们忽略它,谁知道会持续多长时间)。
所以我的观点是:不要依赖 DNS,而是在 IP 层重定向流量,这样可以减少停机时间。我希望这能让你更清楚一点。
在 Ubuntu 上,您可以使用转发和 NAT 来实现(例如,将旧目的地 198.51.100.2 的 http 和 https 路由到新目的地 198.51.100.2;这些设置在您的旧服务器上完成):
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -p tcp --dport 80 -m state --state NEW -j ACCEPT
iptables -A FORWARD -p tcp --dport 443 -m state --state NEW -j ACCEPT
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 198.51.100.2:80
iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to-destination 198.51.100.2:443
iptables -t nat -A POSTROUTING -j MASQUERADE
答案4
一个快速的解决方案(不是最优雅的,但可能有效)就是用简单的查找替换将旧 ip 替换为新 ip。
首先备份区域文件。
然后检查问题:
grep 'ol\.d\.i\.p' *.zone
检查是否有任何行不是您要替换的记录
接下来替换ip:
sed -i 's/ol\.d\.i\.p/ne.w.i.p/g' *.zone
grep 'ne\.w\.i\.p' *.zone # check if the new lines look correct
您不应该在每天运行的脚本中执行此操作,但对于一次性迁移,这可能足以解决问题,而无需开始编写复杂的迁移工具。
- 该
grep
命令仅搜索包含正则表达式的行(此处:ip 的文字匹配,需要.
转义,因为它们在正则表达式中具有特殊含义)。 sed
用于对流或文件进行基于行的操作(使用选项-i
)。用替换项(新 ip)s/regex/replacement/g
替换正则表达式(与命令中使用的相同)。表示全局,如果一行上有多个匹配项,则确保 ip 被替换多次。grep
/g