Cluster DNS: CoreDNS vs KubeDNS

2,973 阅读3分钟

Cluster DNS原理

Cluster DNS策略

  • ClusterFirst 使用这种方式表示 Pod 内的 DNS 优先会使用 k8s 集群内的 DNS 服务,也就是会使用 kubedns 或者 coredns 进行域名解析。如果解析不成功,才会使用宿主机的 DNS 配置进行解析。
  • Default 这种方式,会让 kubelet 来决定 Pod 内的 DNS 使用哪种 DNS 策略。kubelet 的默认方式,其实就是使用宿主机的 /etc/resolv.conf 来进行解析。你可以通过设置 kubelet 的启动参数, --resolv-conf=/etc/resolv.conf 来决定该 DNS 服务使用的解析文件的地址 当我们部署集群 DNS 服务的时候,一般就需要将 dnsPolicy 设置成 Default,而并非使用默认值 ClusterFirst,否则该 DNS 服务的上游解析地址会变成它自身的 Service 的 ClusterIP(我解析我自己),导致域名无法解析。
  • None 这种方式顾名思义,不会使用集群和宿主机的 DNS 策略。而是和 dnsConfig 配合一起使用,来自定义 DNS 配置。
  • ClusterFirstWithHostNet 当一个 Pod 以 HOST 模式(和宿主机共享网络,hostNetwork: true)启动时,这个 POD 中的所有容器都会使用宿主机的 /etc/resolv.conf 配置进行 DNS 查询,但是如果在 Pod 中仍然还想继续使用 k8s 集群 的 DNS 服务时,就需要将 dnsPolicy 设置为 ClusterFirstWithHostNet。

Cluster原理示意图

Cluster DNS

CoreDNS和KubeDNS在资源消耗和性能上的一些关键差异

  • CoreDNS每个实例只使用一个容器,而KubeDNS则使用三个容器。
  • KubeDNS使用单线程的masq缓存集群内部域名,而CoreDNS使用多线程(GO 协程)。
  • CoreDNS会缓存上游域名而KubeDNS不会。

CoreDNS是以插件形式工作的,而KubeDNS则需要dnsmasq、kubedns、sidecar三个容器协协同。 每个实例容器的增加必然会增加基本的内存需求,因为容器间的通信,也会增加一些性能的开销。对于KubeDNS,dnsmasq使用C语言进行了高度优化,但是它是单线程的,这意味着每个实例只能使用单核。另一个方面CoreDNS允许缓存上游域名,这将有助于处理外部域名。

内存方面

CoreDNS和KubeDNS都会在内存中维护Servcie和Endpoint的缓存,因此随着Service和Endpoint的增加,每个DNS Pod的内存压力也会增加。而CoreDNS应该比KubeDNS使用更少的内存。因为CoreDNS Pod中只有一个容器而KubeDNS有三个。

CPU方面

  • KubeDNS在内部域名解析方面要比CoreDNS好10%左右,这可能是因为dnsmasq在内存缓存方面优化的比较好。
  • CoreDNS在外部域名解析方面要比KubeDNS好3倍左右,这是因为KubeDNS没有开启外部域名缓存导致的。然而在KubeDNS中开启外部域名解析并没有显著的性能提升,因此它的性能提升应该是在别的方面。

上述测试使用的Kubernetes 1.2版本。

参考

  1. hansedong.github.io/2018/11/22/…
  2. zhuanlan.zhihu.com/p/39782114
  3. coredns.io/2018/11/27/…