物理主机 DNS 解析故障:从应用查到上游

物理主机 DNS 解析故障:从应用查到上游

业务进程报告域名解析失败,但按地址访问仍然正常时,直接改 DNS 服务器往往会掩盖现场。故障可能发生在应用缓存、NSS 查询顺序、系统解析服务,也可能来自上游返回的错误。排查目标不是让某条命令偶尔成功,而是确认业务进程实际经过哪条解析路径,以及错误在哪一层出现。

本文以 Ubuntu Server 24.04 LTS 为操作环境。AMDSSH 物理主机付款后在控制台查看凭据,通过 SSH 登录;机器有多个地址时使用第一个地址连接。以下检查不修改网卡地址、路由和防火墙,适合先建立证据链。

一、固定查询对象,记录原始错误

先保存应用报错、查询名称、记录类型和发生时间。还应说明故障是所有域名都失败,还是某个名称失败;是宿主上的进程异常,还是容器中的进程异常。短名称会受到搜索域影响,排查时优先使用带末尾点的完整域名。

下面用 amdssh.com. 演示查询格式,不预设它必须返回某个地址。实际验收应替换成业务所需、已确认存在相应记录的名称。先检查工具,再保存基础环境:

command -v getent resolvectl dig
date -Is
readlink -f /etc/resolv.conf
cat /etc/resolv.conf
grep '^hosts:' /etc/nsswitch.conf
systemctl is-active systemd-resolved
resolvectl status

dig 由 dnsutils 软件包提供;若尚未安装,应通过已配置的软件源准备工具。解析已经故障时,安装失败不能作为新的根因证据。

地址连通不等于 DNS 查询链路正常。DNS 收到应答,也不等于应用获得了需要的记录;必须同时检查响应状态、记录类型与实际返回内容。

二、对照 NSS 与系统解析服务

三种查询并不等价

getent 通过 NSS 查询,与常见系统地址解析调用更接近;resolvectl 查询 systemd-resolved;dig 进行 DNS 查询,不能验证完整的 NSS 路径。

getent ahostsv4 amdssh.com.
resolvectl query --type=A amdssh.com.
dig amdssh.com. A +time=2 +tries=1

三个结果应结合读取。若 getent 返回旧地址而 DNS 查询返回新地址,先检查 /etc/hosts 和 hosts: 行的模块顺序。若 resolvectl 成功而 getent 失败,应检查 NSS 模块是否存在、顺序是否合理,以及服务是否运行在不同文件系统环境中。

/etc/resolv.conf 可能指向本地解析入口,并不直接列出最终上游。它还可能由网络管理工具生成。不要因为看到本地地址就认定配置错误,也不要覆盖符号链接后再判断故障是否消失。

某些应用使用自己的 DNS 库,不走 NSS;因此 getent 成功只是系统路径正常的证据,不是所有应用恢复的证明。

三、指定上游,区分响应与传输故障

从 resolvectl status 中记录故障查询对应接口的 DNS 服务器、路由域和当前服务器。多接口机器可能按域名选择不同上游,不能只取输出中的第一项。下面交互输入实际使用的上游地址,不引入未经确认的公共解析器。

read -r -p 'DNS server address: ' DNS_SERVER
dig @"$DNS_SERVER" amdssh.com. A +time=2 +tries=1
dig @"$DNS_SERVER" amdssh.com. A +tcp +time=2 +tries=1
dig @"$DNS_SERVER" amdssh.com. AAAA +time=2 +tries=1

这里的两秒超时和一次尝试是排查参数,不是业务超时建议。保留完整输出,重点看 status、答案区、查询耗时和实际服务器,不要仅凭命令退出码判断业务记录有效。

按应答状态处理

NXDOMAIN 表示名称不存在;先核对拼写、搜索域和权威记录。NOERROR 但答案为空,可能只是该类型没有记录,不应当成网络故障。SERVFAIL 表示解析过程失败,需要结合上游日志或管理方检查;REFUSED 则应核对查询权限。

UDP 查询超时而 TCP 查询成功,提示两种传输路径表现不同,可继续检查相关网络策略。两者都超时,应检查到该上游的路由与访问策略,但不能仅凭超时判定服务器宕机。上游有响应而系统路径失败,则回到本地配置和缓存继续定位。

四、按证据修复,避免覆盖配置所有者

先查明 DNS 配置由哪一层管理。Ubuntu Server 可能通过 Netplan 将配置交给具体网络后端,也可能采用其他管理方式。持久配置应修改实际管理者的配置文件,不能只改生成出来的 /etc/resolv.conf。

若确认权威记录已经更正,而 systemd-resolved 保留了旧结果,可以在记录现场后清空其缓存:

resolvectl statistics
sudo resolvectl flush-caches
resolvectl query --type=A amdssh.com.
getent ahostsv4 amdssh.com.

清缓存不会更改上游,也不会清除应用自己的缓存。名称曾返回不存在时,还可能受负缓存影响,应结合响应中的 SOA 信息判断,不能把反复重启服务当成修复方式。

修改 NSS 顺序前应保存原文件,并明确哪些模块负责本地文件、DNS 或其他名称来源。带条件动作的模块可能提前结束查询,不能只看有没有 dns 字样。

确需更改持久 DNS 配置时,先保存配置、检查语法,并准备原文件恢复步骤。远程应用网络变更前,应保持已有 SSH 会话,优先采用配置管理工具提供的可撤销应用方式;不要同时更改 DNS、路由和网卡名称。

五、在业务进程环境中完成验收

宿主恢复后,还要检查容器或隔离服务看到的解析文件。容器可能有独立的 /etc/resolv.conf,进程也可能缓存旧地址。应进入实际运行环境重复查询,而不是只在宿主终端执行同一条命令。

最终验收包括以下检查项:

如果问题只发生在某个进程,继续检查它的解析器、运行环境和连接池,而不是扩大到整机网络调整。一次完整排查应能解释原始错误、指出故障层,并证明修复后的业务请求经过了预期解析路径。

常见问题

dig 能解析,为什么应用仍然报域名解析失败?

dig 直接进行 DNS 查询,通常不经过完整的 NSS 路径。应用可能受到 hosts 配置、容器内解析文件、进程缓存或自带解析器影响,应对照 getent 结果,并在应用实际运行环境中重复检查。

清空系统 DNS 缓存能修复所有解析故障吗?

不能。resolvectl flush-caches 只清空 systemd-resolved 的缓存,不会修复上游错误,也不会清除应用自身缓存。应先记录响应状态和实际使用的上游,再针对故障所在层处理。

EPYC 7543P 独享物理主机$450.2/月起

从资源规划进入整机配置

机型与选配按月合计计费,配置页列出完整明细;连接凭据在交付后的控制台查看。