从DNS 说起
DNS 解析是一种按照层级的树形结构,从左到右,DNS trace 记录来看 DNS 解析过程,以shikanon.com
域名为例。
dig +trace +additional shikanon.com ; <<>> DiG 9.17.11 <<>> +trace +additional shikanon.com ;; global options: +cmd . 75043 IN NS a.root-servers.net. . 75043 IN NS b.root-servers.net. . 75043 IN NS c.root-servers.net. . 75043 IN NS d.root-servers.net. . 75043 IN NS e.root-servers.net. . 75043 IN NS f.root-servers.net. . 75043 IN NS g.root-servers.net. ... . 75043 IN RRSIG NS 8 0 518400 20210509170000 20210426160000 14631 . DWFiIzpkoh7coUyEcXIOcie8Zrx7oLY89vxCdwpdaybkn0Y8MtzGDbQP AHhwVI7ukMr4PLL+ZzkT6KL1R84mRFUHLbGLq+q3zkdMVGaDhtxBGRbb sNaAjwu6Vhh4RO8ttaL9RrNz13dE/j3WDT7QLcINF/ziuHO6EXFfmVBW NoOim5G8NpoFznY6UCnKxHJst0I5Yh0ylr+3d3jn+mUtauXENzSAjkdF tNboXD1euInf37XSoRedk+cfWdIbxGqbDHhkCHkK+QVhAPeArtu5PFlW cjB8wCPa6ixElr85+kcxMD2qFogn/H761o+O0p16EHi7Yld7jOficWhE ivBSBA== ;; Received 525 bytes from 8.8.8.8#53(8.8.8.8) in 22 ms com. 172800 IN NS a.gtld-servers.net. com. 172800 IN NS b.gtld-servers.net. com. 172800 IN NS c.gtld-servers.net. com. 172800 IN NS d.gtld-servers.net. com. 172800 IN NS e.gtld-servers.net. com. 172800 IN NS f.gtld-servers.net. com. 172800 IN NS g.gtld-servers.net. ... com. 86400 IN DS 30909 8 2 E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CF C41A5766 com. 86400 IN RRSIG DS 8 1 86400 20210510050000 20210427040000 14631 . Kvswc0aZK0YwTSFQMruGPGYhEZHKHhr0XyL53SKqEYTT3pNda3PlEBJs rVpG2WmQOaZVZway5rVwcM3OkPu0ZwnXyRkoNiDqcQ7sDcUMZgK7s5Ji pVN2MYNDIG4z09iKywV/cnnSTtcWNPb34riLwbbiWy6iycD6GEFdU2nb Lnn8q4DqjPRKXKIzdHsAl1/tB/5ywplfcicpoW5MIh8+D2cPFrxtoSER 0bnhKPbtRm7S7yTg9APsBAWu/FQqvURspM063aC/n22sMANsY+0mkwaQ W8y4vycVZzHmDmMZRUkBYKgzuT0BAabaugn5+IttfPFv1sCfbw/B6WNE T0cjCA== a.gtld-servers.net. 172800 IN A 192.5.6.30 a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30 b.gtld-servers.net. 172800 IN A 192.33.14.30 b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30 c.gtld-servers.net. 172800 IN A 192.26.92.30 c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30 d.gtld-servers.net. 172800 IN A 192.31.80.30 d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30 e.gtld-servers.net. 172800 IN A 192.12.94.30 e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30 f.gtld-servers.net. 172800 IN A 192.35.51.30 f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30 g.gtld-servers.net. 172800 IN A 192.42.93.30 ... ;; Received 1200 bytes from 199.9.14.201#53(b.root-servers.net) in 43 ms shikanon.com. 172800 IN NS dns9.hichina.com. shikanon.com. 172800 IN NS dns10.hichina.com. CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN NSEC3 1 1 0 - CK0Q1GIN43N1ARRC9OSM6QPQR81H5M9A NS SOA RRSIG DNSKEY NSEC3PARAM CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN RRSIG NSEC3 8 2 86400 20210504042422 20210427031422 54714 com. oLUUax7mu4pOh0FOU9OStzy6RiNIQR7TS3iGwn64IF6WVtoV6bRVAq/d Fb+ZEDsTG8yj8vcTvgjHjXeUpwz25/ji5d9U1RDBZsxf2w0qKyCJUNH5 SxyvnOkUjvR/cR1v7/jxUfd6QX54UP5dnleap6XAkUcZhOC1cqd3j5qY JFKSa8/NQYfs/xtcdEgr6NAmqbEedtUDT+vLUWD0ifPcWw== 747SBSSOT560BBODGVDAM6IMH3SFUDAO.com. 86400 IN NSEC3 1 1 0 - 747SODOSAS4ANKCQRO7QCOF5H6R1KAH1 NS DS RRSIG 747SBSSOT560BBODGVDAM6IMH3SFUDAO.com. 86400 IN RRSIG NSEC3 8 2 86400 20210504043357 20210427032357 54714 com. YzpSc5yjeEzD37ZGPBI/lsIUHocvmyENBtxZTBGm0TE2aY3tNm9F4rrc VGoplqREzYwK3y/XIPlqV3VVa/E6MsyM9x3gDIjt5/ISONjqW5ZGgF4J 3P8fd8/SXj/NSz1V36uv4lWa3FuVZN+a/U2N/PP8KtvWi5cy66jG4mvb G53lPkvpGw3TOGG52KBS9rSys3DoadUtfFjXwVR+/xYUEQ== dns9.hichina.com. 172800 IN A 106.11.141.115 dns9.hichina.com. 172800 IN A 106.11.141.125 dns9.hichina.com. 172800 IN A 106.11.211.55 dns9.hichina.com. 172800 IN A 106.11.211.65 dns9.hichina.com. 172800 IN A 140.205.41.15 dns9.hichina.com. 172800 IN A 140.205.41.25 dns9.hichina.com. 172800 IN A 140.205.81.15 dns9.hichina.com. 172800 IN A 140.205.81.25 dns9.hichina.com. 172800 IN AAAA 2400:3200:2000:28::1 dns10.hichina.com. 172800 IN A 106.11.141.116 dns10.hichina.com. 172800 IN A 106.11.141.126 ... dns10.hichina.com. 172800 IN AAAA 2400:3200:2000:29::1 ;; Received 949 bytes from 192.43.172.30#53(i.gtld-servers.net) in 56 ms shikanon.com. 600 IN A 118.24.8.219 ;; Received 57 bytes from 140.205.81.15#53(dns9.hichina.com) in 23 ms
域名本质是个树形结构,最顶层是根域名,一般使用 .
来表示,通常在写域名的时候省略,比如shikanon.com
,其全称域名是shikanon.com.
。
通过dig trace
可以看到,首先去找根域名.
,根域名返回的是全球十三个根服务器 xxx.root-servers.net.
,我们从8.8.8.8#53
得到根服务器地址,
然后从根服务器199.9.14.201#53(b.root-servers.net)
地址解析出次级域名服务器的NS和A地址:
com. 172800 IN NS a.gtld-servers.net. com. 172800 IN NS b.gtld-servers.net. com. 172800 IN NS c.gtld-servers.net. ... a.gtld-servers.net. 172800 IN A 192.5.6.30 a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30 b.gtld-servers.net. 172800 IN A 192.33.14.30 b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30 c.gtld-servers.net. 172800 IN A 192.26.92.30 ... ;; Received 1200 bytes from 199.9.14.201#53(b.root-servers.net) in 43 ms
通过迭代查询,最终找到目标域名IP地址。
CoreDNS: 云原生服务发现利器
CoreDNS 是一个用 Go 语言 Caddy 框架编写的 HTTP/2 Web 服务器。
本地搭建一个CoreDNS服务。首先,创建一个Corefile
配置文件:
.:5351 { errors hosts { 192.168.22.63 shikanon.local fallthrough } log }
CoreDNS 支持链式插件,CoreDNS的插件可以在官方文档下 pulgin 找到。这里配置了一个根域名.
监听 5351 端口,根域名服务下启用了三个插件,errors,hosts, log。
errors插件表示开启错误日志; hosts插件支持/etc/hosts
文件,shikanon.local
域名解析到192.168.22.63
;log插件可以开启所有DNS查询日志。
运行CoreDNS容器:
$ docker run --rm-it--name coredns -p5351:5351/udp -v E:/demo/test/coredns/Corefile:/root/Corefile coredns/coredns:1.8.3 -conf /root/Corefile
本地测试:
$ dig @127.0.0.1 -p5351 shikanon.local ; <<>> DiG 9.17.11 <<>> @127.0.0.1 -p5351 shikanon.local ; (1 server found) ;; 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: 64734;; 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: 1232; COOKIE: 54a5ef944ca0c44a (echoed) ;; QUESTION SECTION: ;shikanon.local. IN A ;; ANSWER SECTION: shikanon.local. 3600 IN A 192.168.22.63 ;; Query time: 14 msec ;; SERVER: 127.0.0.1#5351(127.0.0.1) (UDP);; WHEN: Tue Apr 2718:57:16 ;; MSG SIZE rcvd: 85
CoreDNS 支持链式插件,我们可以直接在配置文件后面添加即可。coredns插件:https://coredns.io/explugins/
在k8s中做DNS
pod DNS 策略配置
k8s 提供了 pod 级别的DNS策略,dnsPolicy
主要影响pod中的 /etc/resolv.conf
,dnsPolicy
总提供了四种 DNS 配置方式:
ClusterFirst
模式,使用集群的dns配置,k8s的默认设置,ClusterFirst会用k8s集群提供的dns服务器来解析,由 kubelet 的 –cluster-dns 参数提供集群中 dns 服务器的ip地址,然后安装用这个 ip 安装 coredns 或 kube-dns,从而提供 dns 服务。Default
模式,直接从节点挂载/etc/resolv.conf
到pod容器,从而继承节点命名解析服务。ClusterFirstWithHostNet
模式,是使用 hostNetwork 模型下启用集群dns服务,需配合hostNetwork: true
使用None
模式,不加载k8s的dns配置,一般None
模式会配合dnsConfig
一起使用,用作自定义dns服务。
注:kubelet 提供了--cluster-dns
参数,这个参数用来填写集群默认dns服务器地址,作用于Pod 中设置了 “dnsPolicy=ClusterFirst” 的容器。--cluster-dns
后面跟的DNS服务器可以是多个,以 ,
分割,所有 DNS 服务器必须包含相同的记录组。
使用dnsConfig自定义 dns 解析
dnsConfig 本质会映射到pod的/etc/resolv.conf
文件中,因此其和/etc/resolv.conf
文件是一样的,包括nameservers
,searches
和options
三部分。
- nameservers:将用作于 Pod 的 DNS 服务器的 IP 地址列表。 最多可以指定 3 个 IP 地址。当 Pod 的 dnsPolicy 设置为 “None” 时, 列表必须至少包含一个 IP 地址,否则此属性是可选的。 所列出的服务器将合并到从指定的 DNS 策略生成的基本名称服务器,并删除重复的地址。
- searches:用于在 Pod 中查找主机名的 DNS 搜索域的列表。此属性是可选的。 指定此属性时,所提供的列表将合并到根据所选 DNS 策略生成的基本搜索域名中。 重复的域名将被删除。Kubernetes 最多允许 6 个搜索域。
- options:可选的对象列表,其中每个对象可能具有 name 属性(必需)和 value 属性(可选)。 此属性中的内容将合并到从指定的 DNS 策略生成的选项。 重复的条目将被删除。
k8s中构建自己的DNS服务
这里介绍一个自建的 coredns 服务,用来用来解析shikanon.local
相关的域名服务,服务上游是集群的coredns地址,也就是不匹配shikano.local
域名的交给集群coredns解析。
首先我们构建 coredns 的配置:
apiVersion v1 data Corefile - .:5353 bind $POD_IP errors template IN A shikanon.local match .*\.shikanon\.local answer "{{ .Name }} 60 IN A 192.168.1.1" fallthrough forward . 10.247.3.10 log kind ConfigMap metadata labels app rcmd-coredns k8s-app rcmd-coredns name rcmd-coredns namespace coredns
对配置介绍下,通过 template 插件匹配了所有*.shikanon.local
的服务,并答复其A地址为192.168.1.1
,template插件没匹配的,用 forward插件将所有域名.
查询上游10.247.3.10
,这个IP是集群的coredns的ip地址。.:5353
表示其监听的是5353
端口。
部署一个 coredns 的 deployment 和 service:
apiVersion v1 kind Service metadata labels app rcmd-coredns k8s-app rcmd-coredns name rcmd-coredns namespace coredns spec clusterIP10.247.3.15 portsname dns port53 protocol UDP targetPort5353 selector app rcmd-coredns k8s-app rcmd-coredns type ClusterIP ---apiVersion apps/v1 kind Deployment metadata labels app rcmd-coredns k8s-app rcmd-coredns name rcmd-coredns namespace coredns spec replicas1 selector matchLabels app rcmd-coredns k8s-app rcmd-coredns template metadata labels app rcmd-coredns k8s-app rcmd-coredns spec containersargs -conf /root/Corefile image coredns/coredns1.8.3 name rcmd-coredns envname POD_IP valueFrom fieldRef apiVersion v1 fieldPath status.podIP portscontainerPort5353 protocol UDP volumeMountsmountPath /root name rcmd-coredns dnsPolicy Default volumesconfigMap defaultMode420 name rcmd-coredns name rcmd-coredns
这里主要包括两部分,一个是deployment,用于运行 coredns 的pod,他挂载了coredns的配置文件,监听的5353
端口,协议是UDP(coredns也支持TCP协议),service 的 clusterIP 是固定下来的,因为这个 DNS 要给其他 pod 使用,所以需要设置一个固定的 IP。
部署好后,我们部署一个设置自建 coredns 作为DNS服务器的 demo 容器:
apiVersion apps/v1 kind Deployment metadata labels app tools-jupyter name tools-jupyter namespace rcmd spec replicas1 selector matchLabels app tools-jupyter template metadata labels app tools-jupyter spec containerscommand jupyter notebook --allow-root --port=8000 value"0" image swr.cn-north-4.myhuaweicloud.com/hw-zt-k8s-images/tools-jupyter python-3.8.6 name tools-jupyter dnsPolicy None dnsConfig nameservers 10.247.3.15 searches"rcmd.svc.cluster.local""svc.cluster.local""cluster.local" optionsname ndots value"5"name single-request-reopen name timeout value"2"
设置dnsPolicy: None
,然后启用自己的 DNS 服务设置dnsConfig
,这里其实是将 k8s 的默认配置抄了过来,将 nameservers 改为我们自建的dns服务器地址。
进入容器中可以看到/etc/resolv.conf
已经更改:
cat /etc/resolv.conf nameserver 10.247.3.15 search rcmd.svc.cluster.local svc.cluster.local cluster.local options ndots:5 single-request-reopen timeout:2 |
测试域名:
dig aaa.52tt.local ; <<>> DiG 9.16.1-Ubuntu <<>> aaa.shikanon.local ;; 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: 31512;; 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: 647ae237c8dc9760 (echoed) ;; QUESTION SECTION: ;aaa.shikanon.local. IN A ;; ANSWER SECTION: aaa.shikanon.local. 60 IN A 192.168.1.1 ;; Query time: 2 msec ;; SERVER: 10.247.3.15#53(10.247.3.15);; WHEN: Thu Apr 2902:40:05 UTC 2021;; MSG SIZE rcvd: 85
返回了我们设置的IP地址,这样就实现了一个兼容集群解析的自定义的DNS服务器做泛域名解析。
这里给大家留个小问题,采用组件子DNS服务器和直接配置集群DNS服务器的方式这两种有何异同,分别适用什么样的场景?