DNS 域名解析¶
学习目标¶
学完本章后,学习者应该能够:
- 理解域名解析流程、本地缓存、递归查询和迭代查询。
- 理解 DNS 负载均衡、污染、劫持和缓存过期。
- 理解 Kubernetes CoreDNS 在服务发现中的作用。
- 能排查 Go 服务常见 DNS 解析问题。
DNS 解决什么问题¶
人更容易记住域名,机器通信需要 IP。DNS 负责把域名解析为 IP 地址。
简化流程:
真实流程中会有多级缓存,所以 DNS 问题经常表现为“有些机器正常,有些机器异常”。
递归查询与迭代查询¶
递归查询:客户端把问题交给 DNS 服务器,由 DNS 服务器负责查到底并返回结果。
迭代查询:DNS 服务器告诉查询方下一步该问谁,查询方继续问。
日常排障更关注最终解析结果、耗时、TTL 和使用的是哪个 resolver。
DNS 缓存与 TTL¶
TTL 决定 DNS 记录可以缓存多久。
TTL 太长:
- 切流慢。
- 故障 IP 可能长时间被访问。
TTL 太短:
- DNS 查询压力更高。
- 客户端更频繁解析。
工程上要在切换速度和解析成本之间取舍。
Kubernetes CoreDNS¶
Kubernetes 内部服务名通常由 CoreDNS 解析。
例如:
如果 CoreDNS 异常,Pod 可能无法解析 Service 域名,表现为数据库、Redis、内部服务全部“连不上”。
Go 后端实际应用例子¶
例子一:设置请求超时覆盖 DNS 阶段¶
http.Client.Timeout 覆盖从请求开始到响应体读取完成的整体耗时,包括 DNS、连接、TLS、请求发送和响应读取。
更细粒度可以配置 net.Dialer:
transport := &http.Transport{
DialContext: (&net.Dialer{
Timeout: 1 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
}
client := &http.Client{Transport: transport}
例子二:调试域名解析结果¶
Go 中可以显式解析:
ips, err := net.LookupIP("example.com")
if err != nil {
return err
}
for _, ip := range ips {
log.Println(ip.String())
}
生产中更推荐把 DNS 错误、解析耗时和目标 host 记录到日志或指标里。
常见误区¶
- 误区一:DNS 解析一次后永远不变。
DNS 记录可能变更,客户端和中间缓存遵循 TTL。长连接复用时也可能长期不重新解析。
- 误区二:域名能解析就说明服务可用。
DNS 只返回地址,后续 TCP、TLS、HTTP 仍可能失败。
- 误区三:Kubernetes Service 访问失败一定是网络策略。
CoreDNS 故障、Pod DNS 配置、Service 名称错误也会导致访问失败。
线上问题案例¶
某服务偶发访问内部 Redis 失败,错误为 no such host。排查发现同节点上 CoreDNS 查询超时,导致 Pod 内部域名解析失败。
修复方式包括检查 CoreDNS Pod 状态、资源限制、上游 DNS、节点网络和错误率指标;业务侧增加 DNS 错误分类和超时控制。
实战任务¶
排查“域名偶发解析失败”:
- 在故障机器上查询域名。
- 查看使用的 DNS 服务器。
- 对比其他机器解析结果。
- 检查 TTL 和缓存。
- 如果在 Kubernetes 内,检查 CoreDNS。
参考答案
先确认故障机器实际使用哪个 DNS 服务器,并对同一域名多次解析,观察是否超时、返回不同结果或失败。再和正常机器对比解析结果、TTL 和 resolver 配置。
Kubernetes 内部要检查 Pod 的 /etc/resolv.conf、CoreDNS Pod 状态、CoreDNS 日志、Service 名称是否正确,以及是否存在 DNS 查询流量暴涨。
面试题¶
1. DNS 解析大致流程是什么?¶
参考答案
应用发起域名查询后,通常先查本地缓存,再请求本地 DNS 服务器。本地 DNS 如果没有缓存,会继续向根域、顶级域、权威 DNS 查询,最终拿到记录并按 TTL 缓存。
实际系统中还可能有浏览器缓存、操作系统缓存、语言运行时行为和代理缓存。
2. TTL 有什么作用?¶
参考答案
TTL 决定 DNS 记录可以被缓存多久。较长 TTL 能降低 DNS 查询压力,但故障切换或 IP 变更生效较慢;较短 TTL 能更快切流,但会增加解析压力。
生产系统要根据变更频率、故障切换需求和 DNS 承载能力设置 TTL。
3. Kubernetes CoreDNS 负责什么?¶
参考答案
CoreDNS 是 Kubernetes 集群内常见 DNS 服务,负责解析 Service、Pod 等集群内部域名,也可能转发外部域名查询。
如果 CoreDNS 异常,Pod 可能无法通过服务名访问数据库、缓存或内部服务,表现为大量 no such host 或 DNS timeout。