Kube-dns 已被 CoreDNS 取代,Kubernetes 1.13+ 默认不再部署 kube-dns;直接部署 kube-dns 不仅不兼容新集群,还会因缺失 RBAC、健康探针和插件支持导致解析失败或服务不可用。

为什么不能直接部署 kube-dns
新版 Kubernetes(v1.13 起)已移除 kube-dns 的 manifests 和官方维护支持。尝试用旧 yaml 部署会出现以下典型问题:
-
kube-dnsDeployment 启动后持续CrashLoopBackOff,日志提示failed to list *v1.Service: Unauthorized—— 缺少 ServiceAccount 绑定的 ClusterRole - 即使 Pod 运行成功,
dig my-svc.default.svc.cluster.local @10.96.0.10返回NOERROR但ANSWER SECTION为空 —— kube-dns 不支持 Headless Service 的 A 记录聚合逻辑,也不处理ndots:5等 DNS 策略 - 无法解析
headless-svc.namespace.svc.cluster.local的多个 Pod IP,net.LookupIP始终只返回一个或报no such host - CoreDNS 默认启用
kubernetes插件并内置 endpoint watch 机制,而 kube-dns 依赖已废弃的kubedns进程 +dnsmasq组合,无原生 SRV/A 记录动态生成能力
应该部署 CoreDNS 而不是 kube-dns
所有现代 Kubernetes 集群都使用 CoreDNS 作为默认 DNS 服务。部署方式不是“手动安装”,而是确保其已启用并配置正确:
- 检查是否运行:
kubectl get pods -n kube-system -l k8s-app=kube-dns—— 若返回空,说明用的是 CoreDNS;正确命令是kubectl get pods -n kube-system -l k8s-app=coredns - 确认配置:
kubectl get configmap coredns -n kube-system -o yaml,重点看plugins.kubernetes是否包含endpoint和pod参数,例如:kubernetes cluster.local in-addr.arpa ip6.arpa { pods verified fallthrough in-addr.arpa ip6.arpa } - 若集群未部署 CoreDNS(如某些定制化 K8s 发行版),应使用官方 manifest:
https://github.com/coredns/deployment/blob/master/kubernetes/coredns.yaml.sed,而非任何 kube-dns 的历史版本 yaml - 不要修改
Corefile中的forward . /etc/resolv.conf行为 —— 它负责将外部域名查询转发给上游 DNS;内部服务域名(*.svc.cluster.local)由kubernetes插件直连 API Server 处理,不走转发链路
Go 应用必须适配 CoreDNS 解析行为
即便 CoreDNS 正常运行,Go 程序仍可能解析失败,根本原因在于调用方式与 DNS 协议理解错位:
- 必须用
net.LookupIP("my-svc.default.svc.cluster.local"),而非net.LookupHost—— 后者在 Headless Service 场景下只返回单个随机 IP 或空列表 - 域名必须是完整 FQDN:
my-svc.default.svc.cluster.local,不能省略.svc.cluster.local;否则 Go 的纯 Go resolver(PreferGo: true)不会补全搜索路径,系统 resolver 也可能回退到公网 DNS - 确保 Go 程序运行在集群内 Pod 中:
/etc/resolv.conf的nameserver必须指向 CoreDNS Service IP(通常是10.96.0.10),且search包含default.svc.cluster.local svc.cluster.local cluster.local - 避免全局设置
net.DefaultResolver = &net.Resolver{PreferGo: true}—— 它绕过/etc/resolv.conf的ndots和search,导致短域名无法自动补全,且不支持 EDNS,高并发下易丢包
真正关键的不是“部署哪个 DNS 服务”,而是 Go 代码是否按 CoreDNS 的协议语义发起查询:FQDN、LookupIP、集群内运行、不干预系统 resolver。漏掉任一环,都会表现为“域名能 ping 通但 Go 查不到 IP”。
立即学习“go语言免费学习笔记(深入)”;


















