dig —— DNS 查询工具
一句话定义
dig(Domain Information Groper)是 DNS 调试的事实标准:发一个 DNS 查询,把详细的请求 / 响应打出来。比 nslookup 强大、比 host 详细——三个里选 dig。
典型场景
- 排查"域名解析不对":
dig example.com - 测特定 DNS 服务器:
dig @8.8.8.8 example.com - 排查 K8s CoreDNS:
dig @10.96.0.10 kubernetes.default.svc.cluster.local - 反向 DNS:
dig -x 1.2.3.4 - 看完整解析链:
dig +trace example.com
装
apt install -y dnsutils # Ubuntu / Debian
yum install -y bind-utils # CentOS / RHEL
很多最小化容器镜像没装。
基础用法
dig example.com
输出长这样:
; <<>> DiG 9.18.18 <<>> example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12345
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;example.com. IN A
;; ANSWER SECTION:
example.com. 7200 IN A 93.184.215.14
;; Query time: 24 msec
;; SERVER: 192.168.1.1#53(192.168.1.1) (UDP)
;; WHEN: Mon May 27 14:30:00 UTC 2026
;; MSG SIZE rcvd: 56
读法:
status: NOERROR—— 查询成功(NXDOMAIN= 域名不存在)flags: qr rd ra—— qr=响应,rd=客户端要求递归,ra=服务端支持递归QUESTION SECTION—— 你问了什么ANSWER SECTION—— 答案(最关键)Query time—— 耗时SERVER—— 谁回答的(用了哪个 DNS)
简化输出 +short
完整输出排错有用、但日常太啰嗦。+short 只给答案:
$ dig +short example.com
93.184.215.14
$ dig +short example.com MX
0 .
$ dig +short example.com NS
a.iana-servers.net.
b.iana-servers.net.
日常用 +short,排错用完整输出。
查不同记录类型
dig example.com A # IPv4(默认)
dig example.com AAAA # IPv6
dig example.com MX # 邮件交换
dig example.com NS # 名字服务器
dig example.com TXT # 文本(SPF / DKIM 等)
dig example.com CNAME # 别名
dig example.com SOA # 权威记录
dig example.com SRV # K8s service 用这种
dig example.com ANY # 所有类型(不少 DNS 拒绝这个)
指定 DNS 服务器:@
dig @8.8.8.8 example.com # 用 Google DNS
dig @1.1.1.1 example.com # 用 Cloudflare DNS
dig @10.96.0.10 kubernetes.default.svc.cluster.local # 用 K8s CoreDNS
排查"自己机器上的 /etc/resolv.conf 配的 DNS 不对":用 @ 指定备选 DNS 比较结果。
dig example.com # 用本机配的 DNS
dig @8.8.8.8 example.com # 用 8.8.8.8
# 两者答案不一样 → 本机 DNS 缓存 / 内网劫持 / 配错
反向 DNS:-x
dig -x 8.8.8.8
# 显示 8.8.8.8 对应的主机名(PTR 记录)
# google-public-dns-a.google.com.
排查邮件相关 / 日志里有 IP 想知道是谁。
看完整解析链:+trace
dig +trace example.com
不从本机 DNS 缓存查,从根域名开始一步步问:
. ← 问根
com. ← 问 .com TLD
example.com. ← 问 example.com 权威 NS
+trace 显示每一跳。用来:
- 看是哪一层 DNS 给的错答案
- 验证授权委派链是否正确
- 调试 DNSSEC
K8s CoreDNS 排错黄金套路
K8s 集群内 pod 解析问题 90% 用 dig 在 5 分钟内定位。
1. 集群 DNS 的 IP
kubectl get svc -n kube-system kube-dns
# NAME TYPE CLUSTER-IP ...
# kube-dns ClusterIP 10.96.0.10 ... ← 通常是这个
2. 在某个 pod 里测
kubectl run -it --rm test --image=infoblox/dnstools --restart=Never -- bash
# 进交互
dig kubernetes.default.svc.cluster.local
# 应该返回 10.96.0.1(apiserver service)
3. 测不同 service
dig kubernetes # 简写
dig kubernetes.default # 加 ns
dig kubernetes.default.svc.cluster.local # 全名
dig myapp.myns.svc.cluster.local
如果短名 kubernetes 也解析得到 → /etc/resolv.conf 里的 search domain 在起作用:
cat /etc/resolv.conf
# nameserver 10.96.0.10
# search myns.svc.cluster.local svc.cluster.local cluster.local
# options ndots:5
K8s 自动给 pod 写 search domain,让 dig myapp 自动尝试拼几个域名。
4. 测 service 对应的 endpoint
dig myapp.myns.svc.cluster.local SRV
# _myport._tcp.myapp.myns.svc.cluster.local. 30 IN SRV 0 33 8080 10-244-0-5.myapp.myns.svc.cluster.local.
SRV 记录里包含 endpoint IP 和端口。
5. 测外部域名(pod → 互联网)
dig github.com
# 应该解析到真实 IP(CoreDNS forward 给上游)
dig github.com +trace
# 看每跳;如果某跳是公司内网 DNS 劫持,能在这里看到
排查"pod 解析外部域名超时" —— 用 dig 直接测,看是上游慢还是 CoreDNS pod 自己的问题。
6. 直接问某个 CoreDNS pod
kubectl get pod -n kube-system -l k8s-app=kube-dns -o wide
# coredns-xxx Running 10.244.0.3 m1
# coredns-yyy Running 10.244.1.4 m4
dig @10.244.0.3 kubernetes.default.svc.cluster.local
# 直接问某个 CoreDNS pod
判断"是不是某个 CoreDNS pod 挂了":分别问每个 pod。
+time +tries 控制重试 / 超时
dig +time=3 +tries=1 example.com
# 3 秒超时,不重试
在脚本里测连通性用:
if dig +time=3 +tries=1 +short example.com > /dev/null 2>&1; then
echo "DNS OK"
fi
实战场景
1. pod 解析慢 / 超时
# pod 里抓 DNS 流量
nsenter -t <pod-pid> -n tcpdump -i any -nn 'udp port 53' -c 20
# pod 里直接测
kubectl exec my-pod -- nslookup kubernetes.default
# 或者
kubectl exec my-pod -- timeout 5 dig kubernetes.default.svc.cluster.local
# 测每个 CoreDNS pod
for ip in $(kubectl get pod -n kube-system -l k8s-app=kube-dns -o jsonpath='{.items[*].status.podIP}'); do
echo "=== $ip ==="
dig @$ip kubernetes.default.svc.cluster.local +short +time=3
done
2. 排查 hosts vs DNS
getent hosts example.com # 系统层(含 /etc/hosts + DNS)
dig +short example.com # 只走 DNS
# 两者不一致 → /etc/hosts 里有覆盖
3. 验证 TTL 是不是 0(让浏览器/系统不缓存)
dig example.com | grep -E "ANSWER SECTION" -A 5
# example.com. 30 IN A 1.2.3.4
# ↑ TTL 秒数
DNS 切换前先把 TTL 调小(30 秒),方便快速切。
4. 看 NS 委托是否正确
dig example.com NS
# 返回的 NS 服务器是不是你期望的
dig @ns1.example.com example.com # 直接问权威 NS
5. 验证 DKIM / SPF 记录
dig example.com TXT +short
# "v=spf1 include:_spf.google.com ~all"
dig default._domainkey.example.com TXT
dig vs nslookup vs host
| 工具 | 优点 | 缺点 |
|---|---|---|
dig | 完整输出、可控、专业 | 输出长 |
nslookup | 老 / 普及 | 输出格式不固定、容易解析错 |
host | 简洁 | 信息少 |
学 dig,忘 nslookup。
常见踩坑
坑 1:忘了域名结尾的 . 是 FQDN
dig example.com # 用 search domain 拼接(可能错)
dig example.com. # 末尾的 . 表示 FQDN,不再拼接
要测绝对域名就加 .,避免被 search domain 干扰。
坑 2:dig 在某些容器镜像里没装
$ dig
sh: dig: not found
alpine 用 apk add bind-tools;distroless 没法装 —— 用 kubectl debug 起个调试 sidecar。
坑 3:+short 没答案就退出码 0
dig +short nxdomain.example.com
# (空输出)
echo $?
# 0
空答案的退出码是 0(dig 跑成功了,只是答案是空)。脚本判断:
ANS=$(dig +short example.com)
[ -z "$ANS" ] && echo "no answer"
坑 4:dig 卡住
dig @192.168.1.99 example.com
# 卡住 ...
DNS 服务器不可达,dig 默认重试 3 次每次 5 秒 = 15 秒才退出。
dig +time=2 +tries=1 @192.168.1.99 example.com
# 最多 2 秒
坑 5:本机 stub resolver 缓存让你看不到改动
Ubuntu 22 默认有 systemd-resolved,在 127.0.0.53 监听并缓存。
dig example.com # 用 systemd-resolved,可能拿到缓存
dig @8.8.8.8 example.com # 跳过本地 stub,直接问上游
刷 systemd-resolved 缓存:
resolvectl flush-caches
坑 6:dig pod-name.pod 不存在
dig my-pod.default.pod.cluster.local # 通常不工作
K8s 默认不给 pod 创建 DNS 记录(只给 Service / Headless Service 创建)。要 pod DNS:
- StatefulSet pod 用
pod-name.svc.ns.svc.cluster.local(要有 Headless Service) - 或者 PodDNSConfig
坑 7:CoreDNS forward plugin 转发外部 DNS 失败
pod 解析 github.com 慢 / 超时,但 CoreDNS 本身没事。看 CoreDNS 配置:
kubectl get cm -n kube-system coredns -o yaml | grep -A 5 forward
# forward . /etc/resolv.conf {
# max_concurrent 1000
# }
forward . /etc/resolv.conf 转发给节点的 DNS。节点 DNS 通不通:
ssh m1 'dig @<节点 resolv.conf 里的 DNS> github.com'
通常根因是节点 /etc/resolv.conf 配错 / 上游 DNS 慢。
坑 8:用 dig 测 mDNS(.local)失败
dig myhost.local # 失败
.local 是 mDNS(Avahi / Bonjour)的保留域,不走标准 DNS。K8s .svc.cluster.local 不一样——后者是普通域,CoreDNS 内部权威解析、不走 mDNS。