coredns 必须作为 pod 运行在集群内,因其依赖 kubelet 自动配置 pod 的 /etc/resolv.conf 指向 clusterip、需 serviceaccount 权限实时 watch api 获取服务信息,且 kubelet 必须通过 --cluster-dns 参数显式指定其地址,宿主机进程无法满足这些协同机制。

CoreDNS 本身不直接在 Linux 主机上“安装并配置”来为 K8s 提供 DNS 解析——它必须运行在 Kubernetes 集群内部(作为 Pod),由 kubelet 管理,且依赖 ServiceAccount、RBAC、ConfigMap 和 Deployment 等原生资源。你在宿主机(Linux)上手动装一个 coredns 二进制,对集群 DNS 完全无效。
为什么不能在 Linux 宿主机上直接运行 CoreDNS 来服务 K8s?
因为 K8s 的 DNS 解析链路是硬编码协同的:
-
/etc/resolv.conf在每个 Pod 内部自动生成,指向的是Service类型为ClusterIP的coredns服务(如169.169.0.100),不是宿主机的127.0.0.1:53 - Kubernetes 的
kubelet启动参数必须显式指定--cluster-dns=169.169.0.100和--cluster-domain=cluster.local,否则 Pod 不会把 DNS 请求发给 CoreDNS - CoreDNS Pod 必须使用
ServiceAccount访问 API Server 获取 Service/Pod 列表——宿主机进程没有这个权限上下文 - CoreDNS 的
kubernetes插件依赖实时 watch Kubernetes API,不是读取本地文件或静态 hosts
正确部署 CoreDNS 的三个必要资源对象
你必须在 kube-system 命名空间中同时创建以下三类资源(缺一不可):
-
ConfigMap:存放Corefile,定义监听端口、插件顺序、kubernetes 域范围、上游转发逻辑等 -
Deployment:运行coredns/coredns镜像,挂载 ConfigMap,并设置args: ["-conf", "/etc/coredns/Corefile"] -
Service:类型为ClusterIP,固定 IP(如169.169.0.100),端口53/UDP和53/TCP,selector 匹配 Deployment 的 label
漏掉 Service,Pod 的 /etc/resolv.conf 就没地方写;漏掉 ConfigMap,CoreDNS 启动后无法解析 my-svc.default.svc.cluster.local;漏掉 RBAC 权限,日志里会刷满 Unauthorized 错误。
修改 kubelet 启动参数是生效前提
仅部署 CoreDNS 资源还不够,每个 Node 上的 kubelet 必须明确知道 DNS 服务地址:
- 编辑
/var/lib/kubelet/config.yaml或启动脚本中的KUBELET_EXTRA_ARGS - 确保包含:
--cluster-dns=169.169.0.100(必须和 CoreDNS Service 的clusterIP一致) - 确保包含:
--cluster-domain=cluster.local(必须和 Corefile 中kubernetes插件声明的域一致) - 改完后执行:
systemctl restart kubelet,否则新 Pod 仍会用默认或错误的 DNS 配置
常见错误:CoreDNS Pod Running,但 nslookup kubernetes.default.svc.cluster.local 超时——八成是 kubelet 没配 --cluster-dns,或者配错了 IP。
验证 CoreDNS 是否真正可用
不要只看 Pod 状态,要进容器测真实解析路径:
- 先确认 CoreDNS Pod 是 Running:
kubectl get pod -n kube-system -l k8s-app=kube-dns - 进任意业务 Pod:
kubectl exec -it <code>your-pod-- sh - 检查
/etc/resolv.conf第一行是否为nameserver 169.169.0.100(不是127.0.0.1或宿主机 DNS) - 执行:
nslookup kubernetes.default.svc.cluster.local 169.169.0.100(直连 CoreDNS,绕过 resolv.conf 缓存) - 若返回
Address: 169.169.0.1(即 kubernetes Service 的 ClusterIP),说明解析链路通了
最容易被忽略的是:CoreDNS 默认配置里的 fallthrough in-addr.arpa ip6.arpa 会影响反向解析,而某些监控工具(如 Prometheus node_exporter)会查 1.0.169.169.in-addr.arpa,漏掉这行会导致健康检查失败。











