hello云胜

技术与生活

0%

dns解析流程

我们可以通过抓包来理顺dns解析的流程

关于怎么找到pod的pid,请看【k8s运维】pod name与pid互查 (qq.com)

1
2
3
4
# 进入 dns container 的 network namespace
nsenter -n -t pid
# 对 53 端口进行抓包
tcpdump -i eth0 -N udp dst port 53

nsenter -n 是指定进入network命名空间,-t指定pid

53端口为 DNS服务器的服务端口。

另起一个pod进行nslookup

1
nslookup baidu.com dns_container的ip

image-20230919141805456

因为我的集群有多个coredns容器。nslookup的时候指定一下dns_container的ip。这样可以抓全。

image-20230919140745062

可以看到进行了4次dns查询

1
2
3
4
1、 baidu.com.default.svc.cluster.local.
2、 baidu.com.svc.cluster.local.
3、 baidu.com.cluster.local.
4、 baidu.com.

/etc/resolv.conf

为什么会查询这些?原因就是容器的/etc/resolv.conf的配置

1
2
3
4
/# cat /etc/resolv.conf
nameserver 1x.xx.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

查看下我们dns svc,确实是这个ip

image-20230919155658988

FQDN

要完全理解dns解析过程,首先要指导一个名词FQDN。Fully qualified domain name,全限定域名。(以下简称全域名)

全域名要求以.结束。所以你看到上面的dns查询最后都带着.

baidu.com这不是一个fqdn,baidu.com.这才是一个fqdn。

那是不是fqdn有什么关系呢?

规则是,如果是一个fqdn,那么就转发给DNS服务器进行解析。也就是 nameserver 1x.xx.0.10

如果不是一个fqdn,那么这个域名就要和search中的项组合成一个全域名去搜索。

在这里就是

1
2
3
1、 baidu.com.default.svc.cluster.local.
2、 baidu.com.svc.cluster.local.
3、 baidu.com.cluster.local.

这三个。

options ndots:5

这又是什么东西呢?

这个意思是说域名里的点号大于等于这个数字的话就是个全域名fqdn

比如 a.b.c.d.baidu.com 就算不是以点号结尾的,它也是个全域名。会直接交给DNS服务器进行解析。

总之

不管是内部服务名还是外部域名,最终都是交给DNS服务器进行解析。只不过对于非全域名来说要先经过和search域的组装,然后交给DNS服务器进行解析。我们可以利用这一点,对外部域名要用.结束,避免多次无效的dns解析。

另外一点,对于同一namespace下的svc调用,使用直接的svc名字调用,要比svc名.ns名的效率更高。因为svc名.ns名要经过第二次组装才能查询到,而直接的svc名字是第一次查询解析到了。

k8s的dns策略

k8s提供了4种DNS策略,如下:

  • Default: Pod 从运行所在的节点继承名称解析配置。其实就是使用宿主机的 /etc/resolv.conf 来进行解析
  • ClusterFirst: Pod 内的 DNS 优先会使用 k8s 集群内的 DNS 服务,也就是会使用 kubedns 或者 coredns 进行域名解析。如果解析不成功,才会使用宿主机的 DNS 配置进行解析
  • ClusterFirstWithHostNet:对于以 hostNetwork 方式运行的 Pod,这个 POD 中的所有容器都会使用宿主机的 /etc/resolv.conf 配置进行 DNS 查询,但是如果在 Pod 中仍然还想继续使用 k8s 集群 的 DNS 服务时,就需要将 dnsPolicy 设置为应显式设置其 DNS 策略 ClusterFirstWithHostNet
  • None: 不会使用集群和宿主机的 DNS 策略。需要和 dnsConfig 一起配合使用

查看

1
kubectl -n kube-system get deploy coredns -oyaml

image-20230919155434633

目前使用的是Default策略

关于core-dns和kube-dns

CoreDNS 和 Kube-DNS 都是 Kubernetes 集群的 DNS 服务提供者,作用上是完全相同的。

那选谁呢?

主要看性能差异,根据资料来看CoreDNS 更优。

从 Kubernets 1.11 开始,CoreDNS 达到了 GA,kubeadm 使用它来默认安装 Kubernetes。

从Kubernetes 1.13开始,CoreDNS就成了Kubernetes的默认DNS服务器

但是

1
kubectl -n kube-system get svc

看到的却是kube-dns

这是因为容器镜像使用 coredns 而服务名是 kube-dns,这是为了保证应用从 Kube-DNS 迁移到 coredns 时的后向兼容性。

所以我们集群里用的是coreDns。

看deploy的名字就是coredns。