CoreDNS 和 NodeLocalDNS 的域名解析
在 K8s 中,DNS 解析主要涉及以下两个组件:
- CoreDNS:主要负责集群内部域名解析。
- NodeLocalDNS:在节点本地提供 DNS 缓存,用于优化集群 DNS 查询性能。
首先看一下这份的 /etc/resolv.conf 配置文件中各字段的含义:

1 | # 指定搜索域。 |
在 K8s 中,workload 的 dnsPolicy 有四种类型:
ClusterFirst:默认策略。与集群域后缀不匹配的 DNS 查询,例如www.kubernetes.io,会由集群 DNS 服务器转发到上游名称服务器。Default:Pod 会继承所在节点的名称解析配置。ClusterFirstWithHostNet:对于以hostNetwork方式运行的 Pod,如果仍希望使用集群 DNS,应显式设置为ClusterFirstWithHostNet。None:Pod 会使用dnsConfig中显式提供的 DNS 配置。
CoreDNS
CoreDNS 主要负责集群内部域名解析,保证 Pod 可以通过 Service Name 访问集群内的 Service。也可以通过额外配置,使其解析指定的静态 Host。
1 | kind: ConfigMap |
创建一个 dnsPolicy 为 ClusterFirst 的 busybox:

通过这个 busybox 解析集群内部域名,并通过 tcpdump 抓取 53 端口的包:

可以看到,Pod 会根据 search 配置向 CoreDNS 发起多次查询。
请求路径如下:
1 | Pod -> CoreDNS -> Pod |
1 | [root@controller-node-1 ~]# tcpdump -i any -nnvvv 'port 53 and host 10.233.0.3 and host 10.233.74.83' |
通过这个 busybox 解析集群外部域名:

可以看到,对 www.baidu.com 的解析结果是通过上游 DNS 服务器 192.168.0.5 获取到的。
请求路径如下:
1 | Pod -> CoreDNS -> 192.168.0.5 -> CoreDNS -> Pod |
1 | [root@controller-node-1 ~]# tcpdump -i any -nnvvv 'port 53 and ((host 10.233.74.83 and host 10.233.0.3) or host 192.168.0.5)' |
NodeLocalDNS
NodeLocal DNSCache 通过在每个节点上以 DaemonSet 的方式运行 DNS 缓存代理,提升集群 DNS 查询性能。
NodeLocalDNS Pod 中的 /etc/resolv.conf 与宿主机是相同的:

节点上也会有对应的本地监听地址,这个地址取决于 NodeLocalDNS 的启动参数:

在集群启用 NodeLocalDNS 的情况下,Pod 中的 /etc/resolv.conf 会将 nameserver 指向 NodeLocalDNS 的本地监听地址,例如:
1 | nameserver 169.254.25.10 |
解析集群内部域名
对集群内部域名进行解析时,DNS 请求会先发送到 NodeLocalDNS。
如果 NodeLocalDNS 已经缓存了该记录,请求路径如下:
1 | Pod -> NodeLocalDNS -> Pod |
如果 NodeLocalDNS 没有缓存该记录,NodeLocalDNS 会继续向 CoreDNS 查询,请求路径如下:
1 | Pod -> NodeLocalDNS -> CoreDNS -> NodeLocalDNS -> Pod |
下面的抓包结果显示,Pod 向 NodeLocalDNS 发起查询,随后 NodeLocalDNS 直接返回了结果。
1 | [root@controller-node-1 ~]# tcpdump -i any -nnvvv 'port 53 and ((host 10.233.74.83 and host 169.254.25.10) or host 10.233.0.3)' |
解析集群外部域名
对于集群外部域名,NodeLocalDNS 的行为取决于其 Corefile 配置。
常见配置下:
cluster.local这类集群内部域名会由 NodeLocalDNS 转发到 CoreDNS。- 非集群内部域名会由 NodeLocalDNS 转发到上游 DNS 服务器,不一定再次经过 CoreDNS。
在当前环境中,从抓包结果可以看到,www.google.com 的查询由 NodeLocalDNS 转发到了上游 DNS 服务器 192.168.0.5,并没有经过 CoreDNS。
请求路径如下:
1 | Pod -> NodeLocalDNS -> 192.168.0.5 -> NodeLocalDNS -> Pod |
1 | [root@controller-node-1 ~]# tcpdump -i any -nnvvv 'port 53 and ((host 10.233.74.83 and host 169.254.25.10) or host 192.168.0.5 or host 10.233.0.3)' |
总结
未启用 NodeLocalDNS 时,Pod 会直接把 DNS 查询请求发送到 CoreDNS。
1 | Pod -> CoreDNS |
启用 NodeLocalDNS 后,Pod 会优先把 DNS 查询请求发送到节点本地的 NodeLocalDNS。
1 | Pod -> NodeLocalDNS |
对于集群内部域名:
1 | Pod -> NodeLocalDNS -> CoreDNS |
如果 NodeLocalDNS 已经缓存了记录,则可以直接返回:
1 | Pod -> NodeLocalDNS -> Pod |
对于集群外部域名,NodeLocalDNS 是否经过 CoreDNS 取决于 NodeLocalDNS 的 Corefile 配置。在当前环境中,外部域名由 NodeLocalDNS 直接转发到上游 DNS 服务器。
1 | Pod -> NodeLocalDNS -> 上游 DNS |
CoreDNS 和 NodeLocalDNS 的域名解析
https://warnerchen.github.io/2024/03/30/CoreDNS-和-NodeLocalDNS-的域名解析/
install_url to use ShareThis. Please set it in _config.yml.