golang服务无需部署kube-dns,只需用短域名(如order-service:9000)调用,依赖集群coredns解析;确保pod的/etc/resolv.conf配置正确、service存在且有endpoints。

Golang 项目本身不“部署” kube-dns;kube-dns(或更常见的 CoreDNS)是 Kubernetes 集群层面的系统组件,由集群管理员部署和维护。你的 Golang 服务只需正确使用 DNS 名称,就能自动接入集群 DNS 解析体系——前提是集群 DNS 已就绪。
如果你看到 “Golang 部署 kube-dns” 这类说法,大概率是混淆了使用者角色:你不是在 Golang 里装 DNS 服务器,而是在 Golang 应用中消费 Kubernetes 提供的 DNS 服务。
下面直击实操要点:
确认集群 DNS 实际运行的是 CoreDNS 而非 kube-dns
自 Kubernetes 1.13 起,CoreDNS 已取代 kube-dns 成为默认 DNS 插件。几乎所有新集群(包括 1.20+ 版本)都运行 CoreDNS,而非已弃用的 kube-dns。
-
kubectl get pods -n kube-system中找coredns-开头的 Pod,而不是kube-dns- -
kubectl get cm coredns -n kube-system存在且可读,说明配置走的是 CoreDNS -
kube-dns仅存在于极老集群(如 v1.10 之前),继续使用存在安全与功能缺陷风险
Golang 代码里怎么写才能触发集群 DNS 解析
关键不是“部署 DNS”,而是让 Go HTTP/gRPC 客户端发出的请求域名能被 CoreDNS 正确解析。这依赖两个基础条件:
- Pod 的
/etc/resolv.conf必须包含集群 DNS IP(通常是10.96.0.10)和正确的search域(如default.svc.cluster.local svc.cluster.local cluster.local) - Golang 请求必须用**短域名**(如
http://user-service:8080),而非 IP 或 FQDN(如user-service.default.svc.cluster.local.加尾点) - Go 的
net/http默认使用系统 DNS resolver,无需额外配置;但要注意:http.DefaultClient不会自动重试失败的 DNS 查询,建议配合net.Resolver自定义超时
示例(安全可用):
resp, err := http.Get("http://order-service:9000/v1/submit")
if err != nil {
// 注意:err 可能是 "no such host" —— 表明 DNS 解析失败,不是网络不通
}
常见 DNS 解析失败的根因与排查路径
当 http.Get("http://xxx") 报 no such host,别急着改 Go 代码,先验证 DNS 基础链路:
- 进 Pod 执行
cat /etc/resolv.conf:确认nameserver指向集群 DNS IP(如10.96.0.10),且search包含目标 Service 所在命名空间域(如default.svc.cluster.local) - 执行
nslookup order-service:若失败,说明 DNS 层断了;若成功但 Go 请求仍失败,检查是否用了带尾点的 FQDN(order-service.default.svc.cluster.local.),它会绕过search补全,且末尾点禁止再补后缀 - 检查 Service 是否真存在且有 Endpoint:
kubectl get svc order-service+kubectl get endpoints order-service;空 endpoints 表示 selector 没匹配到 Pod 或 readinessProbe 未就绪 - CoreDNS 日志是否有拒绝记录:
kubectl logs -n kube-system deploy/coredns | grep -i "refused\|error"
不要在 Golang 中硬编码 DNS 配置或替换 resolver
有人试图在 Go 里用 net.DefaultResolver = &net.Resolver{...} 强制指定 DNS 服务器,这是危险操作:
- 会绕过 Kubernetes 的
search域补全逻辑,导致user-service解析失败 - 可能指向外部 DNS(如
8.8.8.8),无法解析.svc.cluster.local内部域名 - 干扰容器 runtime 的 DNS 隔离机制,引发不可预测行为
真正需要定制 resolver 的场景极少(如调试、多集群混合解析),且必须显式构造 *http.Client 并传入自定义 http.Transport,而非全局替换。
CoreDNS 是集群级基础设施,它的稳定性不取决于你 Golang 代码写了什么,而取决于 Service 定义是否正确、Pod 是否就绪、以及 /etc/resolv.conf 是否被意外覆盖。最常被忽略的点是:开发者花 2 小时调 Go 代码,却没看一眼 kubectl get endpoints 输出是否为空。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











