rke\rke2 集群启用 nodelocal-dns 为 coredns 配置 hosts 不生效
NodeLocal DNS 是 Kubernetes 集群中提升 DNS 性能与稳定性的重要组件。它的核心思想是在每个集群节点上运行一个 DNS 缓存代理,让 Pod 的 DNS 请求优先在本地节点处理,从而绕过传统的 iptables/ipvs 规则,有效降低延迟并避免 conntrack 竞争。
下面这张流程图展示了开启 NodeLocal DNS 前后,DNS 解析路径的变化:
核心架构解析
主要组件
NodeLocal DNS 的实现主要包含以下 Kubernetes 对象:
| 组件名称 | 类型 | 作用 |
|---|---|---|
| node-local-dns | DaemonSet | 在每个节点上运行的 nodelocal-dns 服务。 |
| node-local-dns | ConfigMap | nodelocal-dns 配置文件,如缓存时长、上游服务器地址等。 |
| kube-dns-upstream | Service | nodelocal-dns 上游的 CoreDNS svc。 |
工作流程
- 请求拦截:Pod 的
/etc/resolv.conf被配置为 10.43.0.10,这是一个 svc 地址,它会把请求转发到多个 nodelocal-dns pod ip。 - 本地缓存:Pod 发起 DNS 查询,请求通过 10.43.0.10 svc 地址优先转发到同节点的 nodelocal-dns pod ip。
- 命中/未命中:
- 命中:如果本地有缓存,直接返回结果,速度极快。
- 未命中:nodelocal-dns 通过
kube-dns-upstreamsvc 将请求转发给集群的 CoreDNS 服务,并缓存结果以备后续使用。
- 故障转移:如果 nodelocal-dns pod 不可用,10.43.0.10 svc 地址会把请求转发到其他节点的 nodelocal-dns pod ip,确保服务不中断。
核心优势与解决的问题
相比原生 DNS 架构,NodeLocal DNS 带来了显著的性能和稳定性提升:
- 消除单点与降低延迟:绕过 iptables/ipvs,DNS 请求直接到达本地代理。这不仅避免了 conntrack 竞争,还将平均延迟从毫秒级降至微秒级。
- 提升可靠性:nodelocal-dns 与 CoreDNS 之间可以使用 TCP 协议通信,解决了原生 UDP 存在的丢包和超时重试问题(如“DNS 延迟 30 秒”现象)。
- 减轻 CoreDNS 压力:集群内大量的 DNS 请求被节点本地消化,大幅减少了对中心 CoreDNS Pod 的压力,使其能更稳定地处理服务发现等核心任务。
- 保障混合云/边缘场景:在云边协同场景中,即使专线网络出现抖动或中断,节点上已缓存的 DNS 记录依然可用,增强了业务在弱网环境下的韧性。
部署与使用方式
在 rancher rke\rke2 环境中,可以参考 suse kb 文档 https://support.scc.suse.com/s/kb/360039796672?language=en_US 启用 Nodelocal DNS。
常见问题
coredns 配置中添加 hosts 解析不生效
在一些使用场景中,如果没有外部的 dns 服务器,又需要将外部的服务通过域名的方式引入 k8s 集群内,以供业务 pod 访问。这种场景下,可能需要通过 coredns 的 hosts 功能去添加域名解析规则。但是通过测试发现,在 nodelocal-dns 架构下,添加 coredns 的 hosts 配置后,因为 pod 也无法解析对应的域名。
问题分析
查看 Nodelocal DNS pod 日志,在启迪日志中可以看到类似如下的配置。
cluster.local:53 { |
可以看到配置中分别定义了多个 服务器块,从上往下进行匹配。当请求的域名与某个 服务器块 匹配上,如果本地有缓存,则直接返回结果。如果本地没有缓存,则会把请求转发到通过 forward 定义的上游 dns 服务器。
因此,假设 coredns hosts 配置的域名如下:
.:53 { |
可以看到此域名与前面所有的 服务器块 都不匹配,因此它的请求将通过 .:53 服务器块进行处理。如果本地有缓存,则直接返回结果。如果本地没有缓存,则会把请求转发到通过 forward 定义的上游 dns 服务器。此处定义为 /etc/resolv.conf 配置文件,此文件内容默认与主机的 /etc/resolv.conf 配置文件内容相同。因为外部没有 dns 服务器去解析 hosts 中定义的域名,因此将出现无法解析的报错。
解决方法
根据 k8s 官方文档 https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/#stubdomains-and-upstream-server-configuration 的说明,可以创建一个名为 kube-dns 的 ConfigMap,内容如下。
apiVersion: v1 |
upstreamNameservers 为自定义的上游 dns 服务器地址,此处的地址需要设置为 coredns svc ip。设置好 ip 后导入集群即可,新生成的配置如以下示例,当与所有服务器块无法匹配的请求,都将转发到上游 coredns 服务器去查询。
2026/04/07 13:05:36 [INFO] Using config file: |


