DNS解析故障排查与实战案例分析

DNS(Domain Name System)是互联网基础设施的核心组件,一旦出现解析故障,将导致服务无法访问、接口调用失败、用户体验断崖式下降。本文从原理出发,结合实战案例,梳理 DNS 解析故障的系统化排查方法,帮助运维工程师快速定位问题、恢复服务。

一、DNS 解析原理快速回顾

Linux 系统的 DNS 解析流程如下:

1
2
3
4
5
6
7
8
9
应用发起域名请求

检查 /etc/hosts(本地静态映射)

读取 /etc/nsswitch.conf,确认 DNS 查询顺序

调用 /etc/resolv.conf 中配置的 Nameserver

返回解析结果(或 NXDOMAIN / SERVFAIL 等错误码)

关键配置文件:

  • /etc/resolv.conf:Nameserver 地址(通常为 ISP 或自建 DNS 如 114.114.114.114、8.8.8.8)
  • /etc/hosts:本地静态映射,优先级高于 DNS
  • /etc/nsswitch.conf:决定查询顺序(hosts: files dns)
  • /etc/gai.conf:IPv6 相关配置,偶尔影响解析行为

二、常见 DNS 故障类型

故障类型 典型表现 常见原因
完全无法解析 ping / curl 均报 Name or service not known DNS 服务宕机、/etc/resolv.conf 配置错误
解析超时 dig/host 长时间等待后返回 TIMEOUT 网络丢包、防火墙拦截 UDP 53
解析结果错误 返回过期 IP 或他人 IP DNS 缓存污染、TTL 设置过长
特定域名无法解析 其他域名正常,仅某个域名失败 域名过期、NS 记录错误、DNS 区域传送失败
解析延迟高 每次解析耗时数百毫秒 DNS 服务器性能不足、链路质量差

三、系统化排查流程

第一步:确认是 DNS 问题还是网络问题

1
2
3
4
5
6
# 检查能否访问常用 DNS 服务器(验证网络连通性)
ping -c 2 114.114.114.114
ping -c 2 8.8.8.8

# 测试 DNS 服务器的 53 端口是否可达
nc -vzu 114.114.114.114 53

若网络本身不通,先解决网络问题。

第二步:检查本地解析配置

1
2
3
4
5
6
7
8
# 查看 DNS 配置
cat /etc/resolv.conf

# 检查 hosts 文件是否有干扰项
cat /etc/hosts

# 查看 nsswitch.conf 确认查询顺序
grep "^hosts:" /etc/nsswitch.conf

第三步:使用 dig/host/nslookup 查询解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 基本解析查询
dig example.com

# 只看 Answer 部分
dig example.com +short

# 指定 DNS 服务器查询(绕过本地配置)
dig @8.8.8.8 example.com

# 追踪完整解析链路
dig example.com +trace

# 查看 DNS 响应码(status 字段)
# NXDOMAIN = 域名不存在
# SERVFAIL = 服务器故障
# REFUSED = 查询被拒绝

第四步:检查 DNS 缓存

系统级缓存(nscd / systemd-resolved):

1
2
3
4
5
6
7
8
# 重启 nscd 清除缓存(需 root)
systemctl restart nscd

# 查看 systemd-resolved 缓存
resolvectl status

# 清除 systemd-resolved 缓存
systemd-resolve --flush-caches

浏览器/应用层缓存:直接重启应用或清除浏览器缓存。

第五步:检查防火墙和安全策略

UDP 53 端口被拦截是常见场景:

1
2
3
4
5
# 检查 iptables 规则是否 DROP 了 DNS
iptables -L -n | grep -E "53|DNS"

# 检查是否走了 TCP 53(部分场景 DNS 会降级到 TCP)
ss -tunlp | grep :53

四、实战案例:内网服务器 DNS 间歇性超时

故障现象

某台内网 Web 服务器间歇性出现 API 调用超时,问题集中在每天上午 9:00-10:00 高峰时段,其他时间段正常。

排查过程

  1. 收集指标:确认故障时段 DNS 解析耗时从正常的 5ms 上升到 3000ms+。

  2. dig 对比测试

    1
    2
    3
    dig @114.114.114.114 api-backend.internal
    # 高峰期:;; query time: 3204 msec
    # 正常期:;; query time: 4 msec
  3. 排除 DNS 服务器问题:换成阿里 DNS(223.6.6.6)和 Google DNS(8.8.8.8)后高峰时段仍超时,确认不是单一 DNS 服务商问题。

  4. tcpdump 抓包分析

    1
    tcpdump -i eth0 udp port 53 -nn

    发现高峰时段 DNS 请求出现大量 UDP 重传(retransmission),说明网络丢包导致 DNS 查询多次重试。

  5. 定位根因:检查交换机端口 error 计数,发现高峰时段有 CRC 错误计数上升。进一步检查发现网线老化,更换后故障消失。

经验总结

DNS 故障不一定出在 DNS 服务本身,网络质量(丢包、延迟)同样会直接影响 DNS 可用性。本案例中,正是借助 dig 的 query time 数据将问题从”应用层”准确定位到”网络层”,避免了长时间在 DNS 配置上的无效排查。

五、生产环境最佳实践

  1. 配置多路 DNS:至少配置 2 个 Nameserver,避免单点故障:

    1
    2
    nameserver 114.114.114.114
    nameserver 8.8.8.8
  2. 启用 DNS 健康检查:通过监控探针定期检测 DNS 解析可用性和延迟,发现异常自动告警。

  3. 合理设置 TTL:关键域名 TTL 不宜过长(建议 300-600 秒),便于故障时快速切换。

  4. 重要服务使用 hosts 文件兜底:对核心服务在 /etc/hosts 配置静态映射,DNS 故障时仍有备份解析路径。

  5. 日志留存:开启 DNS 查询日志,便于故障后复盘(dnsmasq 或 unbound 可配置 query-log)。

六、快速排查 checklist

  • ping -c 2 114.114.114.114 网络连通性
  • cat /etc/resolv.conf Nameserver 配置
  • dig domain +short 基本解析测试
  • dig @8.8.8.8 domain 指定 DNS 服务器交叉验证
  • dig domain +trace 追踪完整解析链路
  • systemctl restart nscd 清除本地缓存
  • iptables -L -n | grep 53 检查防火墙
  • tcpdump -i eth0 udp port 53 抓包确认请求/响应

DNS 故障排查的核心思路是从本地到远端、从配置到网络、从单点到系统,遵循上述排查路径,大部分 DNS 故障可在 5-10 分钟内定位根因。