冗余通过组件备份提升系统可用性,确保单点故障不影响服务;负载均衡将流量合理分配到多个资源,避免过载并优化性能,两者协同工作,共同实现系统的高可用性、可靠性与性能优化目标。
在 Linux 系统中配置多个 DNS 服务器地址是非常常见的做法,主要目的是为了提高域名解析的可靠性和性能,当你的系统拥有多个 DNS 服务器时,解析器(负责将域名转换为 IP 地址的组件)会遵循特定的规则来决定使用哪一个,以及当遇到问题时如何切换,理解这个过程对于排查网络问题和优化系统配置很有帮助。
- 冗余 (Redundancy): 这是最主要的原因,如果配置的第一个 DNS 服务器宕机、无响应或网络连接出现问题,系统可以自动尝试查询列表中的第二个、第三个服务器,确保域名解析服务不中断,提高网络连接的稳定性。
- 负载均衡 (Load Balancing): 在某种程度上,多个 DNS 服务器可以分担查询请求的压力,虽然解析器通常按顺序尝试,但某些配置或机制(如
options rotate
)可以引入基本的轮询,避免所有请求都压到第一个服务器上,尤其是在客户端数量众多时。 - 性能优化 (Performance): 不同的 DNS 服务器可能在地理位置、网络路径或缓存效率上存在差异,配置多个服务器(一个本地 ISP 的 DNS,一个公共 DNS 如 8.8.8.8,一个公司内网 DNS)可以让解析器有机会选择响应更快的服务器进行查询。
Linux 解析器如何工作:顺序尝试与故障转移
Linux 系统上处理 DNS 解析的核心组件是 glibc
库中的解析器例程(通常通过 /etc/nsswitch.conf
文件中的 hosts
行配置,最终指向 dns
),当应用程序(如浏览器、ping 命令)需要进行域名解析时,它会调用这些库函数。
解析器处理多个 DNS 服务器的基本策略是 “顺序尝试 + 快速故障转移”:
- 按配置顺序查询: 解析器严格按照
/etc/resolv.conf
文件中nameserver
行出现的顺序进行查询,它总是优先尝试列表中的第一个 DNS 服务器。 - 超时等待: 向第一个服务器发送查询请求后,解析器会等待一个设定的超时时间(通常是几秒钟,具体值可能因实现和配置略有不同),如果在这个时间内收到了有效的响应(无论是成功解析还是明确的域名不存在 NXDOMAIN),解析过程就结束了。
- 故障转移 (Failover): 如果第一个服务器在超时时间内没有响应(超时),或者返回了格式错误的响应,解析器会认为这次查询失败。
- 尝试下一个服务器: 一旦判定第一个服务器查询失败,解析器会立即转向列表中的第二个
nameserver
地址,发送相同的查询请求,并同样等待超时。 - 重复过程: 如果第二个服务器也超时或返回错误,解析器会继续尝试第三个,依此类推,直到列表中的所有服务器都尝试完毕。
- 最终失败: 如果所有配置的 DNS 服务器都尝试失败(超时或返回错误),解析器会向应用程序返回一个错误(如
Name or service not known
),表示域名解析失败。
重要特性与注意事项
- 无并行查询: 标准的
glibc
解析器在默认配置下不会同时向所有 DNS 服务器发起并行查询,它是严格串行的:先试第一个,失败了再试第二个,以此类推,这是为了减少不必要的网络流量和服务器负载。 - 缓存的作用: Linux 系统通常有 DNS 缓存机制(可能是
systemd-resolved
,dnsmasq
,nscd
或应用自身的缓存)。成功的解析结果会被缓存一段时间,在缓存有效期内,后续对同一域名的查询会直接从缓存中获取结果,完全不会去查询任何 DNS 服务器,这极大地提高了效率,缓存的存在使得“顺序尝试”的开销在大多数情况下并不显著。 options rotate
: 在传统的/etc/resolv.conf
配置中,有一个可选的options rotate
参数,如果设置了这个选项,解析器会在每次新的查询请求(指不在缓存中的请求)开始时,对nameserver
列表进行轮转 (rotate),第一次查询用 Server1, Server2, Server3;第二次查询用 Server2, Server3, Server1;第三次用 Server3, Server1, Server2,这实现了非常基础的负载均衡,避免所有客户端的首次查询都涌向第一个服务器,但请注意:- 这仍然是串行尝试(轮转后的第一个失败,再试轮转后的第二个)。
- 并非所有环境都默认启用或支持
rotate
。 - 现代缓存机制大大降低了轮转的必要性。
options attempts:n
: 可以设置解析器在放弃前对每个服务器的重试次数(默认为 2)。options attempts:1
表示每个服务器只试一次(超时即算失败),options attempts:3
表示每个服务器最多试 3 次(每次超时后重试)才标记为失败并尝试下一个服务器,这主要用于应对临时的网络抖动。- 现代解析器 (
systemd-resolved
): 许多现代 Linux 发行版(如 Ubuntu, Fedora, Debian 等)默认使用systemd-resolved
作为 DNS 解析管理器,它扮演一个本地缓存和转发代理的角色:- 应用程序查询
systemd-resolved
(通常监听在 127.0.0.53)。 systemd-resolved
管理着从网络接口(NetworkManager, systemd-networkd 等)获取的实际 DNS 服务器列表。systemd-resolved
自身实现了更智能的故障转移逻辑,它可能会更快地标记无响应的服务器为“降级”状态,并在一定时间内跳过它们,优先使用已知良好的服务器,它也可能支持更复杂的配置,如按域指定 DNS 服务器。/etc/resolv.conf
通常只是一个指向systemd-resolved
存根解析器 (127.0.0.53) 的符号链接,实际的服务器列表需要通过resolvectl
命令或网络配置工具(如nmcli
)查看和修改。systemd-resolved
支持 DNS-over-TLS (DoT) 等高级特性。
- 应用程序查询
如何配置多个 DNS 服务器
配置方法取决于你的网络管理方式:
- 图形界面 (NetworkManager):
- 在桌面环境的网络设置中,找到你连接的网络配置(有线/Wi-Fi)。
- 进入 IPv4/IPv6 设置选项卡。
- 将 “DNS” 字段设置为 “Automatic (Addresses Only)” 或 “Manual”。
- 在 “DNS Servers” 输入框中,按优先级顺序输入你想要的 DNS 服务器 IP 地址,用逗号分隔 (
8.8.8, 8.8.4.4, 1.1.1.1
),保存并重新连接网络。
- 命令行 (NetworkManager –
nmcli
):nmcli con mod "YourConnectionName" ipv4.dns "8.8.8.8 8.8.4.4 1.1.1.1" # 空格分隔 nmcli con mod "YourConnectionName" ipv4.ignore-auto-dns yes # 防止 DHCP 覆盖 nmcli con down "YourConnectionName" && nmcli con up "YourConnectionName" # 重启连接
- 命令行 (systemd-networkd): 编辑网络配置文件 (e.g.,
/etc/systemd/network/50-wired.network
):[Network] DNS=8.8.8.8 DNS=8.8.4.4 DNS=1.1.1.1
- 直接修改
/etc/resolv.conf
(不推荐,易被覆盖):- 仅适用于没有使用 NetworkManager 或 systemd-resolved 管理
/etc/resolv.conf
的简单系统,或者作为临时测试。 - 用 root 权限编辑
/etc/resolv.conf
。 - 添加或修改
nameserver
行,每行一个 IP 地址,按优先级从上到下排列:nameserver 192.168.1.1 # 本地路由器/网关 nameserver 8.8.8.8 # Google Public DNS nameserver 1.1.1.1 # Cloudflare DNS
- 可以添加
options rotate
或options attempts:2
等参数(如果需要)。 - 警告: 如果系统使用 DHCP 或 NetworkManager/systemd-resolved,这个文件很可能在下次网络事件(重启、重连)时被自动覆盖,优先使用网络管理工具配置。
- 仅适用于没有使用 NetworkManager 或 systemd-resolved 管理
查看当前生效的 DNS 服务器
- 查看
/etc/resolv.conf
(注意可能是存根):cat /etc/resolv.conf
- 使用
systemd-resolve
/resolvectl
(如果使用 systemd-resolved):resolvectl status # 或较旧系统 systemd-resolve --status
- 查看
Global
部分或特定接口(如Link 2 (enp0s3)
)下的DNS Servers
。
- 查看
- 使用
nmcli
:nmcli dev show | grep DNS
最佳实践与建议
- 优先使用本地网关/路由器: 通常将本地网络的路由器 IP (如
168.1.1
) 作为第一个 DNS 服务器,它通常响应最快,能解析本地网络名称(如打印机、NAS),并且可能缓存了公共查询结果。 - 添加可靠的公共 DNS 作为备份: 将像 Google (
8.8.8
,8.4.4
)、Cloudflare (1.1.1
,0.0.1
)、Quad9 (9.9.9
) 这样的知名公共 DNS 服务器作为第二、第三选择,它们提供高可靠性和全球覆盖。 - 数量适中: 通常配置 2-3 个 DNS 服务器就足够了,配置过多会增加不必要的复杂性和潜在的解析延迟(需要尝试更多服务器才能失败)。
- 理解你的解析器: 了解你的系统是使用传统的
glibc
解析器(直接读/etc/resolv.conf
)还是systemd-resolved
/dnsmasq
等缓存代理,这影响故障转移行为和配置方式。 - 利用缓存: 确保 DNS 缓存服务(如
systemd-resolved
)正常运行,缓存是提升解析速度和减少对上游服务器依赖的关键。 - 考虑隐私与安全: 公共 DNS 提供商通常提供 DNS-over-TLS (DoT) 或 DNS-over-HTTPS (DoH) 选项(如
systemd-resolved
支持配置 DoT),这可以加密你的 DNS 查询,防止窃听和篡改,如果隐私是首要考虑,优先选择支持加密且承诺不记录查询日志的提供商(如 Cloudflare, Quad9)。
Linux 系统配置多个 DNS 服务器主要是为了实现冗余,确保当首选服务器不可用时,域名解析服务依然可用,解析器严格按照配置文件中 nameserver
条目的顺序进行串行查询,并在遇到超时或错误时快速故障转移到下一个服务器,虽然默认行为是串行尝试,但缓存机制极大地优化了性能,而 options rotate
或现代解析器(如 systemd-resolved
)的智能逻辑可以提供一定程度的负载均衡和更优的故障处理,配置时应优先考虑本地服务器和可靠的公共备份,并了解系统实际使用的解析机制(传统 glibc
或 systemd-resolved
)以进行正确管理,对于注重隐私的用户,探索 DNS-over-TLS/HTTPS 是值得推荐的。
引用说明:
- 本文中关于
glibc
解析器行为(顺序查询、超时、故障转移、rotate
和attempts
选项)的描述,基于对 GNU C Library (glibc
) 文档和实现的长期理解,特别是resolver(3)
和resolv.conf(5)
手册页 (man 3 resolver
,man 5 resolv.conf
) 的内容。 systemd-resolved
的功能描述(智能故障转移、DNS-over-TLS 支持、存根解析器)基于systemd-resolved(8)
和resolvectl(1)
手册页 (man 8 systemd-resolved
,man 1 resolvectl
) 以及 systemd 项目文档。- NetworkManager 和
nmcli
的配置方法参考了 NetworkManager 官方文档和nmcli(1)
手册页 (man 1 nmcli
)。 systemd-networkd
的配置语法参考了systemd.network(5)
手册页 (man 5 systemd.network
)。
原创文章,发布者:酷番叔,转转请注明出处:https://cloud.kd.cn/ask/8913.html