我已将 DHCP 服务器配置为提供两台名称服务器以实现冗余,这样,如果其中一台离线,则可以使用另一台。
我已经配置了我的电脑,systemd-resolved
并根据resolvectl status
它获取了所有 DNS 服务器(两者的 IPv4 和 IPv6 地址),并使用其中一台作为当前服务器。
但是,如果 DNS 服务器离线,systemd-resolved
则不会切换到下一台服务器,而是继续尝试连接到离线服务器,从而导致所有未缓存的名称解析失败。
如果我运行systemctl restart systemd-resolved
,它将切换到另一台服务器并继续工作,但一段时间后它会随机切换回离线服务器,并且名称解析将再次失败。
我怎样才能systemd-resolved
停止使用离线 DNS 服务器并快速切换到它知道的其他服务器之一?
Journalctl 仅在切换到使用离线服务器时显示此信息:
systemd-resolved[1985]: Using degraded feature set (UDP) for DNS server fdxx::x.
systemd-resolved[1985]: Using degraded feature set (TCP) for DNS server fdxx::x.
发生这种情况时,相关服务器完全离线并且不响应 ping。
答案1
DNS 专业人士早就知道,如果您希望在任何网络中实现 DNS 服务弹性,则不能将这一决定留给客户端实施。
这是一个非常重要的决定,不能让客户的解析器实现来做出。
虽然理论上客户端应该在第一个 DNS 失败时退回到第二个 DNS,但由于多种原因,这种情况通常不会发生。在我的职业生涯中的这些年里,我看到了完整网络中的巨大失败,人们依赖客户端操作系统解析器足够智能来实现事物。
实际上,您通常所做的就是根名称服务器正在做的事情,即创建 DNS 集群来接管 DNS 服务器的虚拟 IP 地址。最常用的技术是 DNS 选播。您还可以尝试更简单的架构,例如使用 keepdalived。
然而,无论你做什么,我强调不要把决定权留给客户。
传统的保护措施是为给定站点建立多个 DNS 服务器。网络上的每个 DNS 客户端都配置有每个服务器的 IP 地址。所有这些服务器发生灾难性故障的可能性相当小,因此您有一定的安全边际。
另一方面,许多存根解析器只需要两个 DNS 服务器,这使得 DNS 拓扑中几乎不可能出现任何有意义的地理分散。 DNS 存根解析器通常专门使用两个配置的 DNS 服务器中的第一个。因此,您最终会得到一台服务器承担整个查询负载,而另一台服务器闲置,等待故障。虽然不是最优的,但是嘿,这就是冗余的代价……对吧?不一定是这样。
DNS 冗余和故障转移是选播的典型用例。任播是一种获取一个 IP 地址并在多个服务器之间共享该地址的概念,每个服务器都不知道其他服务器。 DNS 根名称服务器广泛使用选播。
附言。过去,我在两家 ISP 和一所大学中使用 iBGP 和 OSPF 实施了任播 DNS,显着提高了 DNS 服务的正常运行时间可用性。
答案2
通过 DHCP 使用多个名称服务器是为了实现弹性,而不是冗余。看来您正在尝试使用多个名称服务器,因为每个客户端都会跟踪名称服务器是否变得无响应,并停止使用它。如果您确实想要这种类型的行为/设计,那么您需要通过 DNS 服务器本身来利用它,DNS 客户端通常无法完成此操作。您在这里经常看到的方法是使您的 DNS 服务器相对于其解析的上游 DNS 服务器而言具有 HA(高可用性)。
要说明为什么这不起作用,请查看该/etc/resolv.conf
文件的工作原理。将多个名称服务器添加到 DHCP 将为每个客户端在其/etc/resolv.conf
文件中提供 2 个条目。该文件只能提供以下处理多个名称服务器的机制:
nameserver Name server IP address Internet address of a name server that the resolver should query, either an IPv4 address (in dot notation), or an IPv6 address in colon (and possibly dot) notation as per RFC 2373. Up to MAXNS (currently 3, see <resolv.h>) name servers may be listed, one per keyword. If there are multiple servers, the resolver library queries them in the order listed. If no nameserver entries are present, the default is to use the name server on the local machine. (The algorithm used is to try a name server, and if the query times out, try the next, until out of name servers, then repeat trying all the name servers until a maximum number of retries are made.)
这句话说的是:
如果有多个服务器,解析器库将按列出的顺序查询它们。
解析器不会执行任何操作来管理此列表,它会盲目地继续使用该列表,每次都从第一个条目开始,然后是第二个条目,依此类推。您可以做的唯一控制它的事情是更改timeout
,retries
和rotate
。
超时:n
设置解析器在通过不同名称服务器重试查询之前等待远程名称服务器响应的时间。以
秒为单位,默认值为 RES_TIMEOUT(当前为 5,请参阅 )。此选项的值默认上限为 30。尝试次数:n
设置解析器在放弃并向调用应用程序返回错误之前向其名称服务器发送查询的次数。默认值为 RES_DFLRETRY(当前为 2,请参阅 )。此选项的值默认上限为 5。
旋转
在 _res.options 中设置 RES_ROTATE,这会导致从列出的名称服务器中循环选择名称服务器。这具有在所有列出的服务器之间分散查询负载的效果
,而不是让所有客户端每次都首先尝试第一个列出的服务器。