为什么解析一个域名,CoreDNS 会收到好几次查询?ndots:5 到底改变了什么?末尾加点有用吗?这篇给 CoreDNS 开 log,在 Pod 里用 wget 发出各种写法的访问,把每条请求的名字和结果按时间顺序列出来。
wget http://example.com(ndots:5):共 8 条 DNS 请求(A 与 AAAA 各算一条),按时间顺序的名字:
example.com.k64.svc.cluster.local NXDOMAIN ×2
example.com.svc.cluster.local NXDOMAIN ×2
example.com.cluster.local NXDOMAIN ×2
example.com NOERROR ×2
不同的名字依次是:['example.com.k64.svc.cluster.local', 'example.com.svc.cluster.local', 'example.com.cluster.local', 'example.com'];NXDOMAIN 的有 6 条,最终成功的 2 条Pod 里的 /etc/resolv.conf 是 search k64.svc.cluster.local svc.cluster.local cluster.local 加 options ndots:5:名字里点数少于 5,就先依次拼上 search 域去查,都失败了才按原名查。example.com 只有 1 个点,所以 CoreDNS 依次收到 example.com.k64.svc.cluster.local、example.com.svc.cluster.local、example.com.cluster.local(都是 NXDOMAIN),最后才是 example.com(NOERROR)。每个名字还有 A 和 AAAA 两条,总共 8 条请求,其中 6 条白查。
wget http://example.com.:共 2 条 DNS 请求(A 与 AAAA 各算一条),按时间顺序的名字:
example.com NOERROR ×2
对比:2 条(带点)名字末尾加一个点(example.com.)就是绝对域名,不走 search,只有 A 和 AAAA 共 2 条。在 Pod 的 dnsConfig 里把 ndots 调成 1,访问 example.com 同样只有 2 条——点数 1 不小于 ndots 1,先按绝对域名查。
Pod cli1(dnsConfig ndots:1)访问 example.com:共 2 条 DNS 请求(A 与 AAAA 各算一条),按时间顺序的名字:
example.com NOERROR ×2
Pod cli1(ndots:1)访问集群内的 s1.k64(只有 1 个点,≥ 1):共 6 条 DNS 请求(A 与 AAAA 各算一条),按时间顺序的名字:
s1.k64 NXDOMAIN ×2
s1.k64.k64.svc.cluster.local NXDOMAIN ×2
s1.k64.svc.cluster.local NOERROR ×2ndots:1 的 Pod 访问集群内的 s1.k64(1 个点)时,会先把 s1.k64 当绝对域名查(NXDOMAIN),再试 s1.k64.k64.svc.cluster.local(NXDOMAIN),最后 s1.k64.svc.cluster.local 才成功,共 6 条请求。ndots 把代价从外部名字转给了集群内的“带命名空间”的短名字,没有免费的午餐。
cli(ndots:5)访问 s1:共 2 条 DNS 请求(A 与 AAAA 各算一条),按时间顺序的名字:
s1.k64.svc.cluster.local NOERROR ×2
cli(ndots:5)访问 s1.k64:共 4 条 DNS 请求(A 与 AAAA 各算一条),按时间顺序的名字:
s1.k64.k64.svc.cluster.local NXDOMAIN ×2
s1.k64.svc.cluster.local NOERROR ×2
cli(ndots:5)访问 s1.k64.svc:共 6 条 DNS 请求(A 与 AAAA 各算一条),按时间顺序的名字:
s1.k64.svc.k64.svc.cluster.local NXDOMAIN ×2
s1.k64.svc.svc.cluster.local NXDOMAIN ×2
s1.k64.svc.cluster.local NOERROR ×2
cli(ndots:5)访问 s1.k64.svc.cluster.local:共 8 条 DNS 请求(A 与 AAAA 各算一条),按时间顺序的名字:
s1.k64.svc.cluster.local.k64.svc.cluster.local NXDOMAIN ×2
s1.k64.svc.cluster.local.svc.cluster.local NXDOMAIN ×2
s1.k64.svc.cluster.local.cluster.local NXDOMAIN ×2
s1.k64.svc.cluster.local NOERROR ×2ndots:5 的 Pod 访问同一个 Service:s1 只要 2 条(第一个 search 域就命中);s1.k64 要 4 条;s1.k64.svc 要 6 条;写成完整的 s1.k64.svc.cluster.local(3 个点,仍小于 5)反而是 8 条以上,先拼 search 域,失败后才查原名,实测序列后半段还重复了一遍(wget 重试了解析,原因我没有深究)。最省的写法是只写 Service 名,或者在名字后面加点。