暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

简浅分析kubernetes中DNS解析过程

ProdanLabs 2019-05-08
1005

背景

近期接触的微服务项目是基于DNS实现服务的注册与发现,整体项目半容器化。如项目全部容器化并迁移至kubernetes集群,假设在不使用kubernetes集群中的DNS做服务注册与发现的前提下,引出一个思考——Kubernetes集群中是如何解析外部域名的?


kubernetes DNS简述

Kuberentes通过将Service注册到DNS中,可以为我们提供一种简单的服务注册发现与负载均衡方式。

CoreDNS是第四个从CNCF毕业的项目,是一个通用、权威的DNS服务,从Kubernetes 1.11版本开始正式GA,替代KubeDNS成为默认的DNS,CoreDNS提供与Kubernetes后向兼容且可扩展的集成。它解决了kube-dns所遇到的问题,并提供了许多独特的功能,可以解决各种各样的用例。kube-dns和CoreDNS的差异可以去社区了解下。


Kubernetes中域名是如何解析的

Kubernetes内部域名解析,依赖容器内resolv.conf文件的配置。Pod运行后,kubelet会自动在容器中创建域名解析配置。

# cat /etc/resolv.conf 
nameserver 10.254.0.2
search default.svc.cluster.local. svc.cluster.local. cluster.local.
options ndots:5


配置中DNS Server是CoreDNS的ClusterIP,在容器内,会根据resolve.conf配置进行解析,例如有一个nginx的service,DNS解析时用字符'nginx'依次带入resolve.conf中的 search 域,进行DNS查找,即

nginx.default.svc.cluster.local -nginx.svc.cluster.local -nginx.cluster.local ,直到找到为止。

配置中ndots:5表示如果查询的域名包含的点".",在Kubernetes中默认值为5,是因为Kubernetes认为内部域名最长为5,要保证内部域名的请求优先走集群内部的DNS,而不是将内部域名的DNS解析请求有外网的机会,ndots的值为5是一个比较合理的值。

<5先走search域,最后将其视为绝对域名进行查询
>=5直接视为绝对域名进行查找,只有当查询不到的时候,才继续走search域

对于跨Namespace的情况,服务名后边对应Namespace即可,如edgecontroller.kubeedge

# nslookup edgecontroller.kubeedge
Server:    10.254.0.2
Address 1: 10.254.0.2 kube-dns.kube-system.svc.cluster.local

Name:      edgecontroller.kubeedge
Address 1: 10.254.67.34 edgecontroller.kubeedge.svc.cluster.local

# curl https://edgecontroller.kubeedge:10000 -k
404 page not found


所以在同个Namespace下,执行 curl nginx,或者执行 curl nginx.default,都可以完成DNS请求:

# curl nginx
Welcome to nginx

# curl nginx.default
Welcome to nginx
#

这2个不同的操作,会分别进行不同的DNS查找步骤:

#curl nginx ,可以一次性找到(nginx + default.svc.cluster.local)
nginx.default.svc.cluster.local

#curl nginx.default,第一次找不到( nginx.default + default.svc.cluster.local)
nginx.default.default.svc.cluster.local
#第二次查找( nginx.default + svc.cluster.local),可以找到
nginx.default.svc.cluster.local

So,curl nginx要比curl nginx.default效率高,当执行带有Namespace的内部域名时,容器的第一个DNS请求是default.svc.cluster.local。

Kubernetes中外部域名走search域吗

以请求www.baidu.com为例,通过抓包的方式,看一看在某个容器中访问www.baidu.com,进行的DNS查找的过程,都产生了什么样的数据包。

#1、找到DNS容器ID,并打印它的NS ID
docker ps | grep k8s_coredns | awk '{print $1}' | xargs docker inspect --format "{{.State.Pid}}" 

#2、进入此容器的网络Namespace
nsenter -n -t  54438

#3、抓DNS包
[root@kube-master ~]# tcpdump -i eth0 udp dst port 53|grep baidu
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
15:40:01.105204 IP 192.168.59.2.46993 > kube-master.domain: 3+ AAAA? www.baidu.com. (31)
15:40:01.105530 IP kube-master.44160 > gateway.domain: 3+ AAAA? www.baidu.com. (31)
15:40:02.556701 IP 192.168.59.2.49297 > kube-master.domain: 4+ A? www.baidu.com. (31)
15:40:02.556942 IP kube-master.44160 > gateway.domain: 4+ A? www.baidu.com. (31)1

可以看到访问外部域名不走search域。CoreDNS通过apiserver+etcd来获得内部Service的A记录以区分内外部域名,访问外部域名时,CoreDNS通常会获取当前node的resolv.conf的配置进行解析,当node的resolv.conf中没有配置dns时,会使用8.8.8.8和8.8.4.4。

当node的resolv.conf配置无法解析域名时,CoreDNS会在search域进行查找

[root@kube-master ]# tcpdump  udp dst port 53 |grep ww.k10s.com
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
16:23:03.774024 IP 192.168.59.2.43274 > kube-master.domain: 3+ AAAA? www.k10s.com. (30)
16:23:03.774383 IP kube-master.56700 > gateway.domain: 3+ AAAA? www.k10s.com. (30)
16:23:05.774764 IP kube-master.45589 > gateway.domain: 3+ AAAA? www.k10s.com. (30)
16:23:07.775035 IP kube-master.52035 > gateway.domain: 3+ AAAA? www.k10s.com. (30)
16:23:07.900422 IP 192.168.59.2.55185 > kube-master.domain: 4+ AAAA? www.k10s.com.default.svc.cluster.local. (56)
16:23:07.900814 IP 192.168.59.2.49646 > kube-master.domain: 5+ AAAA? www.k10s.com.svc.cluster.local. (48)
16:23:07.901088 IP 192.168.59.2.46749 > kube-master.domain: 6+ AAAA? www.k10s.com.cluster.local. (44)
16:23:07.901324 IP 192.168.59.2.48158 > kube-master.domain: 7+ A? www.k10s.com. (30)
16:23:07.901486 IP kube-master.52035 > gateway.domain: 7+ A? www.k10s.com. (30)
16:23:08.588050 IP 192.168.59.2.35448 > kube-master.domain: 8+ A? www.k10s.com.default.svc.cluster.local. (56)
16:23:08.588377 IP 192.168.59.2.39284 > kube-master.domain: 9+ A? www.k10s.com.svc.cluster.local. (48)
16:23:08.588591 IP 192.168.59.2.41323 > kube-master.domain: 10+ A? www.k10s.com.cluster.local. (44)


对于局域网或特殊域名,可以在Corefile配置文件指定的DNS,如

    master.open.com:53 {
        errors
        cache 30
        proxy . 192.168.59.1
    }


文章转载自ProdanLabs,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论