Skip to content

域名和 DNS

IP 地址记不住,所以才有域名这东西——www.example.com203.0.113.10 好记多了。但机器之间通信认的还是 IP,所以浏览器拿到域名之后,第一件事就是查这名字对应哪个 IP,这个过程就是 DNS。不光公网网站用 DNS,公司内网平台、Kubernetes 里的 Service,背后都是同一套名字解析机制。

一、域名的结构

www.example.com 这种域名要倒着读,从右往左层级越来越细:

  • com 是顶级域,跟 orgnetcnio 这些是一类,由 ICANN 这类机构管理
  • example.com 是主域名,这是公司或个人注册的
  • www 是主域名下的一个子域名,可以随便起,业务方自己控制

同一个主域名下挂几个入口完全看业务需要。常见的拆分大概是这样:www 给官网、api 给后端接口、static 给静态资源、grafana 给监控平台、harbor 给镜像仓库。看到陌生域名时,先大致判断它指向的是什么——公网入口、内网服务、CDN、还是 Kubernetes Ingress,后面排查才有方向。

二、递归 DNS 和权威 DNS

客户端不会自己从根 DNS 一路查到底——太慢也太麻烦。系统里配的 DNS 服务器(就是 /etc/resolv.conf 里那个 nameserver)会帮客户端完成整个查询过程,这种替你查的服务器叫递归 DNS。最终保存域名解析记录、对外回答"这个域名对应什么 IP"的,叫权威 DNS

整个查询过程大概是这样:

8.8.8.8(Google)、114.114.114.114(国内通用)、运营商 DNS、公司内网 DNS,这些大多都是递归 DNS。你在云厂商控制台或者域名注册商那里配的解析记录,是由权威 DNS 对外回答的——所以改了记录之后,要等递归 DNS 的缓存过期,新记录才能生效。

三、记录类型

很多人以为 DNS 就是"域名 → IP",其实记录类型有好几种,常用的几种:

类型干什么例子
A指向 IPv4 地址www -> 203.0.113.10
AAAA指向 IPv6 地址www -> 2001:db8::10
CNAME指向另一个域名(不是 IP)www -> cdn.example.net
MX邮件服务器example.com -> mail.example.com
TXT文本记录,常用于域名所有权验证、SPF、DKIMv=spf1 include:xxx ~all
NS指定这个域名由哪些权威 DNS 负责example.com -> ns1.example.net

业务方接触最多的是 A、AAAA、CNAME 这三种。接 CDN 的时候基本都走 CNAME——业务域名先 CNAME 到一个 CDN 厂商给的域名,CDN 自己根据用户位置返回就近的边缘节点 IP。这样业务方就不用关心 CDN 节点 IP 怎么变,都交给 CDN 那边动态调度。

四、TTL

DNS 查询结果会被各级缓存,浏览器、操作系统、路由器、运营商 DNS 都有自己的缓存。TTL(Time To Live)就是告诉这些缓存"这条记录可以放多久"。比如 TTL 写 300,意思是查到这条记录之后,300 秒之内可以重复用,过了 300 秒就要重新查。

TTL 长短是个权衡:

  • TTL 长(比如 3600 秒、86400 秒):查询少,服务器压力小,但切换 IP 的时候旧缓存要等很久才过期,业务切不过来
  • TTL 短(比如 60 秒、300 秒):切换快,改完记录几分钟就全网生效,但查询量大、对权威 DNS 压力大

域名迁移之前的标准操作是先把 TTL 调低:比如原来是 3600,提前一天改成 60 或者 300,等旧缓存全部过期之后,再改 A 记录到新 IP。这样万一新 IP 有问题要回滚,也只需要等几分钟而不是几小时。

已经缓存的旧结果不会因为你在控制台改了记录就立刻消失。改完记录之后某个地区还在解析到旧 IP,大概率是某一层的缓存还没过期——耐心等,或者刷一下本机缓存(systemd-resolve --flush-caches / ipconfig /flushdns)。

五、内网 DNS

DNS 不只是公网的事,内网里用得更狠。公司内部平台的域名、云 VPC 里服务的域名、Kubernetes 里 Service 的域名,都是 DNS。

场景域名长什么样
公司内部 GitLabgitlab.company.local
云 VPC 内的 MySQLmysql.internal.example.com
Kubernetes Serviceapi.default.svc.cluster.local

内网域名最大的价值是解耦 IP——服务不用写死 IP,数据库切主、Pod 重建、服务扩容之后 IP 变了,名字还能保持不变,业务侧不用动代码。这点在 Kubernetes 里特别明显:api.default.svc.cluster.local 这个名字背后对应的 Pod IP 一天可能变好几次,但应用一直用这个名字访问,完全无感。

排查的时候,如果应用日志里看到 lookup api.default.svc.cluster.local: no such host,基本就是 DNS 查不到了——可能是 Service 名拼错了、namespace 不对、CoreDNS 出问题,顺着这几条查。

六、解析异常

DNS 出问题时通常报这几种结果:

结果大概率原因
NXDOMAIN域名根本不存在,或者记录没配
SERVFAILDNS 服务器自己有问题,可能是权威 DNS 挂了、网络断了
解析到旧 IP缓存还没过期,或者某台机器的 /etc/hosts 里写了静态映射
不同地区解析到不同 IPCDN 智能调度、运营商缓存差异、做了线路解析

NXDOMAIN 不一定是故障——有些应用启动时会去探多个候选域名,部分候选不存在是正常的,日志里看到几条 NXDOMAIN 不用慌。真正要警觉的是:多个核心域名同时 SERVFAIL,或者解析耗时从平时的几毫秒突然涨到几秒,这种情况基本就是 DNS 链路本身有问题,要去看 CoreDNS、上游 DNS、网络连通性这几条线。