普通网友 2026-02-27 05:35 采纳率: 98.5%
浏览 0
已采纳

Linux多DNS配置冲突导致域名解析异常如何排查?

Linux多DNS配置冲突是运维中高频故障:当`/etc/resolv.conf`手动配置、NetworkManager动态生成、systemd-resolved服务、DHCP自动注入等多源共存时,常出现DNS优先级混乱(如`nameserver`顺序被覆盖、`options rotate`误启、`127.0.0.53`本地stub与上游DNS混用),导致部分域名解析超时或返回错误IP。典型现象包括:`nslookup`正常而`curl`失败、`dig @8.8.8.8`通但无指定DNS参数时失败、`resolvectl status`显示多个Link却仅一个生效。排查需分四步:① 检查真实生效的resolv.conf(注意符号链接及`/run/systemd/resolve/stub-resolv.conf`);② 运行`resolvectl status`或`nmcli dev show | grep DNS`定位管理主体;③ 使用`strace -e trace=connect,sendto,recvfrom curl -v example.com 2>&1`确认实际查询目标;④ 临时禁用冲突服务(如`sudo systemctl stop systemd-resolved`)验证根因。关键原则:单一权威源 + 显式优先级控制。
  • 写回答

1条回答 默认 最新

  • 舜祎魂 2026-02-27 05:35
    关注
    ```html

    一、现象层:识别“看似正常却失败”的DNS异常行为

    运维人员常遇到nslookup能解析、curl却超时的矛盾现象——这是因为nslookup直连指定DNS(默认/etc/resolv.conf),而curl依赖glibc的getaddrinfo(),受systemd-resolved stub 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配置冲突导致双写

    三、诊断层:四步精准定位法(含命令链与原理注解)

    1. 查真实生效文件ls -l /etc/resolv.conf → 若指向/run/systemd/resolve/stub-resolv.conf,则glibc实际使用stub;若指向/var/run/NetworkManager/resolv.conf,则NM为权威源。
    2. 定管理主体resolvectl status | grep "Global\|Link:" 显示resolved管理范围;nmcli dev show | grep DNS 输出NM当前应用的DNS,二者冲突即需裁决。
    3. 验实际流量路径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请求目标,绕过工具假象。
    4. 做隔离验证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 statusnmcli dev showdig +short google.com @127.0.0.53结果一致性
    • Ansible标准化模板:强制/etc/resolv.conf为只读文件,并通过nmcliresolved API统一注入DNS
    • 监控埋点:采集resolvectl statistics中的Cache hit rateFailed 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节点混用corednssystemd-resolved → coredns upstream指向127.0.0.53形成环路;应改为upstream 8.8.8.8或停用resolved。

    ```
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 2月28日
  • 创建了问题 2月27日