聊聊 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 包结果:

mark

从上图抓包来看,京东域名点的个数比配置中 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 协议 ,转载请注明出处!