在 Kubernetes 集群中配置 CoreDNS 使用自定义上游 DNS,最直接的方式是修改 kube-system 命名空间下的 coredns ConfigMap,调整 forward 插件指向的目标地址。
先说结论:通过编辑 CoreDNS ConfigMap 修改 forward 配置即可生效,适用于需要解析内部域名或指定外部解析源的场景。
- 适合:集群需要解析私有域、特定公共 DNS 或绕过节点默认 DNS 的场景
- 先准备:备份原有 ConfigMap 配置,确认目标 DNS 服务器 IP 可达
- 验收:在 Pod 内执行 dig 或 nslookup 验证解析路径和延迟
命令速用版
kubectl edit cm coredns -n kube-system
在打开的编辑器中找到 Corefile 数据块,修改 forward 行(确保在 .:53 块内):
forward . 8.8.8.8 8.8.4.4 {
max_concurrent 1000
}
保存退出后 CoreDNS 会自动重载配置。
原理简述
CoreDNS 是 K8s 集群默认的 DNS 服务器,运行在 Pod 中。默认情况下,它会读取节点上的 /resolv.conf 作为上游,但很多时候我们需要指定特定的 DNS 服务器(比如公司内部 DNS 或更稳定的公共 DNS)。CoreDNS 通过 forward 插件将非集群域名的查询请求转发给指定的上游服务器,修改这个配置就能改变解析路径。
分步处理
1. 备份当前配置,防止改错导致集群 DNS 不可用:
kubectl get cm coredns -n kube-system -o yaml > coredns-backup.yaml
2. 编辑 ConfigMap:
kubectl edit cm coredns -n kube-system
3. 找到 Corefile 部分,修改 forward 行。注意:forward 配置必须位于 .:53 块内部,保持缩进一致。完整配置上下文示例如下:
data:
Corefile: |
.:53 {
errors
health
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
forward . 8.8.8.8 8.8.4.4 {
max_concurrent 1000
}
cache 30
loop
reload
loadbalance
}
4. 保存退出。CoreDNS 部署通常带有滚动更新策略,修改 ConfigMap 后 Pod 会自动重载或重启。
5. 异常回滚:如果修改后 DNS 异常,立即使用备份恢复:
kubectl apply -f coredns-backup.yaml
怎么验证是否生效
进入一个业务 Pod,检查 /resolv.conf 确认 nameserver 指向了 CoreDNS 服务 IP,然后测试解析:
kubectl run -it `--rm` debug `--image`=busybox:1.28 `--restart`=Never -- nslookup www.baidu.com
如果需要确认是否走的是自定义上游,可以在 CoreDNS Pod 日志中观察查询记录,或者在上游 DNS 服务器侧查看查询来源。
常见坑
- 循环检测(Loop):如果上游 DNS 又把请求转发回 CoreDNS,会触发 loop 插件报错,导致解析失败。确保上游 DNS 不会将 Kubernetes 域名的请求回指给 CoreDNS。
- 网络策略:确保 CoreDNS Pod 所在的节点能访问你配置的上游 DNS IP,防火墙可能拦截 UDP 53 端口。
- 语法错误:Corefile 对缩进和格式敏感,编辑时不要破坏原有结构,否则 CoreDNS 启动失败。
- 缓存问题:修改后旧缓存可能残留,验证时建议测试新域名或使用 dig 关闭本地缓存。
参考来源
- Kubernetes 官方文档:Customizing DNS Service (https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameserver/)
- CoreDNS 官方文档:forward plugin (https://coredns.io/plugins/forward/)