K3s覆盖/etc/resolv.conf是为启用CoreDNS+dnsmasq本地DNS代理,设nameserver 127.0.0.1,但基础镜像常无dnsmasq导致解析失败;需显式配置dnsPolicy或挂载自定义resolv.conf修复。

在 K3s 集群中,Pod 启动后 /etc/resolv.conf 被覆盖为仅含 nameserver 127.0.0.1(或指向 CoreDNS 的本地代理),但实际 CoreDNS 并未监听该地址,或 Pod 网络无法访问该地址,从而导致 DNS 解析失败。
为什么 K3s 会覆盖 resolv.conf?
K3s 默认使用 CoreDNS + dnsmasq 插件(通过 k3s-agent 内置的轻量 DNS 代理)提供集群 DNS 服务。它会自动将 Pod 的 resolv.conf 设置为:
-
nameserver 127.0.0.1(指向 Pod 内部的dnsmasq或coredns本地监听) search.svc.cluster.local svc.cluster.local cluster.local options ndots:5
但这个机制依赖两个前提:Pod 必须运行在支持 hostNetwork: false + dnsPolicy: ClusterFirst 的标准 CNI 网络下,且容器内需有 dnsmasq 或能响应 127.0.0.1:53 的 DNS 代理进程——而大多数基础镜像(如 Alpine、BusyBox、Distroless)并不自带,也**不会自动注入**。
常见触发场景
以下情况容易暴露该问题:
- 使用
hostNetwork: true的 Pod:K3s 不会注入127.0.0.1,但可能仍覆盖原有resolv.conf为错误内容 - 自定义镜像未安装
dnsmasq或coredns,却继承了 K3s 的默认dnsPolicy - 使用
initContainer或多阶段构建时,resolv.conf被挂载覆盖或写入失败 - K3s 版本升级后,
dnsPolicy行为变更(如 v1.25+ 对hostNetworkPod 的处理更严格)
快速修复方法
根据实际需求选择一种或组合使用:
-
显式指定 DNS 配置:在 Pod spec 中设置
dnsPolicy: None并手动提供dnsConfig -
回退到集群 DNS:改用
dnsPolicy: ClusterFirstWithHostNet(仅限hostNetwork: true场景) -
跳过自动覆盖:挂载只读空文件覆盖
/etc/resolv.conf,例如:volumeMounts:- name: resolv-confmountPath: /etc/resolv.confreadOnly: truevolumes:- name: resolv-confconfigMap:name: custom-resolv
其中custom-resolv包含你期望的nameserver 10.43.0.10(K3s CoreDNS ClusterIP) -
验证 CoreDNS 可达性:进入 Pod 执行
nslookup kubernetes.default.svc.cluster.local 10.43.0.10,确认 CoreDNS 是否正常响应
长期建议
避免“覆盖即生效”的隐式行为:
- 所有生产 Pod 显式声明
dnsPolicy,不依赖默认值 - 基础镜像中预装
dnsmasq(仅当需127.0.0.1:53代理)或统一使用ClusterFirst+10.43.0.10 - 通过
kubectl get svc -n kube-system确认 CoreDNS Service 的 ClusterIP(通常是10.43.0.10),并在文档中标注为集群 DNS 地址 - 若使用
hostNetwork,优先考虑dnsPolicy: Default(复用宿主机resolv.conf),并确保宿主机 DNS 可用










