场景
在 Kubernetes 中,我们经常会有直接使用 Service 的名字访问对应 Service 地址的场景。
举个栗子,我们建一个 Service,名字叫 demo-svc
,对应的 ClusterIP
为 10.0.171.239
,端口为 80
。
那么,我们在访问同一个 Namespace 下的这个 Service 时,我们一般会通过一下几种方式之一访问:
- 10.0.171.239:80
- demo-svc:80
- demo-svc.namespace-name.svc.cluster.local:80
注意:如果时要访问不同 Namespace 下,或者集群外部 Service,可以通过
ExternalName
类型的 Service 实现, 但是这是另一个话题,就不展开了。
通过 IP 地址访问的情况自然是不需要解释,通过 Service 名字访问的方式也很自然能想到时通过 DNS 解析实现。
但是, demo-svc
和 demo-svc.namespace-name.svc.cluster.local
之间的区别和关系是什么呢?
原理解析
DNS
查看 Pod 内的 /etc/resolve.conf
,能看到一下内容:
nameserver 10.0.0.10
search namespace-name.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
其中:
10.0.0.10
时 CoreDNS 的 Service 的 IP 地址,我们的请求都会发送到 CoreDNS 解析。search
时 Kubernetes 加上的,顾名思义,解析 DNS 的时候会查找
后面对应的这几个后缀。options ndots:5
这个有意思,当请求的域名里,显式出现少于 5 个点
时,才补上search
的后缀。
值得注意的时 options ndots:5
,显式出现少于 5 个 点
是什么意思呢?
demo-svc.namespace-name.svc.cluster.local
: 有 4 个点,会补全search
中后缀解析demo-svc.namespace-name.svc.cluster.local.
: 有 5 个点,只会使用原域名解析
所以,我们在使用 demo-svc
访问 Service 的时候,DNS 解析时会自动加上 namespace-name.svc.cluster.local
进行解析,得到 demo-svc.namespace-name.svc.cluster.local.
的 IP 地址,
所以,我们在访问 Service 时,最终都是以 demo-svc.namespace-name.svc.cluster.local.
的地址访问的。
补全顺序
上文提到当少于 5 个 点
时,会补全域名再解析,那会按 search
配置中的顺序,
从前往后,依次尝试,还是刚刚的栗子:
demo-svc
在解析时,会尝试:
- demo-svc.namespace-name.svc.cluster.local
- demo-svc.svc.cluster.local
- demo-svc.cluster.local
当然,在尝试 demo-svc.namespace-name.svc.cluster.local
时就已经匹配了,就不会继续尝试后续的了。
验证
怎么来验证上文内容呢,有两个方式:
- 客户端
- 服务端
客户端
上文内容也不外乎是 DNS 解析,既然时 DNS,那少不了的工具就是dig。
dig 是 BIND9 套件中的域名解析工具,至于 BIND9 又是什么,那就可以再花一篇文章来讲了。
本文中,我们可以进到某一个容器中,用 dig
来验证我们的结果。
使用 dig 时, +showsearch
参数会打印出尝试结果:
4 个点,补全:
可以看到,我们访问 demo-svc.namespace-name.svc.cluster.local
时,由于上文提到的,
只有 4 个点,所以自动补全搜索了:
如果我们访问 demo-svc
也是一样的结果,只是第一次补全就会看到成功。
# 进入容器
kubectl exec -it pod-name bash
# root@pod-name:/#
# 使用 4 个点的域名,用于验证 4 个点的补全
dig demo-svc.namespace-name.svc.cluster.local +showsearch
# ; <<>> DiG 9.11.3-1ubuntu1.7-Ubuntu <<>> demo-svc.namespace-name.svc.cluster.local +showsearch
# ;; global options: +cmd
# ;; Got answer:
# ;; WARNING: .local is reserved for Multicast DNS
# ;; You are currently testing what happens when an mDNS query is leaked to DNS
# ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 44747
# ;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
# ;; WARNING: recursion requested but not available
#
# ;; OPT PSEUDOSECTION:
# ; EDNS: version: 0, flags:; udp: 4096
# ; COOKIE: 0e9627a231a03702 (echoed)
# ;; QUESTION SECTION:
# ;demo-svc.namespace-name.svc.cluster.local.namespace-name.svc.cluster.local. IN A
#
# ;; AUTHORITY SECTION:
# cluster.local. 5 IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 1567162775 7200 1800 86400 5
#
# ;; Query time: 0 msec
# ;; SERVER: 10.0.0.10#53(10.0.0.10)
# ;; WHEN: Fri Aug 30 11:06:19 UTC 2019
# ;; MSG SIZE rcvd: 200
#
#
# ; <<>> DiG 9.11.3-1ubuntu1.7-Ubuntu <<>> demo-svc.namespace-name.svc.cluster.local +showsearch
# ;; global options: +cmd
# ;; Got answer:
# ;; WARNING: .local is reserved for Multicast DNS
# ;; You are currently testing what happens when an mDNS query is leaked to DNS
# ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 53786
# ;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
# ;; WARNING: recursion requested but not available
#
# ;; OPT PSEUDOSECTION:
# ; EDNS: version: 0, flags:; udp: 4096
# ; COOKIE: 0e9627a231a03702 (echoed)
# ;; QUESTION SECTION:
# ;demo-svc.namespace-name.svc.cluster.local.svc.cluster.local. IN A
#
# ;; AUTHORITY SECTION:
# cluster.local. 5 IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 1567162775 7200 1800 86400 5
#
# ;; Query time: 0 msec
# ;; SERVER: 10.0.0.10#53(10.0.0.10)
# ;; WHEN: Fri Aug 30 11:06:19 UTC 2019
# ;; MSG SIZE rcvd: 188
#
#
# ; <<>> DiG 9.11.3-1ubuntu1.7-Ubuntu <<>> demo-svc.namespace-name.svc.cluster.local +showsearch
# ;; global options: +cmd
# ;; Got answer:
# ;; WARNING: .local is reserved for Multicast DNS
# ;; You are currently testing what happens when an mDNS query is leaked to DNS
# ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 1277
# ;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
# ;; WARNING: recursion requested but not available
#
# ;; OPT PSEUDOSECTION:
# ; EDNS: version: 0, flags:; udp: 4096
# ; COOKIE: 0e9627a231a03702 (echoed)
# ;; QUESTION SECTION:
# ;demo-svc.namespace-name.svc.cluster.local.cluster.local. IN A
#
# ;; AUTHORITY SECTION:
# cluster.local. 5 IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 1567162775 7200 1800 86400 5
#
# ;; Query time: 0 msec
# ;; SERVER: 10.0.0.10#53(10.0.0.10)
# ;; WHEN: Fri Aug 30 11:06:19 UTC 2019
# ;; MSG SIZE rcvd: 184
#
#
# ; <<>> DiG 9.11.3-1ubuntu1.7-Ubuntu <<>> demo-svc.namespace-name.svc.cluster.local +showsearch
# ;; global options: +cmd
# ;; Got answer:
# ;; WARNING: .local is reserved for Multicast DNS
# ;; You are currently testing what happens when an mDNS query is leaked to DNS
# ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 8827
# ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
# ;; WARNING: recursion requested but not available
#
# ;; OPT PSEUDOSECTION:
# ; EDNS: version: 0, flags:; udp: 4096
# ; COOKIE: 0e9627a231a03702 (echoed)
# ;; QUESTION SECTION:
# ;demo-svc.namespace-name.svc.cluster.local. IN A
#
# ;; ANSWER SECTION:
# demo-svc.namespace-name.svc.cluster.local. 5 IN A 10.102.159.83
#
# ;; Query time: 0 msec
# ;; SERVER: 10.0.0.10#53(10.0.0.10)
# ;; WHEN: Fri Aug 30 11:06:19 UTC 2019
# ;; MSG SIZE rcvd: 129
5 个点,不补全
当访问域名有 5 个点时,就不会尝试补全,如完整的 demo-svc.namespace-name.svc.cluster.local.
:
# 进入容器
kubectl exec -it pod-name bash
# root@pod-name:/#
# 使用 5 个点的域名,用于验证 5 个点的不补全