Linux多DNS配置冲突导致域名解析异常如何排查?
- 写回答
- 好问题 0 提建议
- 关注问题
- 邀请回答
-
1条回答 默认 最新
舜祎魂 2026-02-27 05:35关注```html一、现象层:识别“看似正常却失败”的DNS异常行为
运维人员常遇到nslookup能解析、curl却超时的矛盾现象——这是因为
nslookup直连指定DNS(默认/etc/resolv.conf),而curl依赖glibc的getaddrinfo(),受systemd-resolvedstub resolver或NetworkManager DNS策略影响。典型表现还包括:dig @8.8.8.8 google.com成功,但ping google.com失败;resolvectl status显示3个Link(eno1/wlan0/docker0),却仅eno1的DNS生效;cat /etc/resolv.conf显示127.0.0.53,但dig +trace未见该地址参与查询。二、配置层:多源共存下的文件与服务冲突图谱
配置源 写入路径 覆盖机制 典型干扰项 手动编辑 /etc/resolv.conf(若非软链)被NM或resolved自动重写 options rotate引发轮询乱序NetworkManager /var/run/NetworkManager/resolv.conf→ 软链至/etc/resolv.confDHCP响应后强制刷新 忽略 dns=none配置导致stub接管systemd-resolved /run/systemd/resolve/stub-resolv.conf(glibc实际读取)开机自启并劫持 127.0.0.53stub模式下不转发 .local以外域名DHCP客户端 /etc/dhcp/dhclient.conf+supersede domain-name-servers每次租约更新触发重载 与NM配置冲突导致双写 三、诊断层:四步精准定位法(含命令链与原理注解)
- 查真实生效文件:
ls -l /etc/resolv.conf→ 若指向/run/systemd/resolve/stub-resolv.conf,则glibc实际使用stub;若指向/var/run/NetworkManager/resolv.conf,则NM为权威源。 - 定管理主体:
resolvectl status | grep "Global\|Link:"显示resolved管理范围;nmcli dev show | grep DNS输出NM当前应用的DNS,二者冲突即需裁决。 - 验实际流量路径:
strace -e trace=connect,sendto,recvfrom -s 1024 curl -v https://example.com 2>&1 | grep -E "(127\.0\.0\.53|8\.8\.8\.8|114\.114\.114\.114)"—— 直接捕获socket级DNS请求目标,绕过工具假象。 - 做隔离验证:
sudo systemctl stop systemd-resolved && sudo systemctl disable systemd-resolved后测试;若恢复则确认其为根因,反之需检查NM或DHCP。
四、架构层:单一权威源实施策略(推荐生产级方案)
遵循单一权威源 + 显式优先级控制原则,推荐以下两种稳定架构:
graph LR A[统一入口] --> B{选择模式} B -->|轻量级服务器| C[停用resolved + NM托管
nmcli dev set eno1 ipv4.ignore-auto-dns yes
nmcli dev set eno1 ipv4.dns “8.8.8.8 114.114.114.114”] B -->|容器/边缘设备| D[启用resolved + 全局配置
sudo resolvectl revert eno1
sudo resolvectl dns eno1 8.8.8.8 114.114.114.114
sudo resolvectl domain eno1 “~.”] C --> E[最终:/etc/resolv.conf 指向 NM 生成文件] D --> F[最终:/etc/resolv.conf 指向 stub-resolv.conf,resolved全局分发]五、进阶层:高级调试与长期治理建议
- 启用
systemd-resolved日志:sudo journalctl -u systemd-resolved -f观察域名转发链路 - 禁用glibc stub绕过:
export GODEBUG=netdns=go(Go程序)或编译时加-tags netgo - 自动化校验脚本:
check-dns-consistency.sh每小时比对resolvectl status、nmcli dev show、dig +short google.com @127.0.0.53结果一致性 - Ansible标准化模板:强制
/etc/resolv.conf为只读文件,并通过nmcli或resolvedAPI统一注入DNS - 监控埋点:采集
resolvectl statistics中的Cache hit rate和Failed queries指标,接入Prometheus告警
六、避坑指南:五个高频误操作与修正指令
① 错误:直接
```chattr +i /etc/resolv.conf→ 导致NM无法更新,网络断连;应改用nmcli dev set eno1 ipv4.ignore-auto-dns yes。
② 错误:在/etc/systemd/resolved.conf中设DNS=127.0.0.53→ 引发循环解析;正确值应为上游IP如8.8.8.8。
③ 错误:启用options rotate却不配timeout:1→ 多DNS轮询放大超时;建议禁用rotate,改用systemd-resolved内置负载均衡。
④ 错误:Docker启动时未加--dns 8.8.8.8且宿主机用stub → 容器内127.0.0.11不可达;应配置/etc/docker/daemon.json中"dns": ["8.8.8.8"]。
⑤ 错误:Kubernetes节点混用coredns与systemd-resolved→ coredns upstream指向127.0.0.53形成环路;应改为upstream 8.8.8.8或停用resolved。本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报- 查真实生效文件: