在 Kubernetes 集群中,Pod 默认使用 CoreDNS 解析集群内部域名(如 Service、Pod 等)。但当业务应用需要解析自定义的内部域名(如 *.odboy.com)时,默认配置无法满足需求。本文提供一套完整的解决方案:在宿主机上部署 BIND9 作为内部域名服务器,并通过修改 CoreDNS 配置,将特定域名的解析请求转发到 BIND9。
核心内容包括:
BIND9 安装与配置:在 CentOS 7 宿主机上安装 BIND9,修改 named.conf 监听所有接口、开启递归查询、添加转发器,并创建自定义区域文件 odboy.com.zone
区域文件配置:配置泛域名解析(* 通配符),将所有 odboy.com 子域名指向同一 IP(如 192.168.235.128)
CoreDNS 转发配置:修改 CoreDNS ConfigMap,新增 odboy.com:53 配置块,使用 forward 插件将查询转发到宿主机 BIND9 服务
验证与测试:通过 dig 命令验证 BIND9 和 CoreDNS 转发是否生效,并在 Pod 内部使用 nslookup 测试域名解析
本文适用于需要在 Kubernetes 集群内解析自定义内部域名的运维和开发人员。
实验环境: centos7
shellyum install bind bind-utils -y
shellvi /etc/named.conf
找到 options 部分,修改 listen-on 配置:
textoptions { listen-on port 53 { any; }; listen-on-v6 port 53 { none; }; directory "/var/named"; dump-file "/var/named/data/cache_dump.db"; statistics-file "/var/named/data/named_stats.txt"; memstatistics-file "/var/named/data/named_mem_stats.txt"; recursing-file "/var/named/data/named.recursing"; secroots-file "/var/named/data/named.secroots"; # 修改:允许所有客户端查询 allow-query { any; }; # 开启递归查询(允许转发) recursion yes; # 临时禁用 DNSSEC 简化配置(可选,如果不需要可以保持开启) dnssec-enable no; dnssec-validation no; # 如果上面禁用 DNSSEC,注释掉下面这行 # bindkeys-file "/etc/named.root.key"; # 如果禁用 DNSSEC,也注释掉 managed-keys # managed-keys-directory "/var/named/dynamic"; # 允许所有客户端使用缓存和递归 allow-query-cache { any; }; allow-recursion { any; }; pid-file "/run/named/named.pid"; session-keyfile "/run/named/session.key"; # 可选:添加转发器提高解析速度 forwarders { 8.8.8.8; 114.114.114.114; }; forward only; }; logging { channel default_debug { file "data/named.run"; severity dynamic; }; }; zone "." IN { type hint; file "named.ca"; }; include "/etc/named.rfc1912.zones"; # 如果禁用了 DNSSEC,注释掉下面这行 # include "/etc/named.root.key";
shell# 1. 创建区域文件
sudo tee /var/named/odboy.com.zone > /dev/null << 'EOF'
$TTL 86400
@ IN SOA ns1.odboy.com. admin.odboy.com. (
2026040601 ; Serial
3600 ; Refresh
1800 ; Retry
604800 ; Expire
86400 ; Minimum TTL
)
@ IN NS ns1.odboy.com.
@ IN A 192.168.235.128
ns1 IN A 192.168.235.128
* IN A 192.168.235.128
EOF
# 2. 设置权限
sudo chown named:named /var/named/odboy.com.zone
sudo chmod 640 /var/named/odboy.com.zone
# 3. 在 named 配置中添加区域(如果还没有)
if ! sudo grep -q "odboy.com" /etc/named.rfc1912.zones; then
echo 'zone "odboy.com" IN {
type master;
file "odboy.com.zone";
allow-update { none; };
};' | sudo tee -a /etc/named.rfc1912.zones
fi
# 4. 检查配置语法
sudo named-checkconf
sudo named-checkzone odboy.com /var/named/odboy.com.zone
# 5. 重新加载配置
sudo rndc reload
# 或者重启
sudo systemctl restart named
shell# 测试解析(使用 IPv4)
dig @127.0.0.1 test.odboy.com
# 如果成功,应该看到:
# ;; ANSWER SECTION:
# test.odboy.com. 86400 IN A 192.168.235.128
shellkubectl edit configmap coredns -n kube-system
textapiVersion: v1 data: Corefile: | .:53 { errors health ready kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure fallthrough in-addr.arpa ip6.arpa } prometheus :9153 forward . /etc/resolv.conf { max_concurrent 1000 } cache 30 loop reload loadbalance } # 将 odboy.com 域名的查询转发到宿主机的BIND服务(192.168.235.128)上 # odboy.com 域名解析配置块 # 这个配置块专门处理所有以 odboy.com 结尾的域名查询 odboy.com:53 { # errors:错误日志插件 # 当解析过程中发生错误时,记录错误信息到日志中 # 便于排查 DNS 解析问题 errors # log:查询日志插件(可选,调试完成后可以删除) # 记录所有到达此配置块的 DNS 查询请求 # 日志格式:时间、客户端IP、查询类型、域名、响应状态等 # 例如:[INFO] 10.244.0.1:54321 - 12345 "A IN test.odboy.com. udp 32 false 512" NOERROR log # cache:缓存插件 # 缓存 DNS 查询结果,减少对上游 DNS 的请求压力 # 参数 30 表示缓存时间为 30 秒 # 缓存的内容包括:A、AAAA、CNAME、TXT 等常见记录类型 # 优点:提高解析速度,减少网络延迟 cache 30 # forward:转发插件 # 将域名查询请求转发到指定的上游 DNS 服务器 # . 表示所有查询(这个配置块下的所有查询) # 192.168.235.128 是上游 DNS 服务器地址(你的 BIND 服务器) forward . 192.168.235.128 { # max_concurrent:最大并发连接数 # 限制同时发往上游 DNS 的最大连接数 # 1000 表示最多允许 1000 个并发查询 # 防止突发流量压垮上游 DNS 服务器 max_concurrent 1000 # prefer_udp:优先使用 UDP 协议 # DNS 查询默认使用 UDP 协议(速度快,但数据包大小有限制) # 启用后优先尝试 UDP,失败后自动切换 TCP # 适用于大多数常规 DNS 查询场景 prefer_udp # force_tcp:强制使用 TCP 协议(可选,与 prefer_udp 互斥) # 注释掉的行,如需使用请删除 # 并注释掉 prefer_udp # TCP 协议适用于: # - 响应数据包大于 512 字节(如 DNSSEC、大量 TXT 记录) # - DNS 区域传输(AXFR/IXFR) # - 网络环境 UDP 不稳定或被限制 # 缺点:相比 UDP 有额外的 TCP 握手开销 # force_tcp } # health:健康检查插件(可选) # 为 CoreDNS 内部健康检查提供端点 # 默认监听 8080 端口,路径 /health # Kubernetes 的 livenessProbe 和 readinessProbe 可以访问此端点 # 用于判断 CoreDNS 实例是否健康工作 # 示例检查命令:curl http://localhost:8080/health health # ready:就绪检查插件(可选) # 为 Kubernetes 的就绪探针提供端点 # 默认监听 8181 端口,路径 /ready # 当所有插件(包括转发插件)都准备就绪后,返回 200 状态码 # Kubernetes 使用此端点判断 Pod 是否应该接收流量 # 示例检查命令:curl http://localhost:8181/ready ready }
textapiVersion: v1 data: Corefile: | .:53 { errors health ready kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure fallthrough in-addr.arpa ip6.arpa } prometheus :9153 forward . /etc/resolv.conf { max_concurrent 1000 } cache 30 loop reload loadbalance } # 将 odboy.com 域名的查询转发到宿主机的 BIND odboy.com:53 { # 错误记录(必需) errors # 缓存 30 秒(推荐) cache 30 # 转发到 BIND 服务器 forward . 192.168.235.128 { max_concurrent 1000 prefer_udp } # 健康检查(Kubernetes 需要) health ready } }
text保存并退出
shell# 重启 CoreDNS Deployment
kubectl rollout restart deployment coredns -n kube-system
# 查看重启状态
kubectl rollout status deployment coredns -n kube-system
# 查看 CoreDNS Pods 状态
kubectl get pods -n kube-system -l k8s-app=kube-dns
shell# 查看 CoreDNS 日志,确认没有错误
kubectl logs -n kube-system -l k8s-app=kube-dns --tail=20
shell# 获取 CoreDNS Service IP ->
kubectl get svc kube-dns -n kube-system
# CoreDNS IP 是 10.68.0.2,测试转发
dig @10.68.0.2 test.odboy.com
dig @10.68.0.2 kenaito-pilot-api.odboy.com
text[root@easzlab ingress-nginx-controller-v1.12.0]# dig @10.68.0.2 test.odboy.com ; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.16 <<>> @10.68.0.2 test.odboy.com ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5251 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;test.odboy.com. IN A ;; ANSWER SECTION: test.odboy.com. 30 IN A 192.168.235.128 ;; AUTHORITY SECTION: odboy.com. 30 IN NS ns1.odboy.com. ;; ADDITIONAL SECTION: ns1.odboy.com. 30 IN A 192.168.235.128 ;; Query time: 1 msec ;; SERVER: 10.68.0.2#53(10.68.0.2) ;; WHEN: Sun Mar 29 02:45:29 CST 2026 ;; MSG SIZE rcvd: 138 [root@easzlab ingress-nginx-controller-v1.12.0]# dig @10.68.0.2 kenaito-pilot-api.odboy.com ; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.16 <<>> @10.68.0.2 kenaito-pilot-api.odboy.com ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 42248 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;kenaito-pilot-api.odboy.com. IN A ;; ANSWER SECTION: kenaito-pilot-api.odboy.com. 30 IN A 192.168.235.128 ;; AUTHORITY SECTION: odboy.com. 30 IN NS ns1.odboy.com. ;; ADDITIONAL SECTION: ns1.odboy.com. 30 IN A 192.168.235.128 ;; Query time: 1 msec ;; SERVER: 10.68.0.2#53(10.68.0.2) ;; WHEN: Sun Mar 29 02:45:34 CST 2026 ;; MSG SIZE rcvd: 164
shell# 1. 测试泛域名解析
kubectl exec -it kenaito-pilot-daily-pod-0 -n kenaito-pilot -- nslookup test.odboy.com
kubectl exec -it kenaito-pilot-daily-pod-0 -n kenaito-pilot -- nslookup api.odboy.com
kubectl exec -it kenaito-pilot-daily-pod-0 -n kenaito-pilot -- nslookup app.odboy.com
# 2. 测试集群内部 DNS 是否仍然正常
kubectl exec -it kenaito-pilot-daily-pod-0 -n kenaito-pilot -- nslookup kubernetes.default.svc.cluster.local
# 3. 测试外部 DNS 解析(如百度)
kubectl exec -it kenaito-pilot-daily-pod-0 -n kenaito-pilot -- nslookup baidu.com
# 4. 查看 DNS 配置
kubectl exec -it kenaito-pilot-daily-pod-0 -n kenaito-pilot -- cat /etc/resolv.conf
text[root@easzlab ingress-nginx-controller-v1.12.0]# kubectl exec -it kenaito-pilot-daily-pod-0 -n kenaito-pilot -- nslookup test.odboy.com Server: 169.254.20.10 Address: 169.254.20.10#53 Name: test.odboy.com Address: 192.168.235.128 [root@easzlab ingress-nginx-controller-v1.12.0]# kubectl exec -it kenaito-pilot-daily-pod-0 -n kenaito-pilot -- nslookup kubernetes.default.svc.cluster.local Server: 169.254.20.10 Address: 169.254.20.10#53 Name: kubernetes.default.svc.cluster.local Address: 10.68.0.1 [root@easzlab ingress-nginx-controller-v1.12.0]# kubectl exec -it kenaito-pilot-daily-pod-0 -n kenaito-pilot -- nslookup baidu.com Server: 169.254.20.10 Address: 169.254.20.10#53 Non-authoritative answer: Name: baidu.com Address: 111.63.65.103 Name: baidu.com Address: 124.237.177.164 Name: baidu.com Address: 111.63.65.247 Name: baidu.com Address: 110.242.74.102 [root@easzlab ingress-nginx-controller-v1.12.0]# kubectl exec -it kenaito-pilot-daily-pod-0 -n kenaito-pilot -- cat /etc/resolv.conf search kenaito-pilot.svc.cluster.local svc.cluster.local cluster.local io.local nameserver 169.254.20.10 options ndots:5


本文作者:Odboy
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 CC 4.0 BY-SA 许可协议。转载请注明出处!