systemd-resolved 是 Linux 默认本地 DNS 解析与缓存服务,常因配置叠加、缓存残留或服务异常导致解析不一致;排查需分层验证解析路径是否被 NetworkManager、dnsmasq 或 /etc/resolv.conf 修改劫持,并确认 nsswitch.conf 中 hosts 行含 dns。

Linux 中的 systemd-resolved 是默认启用的本地 DNS 解析与缓存服务,它通过 127.0.0.53 提供转发式解析,但常因配置叠加、缓存残留或服务状态异常导致解析结果不一致——比如域名解析到旧 IP、部分域名失败、dig 和浏览器行为不一致等。排查这类“缓存冲突”,关键不是盲目清空,而是分层验证解析路径是否被意外劫持或缓存干扰。
确认当前实际生效的 DNS 解析链路
很多问题根源在于你以为走的是 systemd-resolved,其实被 NetworkManager、dnsmasq 或手动修改的 /etc/resolv.conf 绕过了:
- 运行
resolvectl status,重点看 “Current Scopes” 是否含dns,以及 “DNS Servers” 列出的地址是否合理(如 127.0.0.53、8.8.8.8 等) - 检查
/etc/resolv.conf是否为符号链接:ls -l /etc/resolv.conf;若指向/run/systemd/resolve/stub-resolv.conf,说明 resolved 正在接管;若指向/run/NetworkManager/resolv.conf或是静态文件,则 NetworkManager 或手动配置可能主导解析 - 执行
cat /etc/nsswitch.conf | grep hosts,确保行中包含dns(如hosts: files resolve [!UNAVAIL=return] dns),否则即使 resolv.conf 正确,glibc 也不会查 DNS
区分缓存命中与真实上游响应
systemd-resolved 不提供缓存条目列表,但可通过对比行为判断是否缓存干扰:
- 用
resolvectl query example.com执行两次,观察 “Query time”:首次 >100ms、后续骤降至 - 用直连方式绕过本地缓存验证真实结果:
dig @8.8.8.8 example.com +short和dig @1.1.1.1 example.com +short,比对输出是否与resolvectl query一致 - 特别注意 NXDOMAIN(域名不存在):resolved 默认只缓存该结果 30 秒,若长期返回 “no servers could be reached” 或 “server failure”,更可能是服务未运行或上游不可达,而非缓存问题
定位缓存冲突的典型表现与应对
以下现象往往不是缓存“脏”,而是解析路径混乱所致:
-
同一域名,
dig example.com成功但curl example.com失败:检查是否设置了http_proxy或HTTPS_PROXY环境变量,某些代理会强制走自身 DNS,绕过系统 resolver -
重启网络后解析变慢或错误:NetworkManager 可能覆盖了 resolved 的配置;运行
nmcli dev show | grep DNS查看接口级 DNS,并确认resolvectl status中 “Global” 部分是否同步 -
修改了 DNS 设置但无变化:systemd-resolved 不自动重载
/etc/systemd/resolved.conf,需sudo systemctl reload systemd-resolved或重启服务 -
容器内解析异常:Docker 默认使用 host 的
/etc/resolv.conf,若其指向 127.0.0.53 但容器未共享 host 网络,请求将失败;建议容器启动时加--dns 8.8.8.8或改用host.docker.internal模式
安全清理与临时隔离策略
当确认是缓存或服务状态引发冲突,按影响范围选择操作:
- 轻量刷新缓存:
sudo resolvectl flush-caches(适用于 systemd v245+,Ubuntu 22.04 / Debian 12 及更新版) - 彻底重置解析状态:
sudo systemctl restart systemd-resolved(缓存清空 + 配置重载,兼容所有版本) - 临时停用以排除干扰:
sudo systemctl stop systemd-resolved,再手动把/etc/resolv.conf改为nameserver 8.8.8.8,测试是否恢复;恢复时别忘了sudo systemctl start systemd-resolved - 禁用缓存(仅调试):编辑
/etc/systemd/resolved.conf,取消注释并设Cache=no,然后重启服务;不建议长期开启


















