为什么 dig 正常但应用不对
Linux 与 Windows 默认的解析顺序都是先查本地 hosts 文件,再走 DNS;Linux 上这个顺序由 nsswitch.conf 的 hosts 行控制(常见写法是 files dns)。这意味着 dig 直接查询 DNS 得到的结果,未必等于应用程序看到的地址——应用走的是 NSS 全链路,hosts 里的静态记录会优先命中。排查「同一域名两台机器解析不同」这类问题时,这一步必须先在前面做掉。
基本信息
| 适用平台 | Linux(/etc/hosts 与 nsswitch.conf)、Windows(System32\drivers\etc\hosts) |
|---|---|
| 解析顺序 | Linux 由 nsswitch.conf 的 hosts 行决定;Windows 固定为 hosts 优先 |
| 关键命令 | getent hosts 走 NSS 全链路,与 ping、应用行为一致 |
| 验证手段 | dig 与 getent 结果不一致,说明命中了 hosts 或其他 NSS 源 |
| 容器环境 | 容器内 hosts 通常由编排平台注入,改宿主机文件无效 |
典型使用场景
- 域名指向不对:先确认 hosts 里没有写死旧地址
- 迁移后部分机器仍访问老服务:核对 hosts 中的临时记录是否清理
- 排查「dig 结果正确但应用连不上」:用 getent 验证应用实际拿到的地址
- 容器内解析异常:确认容器内的 hosts 与 DNS 配置来源
- 统一解析口径:确认 nsswitch.conf 是否被改成了先走其他解析源
Linux 核对
Linux 核对
grep -v '^#' /etc/hosts # 查看 hosts 里的有效记录
grep '^hosts' /etc/nsswitch.conf # 例:hosts: files dns(files 优先)
getent hosts example.com # 走 NSS 全链路,与 ping 行为一致
dig +short example.com # 只查 DNS,两者结果不一致即命中了 hosts
# 追踪实际访问了哪些解析来源
strace -e trace=openat,connect getent hosts example.com 2>&1 | head -20Windows 核对
Windows 核对
Get-Content C:\Windows\System32\drivers\etc\hosts | Where-Object {$_ -notmatch '^\s*#' -and $_.Trim()}
Resolve-DnsName example.com -DnsOnly # 绕过 hosts,直接看 DNS 记录
Get-DnsClientCache | Where-Object {$_.Entry -eq 'example.com'} # 查看本地 DNS 缓存两种查询口径对比
| 命令 | 是否读 hosts | 用途 |
|---|---|---|
| getent hosts | 是,走 NSS 全链路 | 与应用行为一致,用于复现真实结果 |
| dig / nslookup | 否,只查 DNS | 验证 DNS 记录本身是否正确 |
| ping | 是,与 getent 一致 | 快速确认应用侧看到的地址 |
| Resolve-DnsName -DnsOnly | 否(Windows) | 绕过 hosts 验证 DNS 记录 |
| /etc/hosts 直接查看 | — | 确认是否存在静态记录干扰 |
getent hosts 与 dig 都查一遍:两者结果不一致,说明走了 hosts 或其他 NSS 源。这个方法对「同一域名在两台机器上结果不同」类问题尤其有效。