go应用在kubernetes中需显式配置coredns以解析非cluster.local域名(如auth.internal),默认仅处理集群内域名;应添加独立server block并启用fallthrough,避免塞入主块,并通过自定义net.resolver直连coredns确保解析可控。

Go 应用在 Kubernetes 中部署本身不特殊,关键在于 DNS 解析行为是否可控——默认走集群 DNS(即 CoreDNS),但若需解析非 svc.cluster.local 的内部域名(如 auth.internal、db.company),必须让 CoreDNS 知道怎么处理,否则 net.Dial 或 http.Get 会超时或返回 NXDOMAIN。
CoreDNS 配置必须显式支持自定义域名区域
默认 Corefile 只监听 .:53 并处理 cluster.local 及反向解析,其他域名直接 forward 到上游(比如 /etc/resolv.conf)。这意味着你写死的 auth.internal 不会被识别,也不会命中 hosts 插件,除非单独为它开一个 server block。
常见错误现象:
-
nslookup auth.internal返回** server can't find auth.internal: NXDOMAIN - Go 应用启动时报
lookup auth.internal: no such host,且日志里看不到 CoreDNS 的hosts匹配日志
正确做法是添加独立端口监听块(推荐用不同端口避免冲突):
auth.internal:53 {
log
errors
hosts {
10.96.123.45 auth.internal
fallthrough
}
}
注意点:
- 不能写成
auth.internal:53 { hosts { ... } }而漏掉fallthrough,否则auth.internal能解析,但auth.internal.svc.cluster.local就失效了 - 不要把自定义块塞进主
.:53块里——hosts插件在主块中只对未匹配 kubernetes 插件的请求生效,而auth.internal不符合cluster.local规则,会被forward吞掉,根本到不了hosts - 修改后必须重启:执行
kubectl -n kube-system rollout restart deployment coredns
Go 应用代码里别依赖系统 resolv.conf
Kubernetes Pod 启动时注入的 /etc/resolv.conf 通常只含集群 DNS IP(如 10.96.0.10),它能解析 service.namespace.svc.cluster.local,但无法保证解析你加的 auth.internal——因为那是你后来手动加的 server block,不是默认逻辑。
更稳妥的方式是在 Go 代码中绕过系统 resolver,直连 CoreDNS 实例做解析:
r := &net.Resolver{
PreferGo: true,
Dial: func(ctx context.Context, network, addr string) (net.Conn, error) {
return net.DialTimeout(network, "10.96.0.10:53", 3*time.Second)
},
}
ip, err := r.LookupHost(ctx, "auth.internal")
这样做的好处:
- 不依赖容器内
/etc/resolv.conf内容是否被覆盖或延迟更新 - 避免因节点上
ndots或 search domain 导致的额外查询(比如查auth.internal.default.svc.cluster.local) - 超时可控,不会卡住整个 HTTP 客户端初始化
- CoreDNS 日志:加
log插件后,执行kubectl logs -n kube-system deploy/coredns | grep auth.internal,应看到类似auth.internal. A IN的查询记录 - Pod 内实际 DNS 配置:进 Pod 执行
cat /etc/resolv.conf,确认nameserver指向的是 CoreDNS ClusterIP(不是宿主机 DNS) - Go 应用运行时行为:在代码里加
fmt.Printf("resolved %v\n", ip),或用dig @10.96.0.10 auth.internal直连验证,排除客户端缓存干扰
验证自定义解析是否生效的三步检查法
别只信 kubectl exec 里的 nslookup,那只是测试链路一环。要确认真实生效,得看三个位置:
最容易被忽略的是:CoreDNS 的 hosts 插件不支持通配符(如 *.internal),也不支持 SRV 记录;如果业务需要泛解析或服务发现元数据,得换用 template 插件或对接 Consul + consul 插件。











