聊聊 resolv.conf 中 search 和 ndots 配置
一、背景
Kubernetes 集群中,域名解析离不开 DNS 服务,在 Kubernetes v1.10 以前集群使用 kube-dns dns服务,后来在 Kubernetes v1.10+ 使用 Coredns 做为集群dns服务。
使用 Kubernetes 集群时,会发现 Pod /etc/resolv.conf 配置。具体如下:
[root@k8s-10 ~]# docker exec -it 7a18fcfea7f9 bash
root@cs-apm-demo-d-5b7c79d8f6-5v88b:/opt#cat /etc/resolv.conf
nameserver 172.21.0.10
search dolphin.svc.cluster.local svc.cluster.local cluster.local 65.3.6
options ndots:5
[root@k8s-10 ~]# sudo kubectl get all --all-namespaces -owide| grep 172.21.0.10
kube-system service/kube-dns ClusterIP 172.21.0.10 <none> 53/UDP,53/TCP,9153/TCP 70d k8s-app=kube-dns
172.21.0.10为KubeDNS的集群IP,对于内部域名,KubeDNS会直接解析,对于外部域名,KubeDNS会丢给上一级DNS服务器解析,这个上一级DNS服务器就依赖于resolv.conf;
1.1、名词解释:
nameserver:定义DNS服务器的IP地址
search:它的多个参数指明域名查询顺序。搜索列表目前仅限于6个域名,共计256个字符。
ndots:通俗一点说,如果你的域名请求参数中,点的个数比配置的ndots小,则会按照配置的search内容,依次添加相应的后缀直到获取到域名解析后的地址。如果通过添加了search之后还是找不到域名,则会按照一开始请求的域名进行解析。
options ndots:5 解释
如果查询的域名包含的点".",不到5个,那么进行DNS查找,将使用非完全限定名称(或者叫绝对域名),如果你查询的域名包含点数大于等于5,那么DNS查询,默认会使用绝对域名进行查询。
如果我们请求的域名是,a.b.c.d.e,这个域名中有4个点,那么容器中进行DNS请求时,会使用非绝对域名进行查找,使用非绝对域名,会按照 /etc/resolv.conf 中的 search 域,走一遍追加匹配:
a.b.c.d.e.cicd.svc.cluster.local. ->
a.b.c.d.e.svc.cluster.local. ->
a.b.c.d.e.cluster.local.
直到找到为止。如果走完了search域还找不到,则使用 a.b.c.d.e. ,作为绝对域名进行DNS查找。
说明:
a)请求域名中点数少于5个时,先走search域,最后将其视为绝对域名进行查询;
b)请求域名中点数大于等于5个时,直接视为绝对域名进行查找,只有当查询不到的时候,才继续走 search 域。
二、解析集群内部域名
/ # nslookup cs-ezview-cu
Server: 172.21.0.10
Address: 172.21.0.10:53
Name: cs-ezview-cu.dolphin.svc.cluster.local
Address: 172.21.20.207
*** Can't find cs-ezview-cu.svc.cluster.local: No answer
*** Can't find cs-ezview-cu.cluster.local: No answer
*** Can't find cs-ezview-cu.65.3.6: No answer
*** Can't find cs-ezview-cu.dolphin.svc.cluster.local: No answer
*** Can't find cs-ezview-cu.svc.cluster.local: No answer
*** Can't find cs-ezview-cu.cluster.local: No answer
*** Can't find cs-ezview-cu.65.3.6: No answer
从上面看,解析 cs-ezview-cu 域名时,点的个数比配置中 ndots 值小,会按照配置 search 参数填补域名后缀。在第一次填补后缀 cs-ezview-cu.dolphin.svc.cluster.local 就解析出 A记录,这时就会终止dns查询返回A记录结果。
三、解析集群外部域名
下面是抓 www.jd.com 域名 DNS 包结果:

从上图抓包来看,京东域名点的个数比配置中 ndots 值小,会按照配置 search 参数填补域名后缀。依次填补 production.svc.cluster.local.、svc.cluster.local.、cluster.local.都没有查询出结果,后面直接解析 www.jd.com 域名,查询出A记录并返回结果。
使用另外一个命令测试:
root@ga-transit-multidimension-back-7758f58d7d-pgs4g:/etc/sysconfig/network-scripts#host -v www.baidu.com
Trying "www.baidu.com.dolphin.svc.cluster.local"
Trying "www.baidu.com.svc.cluster.local"
Trying "www.baidu.com.cluster.local"
Trying "www.baidu.com.65.3.6"
Trying "www.baidu.com"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12482
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;www.baidu.com. IN A
;; ANSWER SECTION:
www.baidu.com. 30 IN CNAME www.a.shifen.com.
www.a.shifen.com. 30 IN A 180.101.49.12
www.a.shifen.com. 30 IN A 180.101.49.11
Received 138 bytes from 172.21.0.10#53 in 35 ms
Trying "www.a.shifen.com"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49747
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
;; QUESTION SECTION:
;www.a.shifen.com. IN AAAA
;; AUTHORITY SECTION:
a.shifen.com. 30 IN SOA ns1.a.shifen.com. baidu_dns_master.baidu.com. 2007300002 5 5 2592000 3600
Received 124 bytes from 172.21.0.10#53 in 35 ms
Trying "www.a.shifen.com"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31427
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
;; QUESTION SECTION:
;www.a.shifen.com. IN MX
;; AUTHORITY SECTION:
a.shifen.com. 30 IN SOA ns1.a.shifen.com. baidu_dns_master.baidu.com. 2007300002 5 5 2592000 3600
Received 124 bytes from 172.21.0.10#53 in 68 ms
如此一来,在默认配置情况下,在容器内部解析域名的成本还是很高的,大部分的域名都不会有5个.,也就意味着大部分外部域名DNS解析请求都需要5次才能解析成功。
四、解析域名点数大于或者等于ndots配置
解析域名点数大于或者等于ndots配置,又会发生什么事情了?
随便找个外网的泛域名:
点数等于 ndots
root@ga-transit-multidimension-back-7758f58d7d-pgs4g:/etc/sysconfig/network-scripts#host -v asd.asd.asd.asd.lty.com
Trying "asd.asd.asd.asd.lty.com"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 52878
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;asd.asd.asd.asd.lty.com. IN A
;; ANSWER SECTION:
asd.asd.asd.asd.lty.com. 30 IN A 65.254.248.194
Received 80 bytes from 172.21.0.10#53 in 417 ms
Trying "asd.asd.asd.asd.lty.com"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 60759
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
;; QUESTION SECTION:
;asd.asd.asd.asd.lty.com. IN AAAA
;; AUTHORITY SECTION:
lty.com. 30 IN SOA ns1.fatcow.com. dnsadmin.fatcow.com. 2012041904 10800 3600 604800 86400
Received 117 bytes from 172.21.0.10#53 in 386 ms
Trying "asd.asd.asd.asd.lty.com"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41858
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;asd.asd.asd.asd.lty.com. IN MX
;; ANSWER SECTION:
asd.asd.asd.asd.lty.com. 30 IN MX 30 mx.lty.com.
Received 90 bytes from 172.21.0.10#53 in 386 ms
点数大于 ndots:
root@ga-transit-multidimension-back-7758f58d7d-pgs4g:/etc/sysconfig/network-scripts#host -v a.asd.asd.asd.asd.lty.com
Trying "a.asd.asd.asd.asd.lty.com"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48797
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;a.asd.asd.asd.asd.lty.com. IN A
;; ANSWER SECTION:
a.asd.asd.asd.asd.lty.com. 30 IN A 65.254.248.194
Received 84 bytes from 172.21.0.10#53 in 383 ms
Trying "a.asd.asd.asd.asd.lty.com"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34831
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
;; QUESTION SECTION:
;a.asd.asd.asd.asd.lty.com. IN AAAA
;; AUTHORITY SECTION:
lty.com. 30 IN SOA ns1.fatcow.com. dnsadmin.fatcow.com. 2012041904 10800 3600 604800 86400
Received 119 bytes from 172.21.0.10#53 in 399 ms
Trying "a.asd.asd.asd.asd.lty.com"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 37761
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;a.asd.asd.asd.asd.lty.com. IN MX
;; ANSWER SECTION:
a.asd.asd.asd.asd.lty.com. 30 IN MX 30 mx.lty.com.
Received 94 bytes from 172.21.0.10#53 in 397 ms
从上面我们可以得出结论,不管是点数大于或者等于 ndots 配置,都不会匹配 search的配置。
五、优化建议
通过上面案例可以发现ndots的值和请求息息相关,在使用中为了避免过多的DNS查询请求,可以适当优化相应的值或者请求域名。
- 条件允许的情况下,尽量将请求体中的点都带上,并且要大于或者等于配置中的ndots的值。
- 由于自动填补域名后缀是按照配置中的参数依次添加,所以在同一个namespace下,可以直接解析Service名即可。如 nslookup cs-ezview-cu,会自动补全 cs-ezview-cu.dolphin.svc.cluster.local 后缀,且是第一个配置的,因此查询也只有一条。提高DNS解析速度。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!