Kubernetes DNS 完全指南:服务发现核心机制与实践
一、Kubernetes DNS 核心概述
1. 基本定位
-
内置特性:Kubernetes 1.3+ 版本默认集成 DNS 服务,通过集群插件自动部署(包含 DNS Pod 和 Service)。
-
核心作用:为集群内的 Service、Pod 提供域名解析能力,替代手动配置 IP 地址,实现灵活的服务发现。
-
工作原理 :kubelet 通过
--cluster-dns标志告知容器 DNS 服务 IP,容器通过该 IP 解析集群内域名;同时通过--cluster-domain配置集群默认域(默认cluster.local)。
2. 核心优势
-
无需修改应用代码,兼容传统 DNS 解析逻辑。
-
自动同步 Service/Pod 变更,IP 动态变化时无需手动更新配置。
-
支持跨命名空间解析,简化多团队协作部署。
二、DNS 命名规则与解析模式
1. 域名生成规则
集群内所有资源的 DNS 域名遵循统一格式,核心结构为:
[资源名称].[命名空间].[资源类型].cluster.local
-
默认搜索列表:Pod 的 DNS 配置会自动包含「自身命名空间 + 集群默认域」,简化短域名解析。
-
示例说明:
- 命名空间
bar中的 Servicefoo,在同命名空间可通过foo解析,跨命名空间(如quux)需通过foo.bar解析。
- 命名空间
2. 支持的 DNS 记录类型
(1)Service 相关记录
| 记录类型 | 适用场景 | 域名格式 | 解析结果 |
|---|---|---|---|
| A 记录 | 普通 Service(带 ClusterIP) | my-svc.my-namespace.svc.cluster.local |
Service 的 ClusterIP |
| A 记录 | 无头服务(Headless Service,无 ClusterIP) | my-svc.my-namespace.svc.cluster.local |
关联的所有 Pod IP 列表(轮询负载均衡) |
| SRV 记录 | 命名端口的 Service | _port-name._port-protocol.my-svc.my-namespace.svc.cluster.local |
端口号 + 对应域名(普通 Service)或多个 Pod 端口 + 域名(无头服务) |
(2)Pod 相关记录
-
默认 A 记录 (启用后):
pod-ip-address.my``-namespace.pod.cluster.local(如1-2-3-4.default.pod.cluster.local)。 -
自定义主机名 / 子域名 :通过 PodSpec 的
hostname和subdomain字段配置,生成格式为[hostname].[subdomain].[namespace].svc.cluster.local的域名,需配合无头服务使用:示例:Pod 自定义域名配置
apiVersion: v1
kind: Service
metadata:
name: default-subdomain # 无头服务(clusterIP: None)
spec:
selector:
name: busyboxclusterIP: None
ports:
-
name: foo
port: 1234
apiVersion: v1
kind: Pod
metadata:
name: busybox1
labels:
name: busybox
spec:
hostname: busybox-1 # 自定义主机名
subdomain: default-subdomain # 关联无头服务
containers:
-
image: busybox
command: ["sleep", "3600"]
name: busybox
-
最终 Pod 域名:busybox-1.default-subdomain.default.svc.cluster.local。
三、DNS 服务使用与验证
1. 快速验证 DNS 可用性
步骤 1:创建测试 Pod
yaml
# busybox.yaml
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: default
spec:
containers:
- image: busybox
command: ["sleep", "3600"]
name: busybox
restartPolicy: Always
$ kubectl create -f busybox.yaml
$ kubectl get pods busybox # 等待 STATUS 为 Running
步骤 2:执行 DNS 解析测试
# 解析集群默认 Service(kubernetes.default)
$ kubectl exec -ti busybox -- nslookup kubernetes.default
# 成功输出示例:
Server: 10.0.0.10 # DNS Service IP
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: kubernetes.default
Address 1: 10.0.0.1 # kubernetes Service 的 ClusterIP
2. 查看 Pod DNS 配置
Pod 的 DNS 配置存储在 /etc/resolv.conf 中,可通过以下命令查看:
$ kubectl exec busybox -- cat /etc/resolv.conf
# 典型输出(包含搜索路径和 DNS 服务器):
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.0.0.10 # 集群 DNS Service IP
options ndots:5
-
search:解析短域名时的搜索路径,按顺序匹配命名空间和集群域。 -
ndots:5:当域名中.数量少于 5 时,优先使用搜索路径拼接解析。
四、DNS 常见问题排查
当 DNS 解析失败时,按以下步骤逐步排查:
1. 基础配置检查
-
验证 Pod 的
/etc/resolv.conf是否包含正确的nameserver(集群 DNS IP)和search路径。 -
确认目标 Service/Pod 已创建,且命名空间、名称无拼写错误。
2. DNS 组件状态检查
# 1. 检查 DNS Pod 是否运行(kube-system 命名空间)
$ kubectl get pods --namespace=kube-system -l k8s-app=kube-dns
# 预期输出:3/3 Ready(包含 kubedns、dnsmasq、healthz 三个容器)
# 2. 检查 DNS Service 是否存在
$ kubectl get svc --namespace=kube-system kube-dns
# 预期输出:CLUSTER-IP 为 10.0.0.10(默认),PORT(S) 为 53/UDP,53/TCP
# 3. 检查 DNS Endpoints 是否正常(关联 DNS Pod IP)
$ kubectl get ep kube-dns --namespace=kube-system
# 预期输出:ENDPOINTS 包含 DNS Pod 的 IP:53
3. 日志排查
查看 DNS Pod 日志,定位错误原因(如连接 apiserver 失败、配置错误等):
# 查看 kubedns 容器日志
$ kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c kubedns
# 查看 dnsmasq 容器日志
$ kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c dnsmasq
- 日志级别说明:
W(警告)、E(错误)、F(失败)需重点关注。
4. 已知问题与规避方案
-
Linux libc 限制 :最多支持 3 个
nameserver和 3 个search记录,超出部分会被截断。可通过 Node 部署 dnsmasq 扩展nameserver,或使用 kubelet 的--resolv-conf自定义配置文件。 -
Alpine 镜像兼容问题 :Alpine 3.3 及更早版本 DNS 解析异常,需升级镜像或手动安装
bind-tools。 -
Pod 继承 Node DNS :默认情况下,Pod 会继承 Node 的 DNS 配置,若需自定义,可通过 kubelet 的
--resolv-conf标志指定配置文件(设为""表示不继承)。
五、高级配置与扩展
1. 自定义集群域名
通过 kubelet 的 --cluster-domain 标志修改集群默认域(默认 cluster.local),例如:
# kubelet 启动参数
--cluster-domain=my-cluster.local
修改后,Service 域名格式变为 my-svc.my-namespace.svc.my``-cluster.local。
2. 无头服务(Headless Service)DNS 配置
无头服务无 ClusterIP,DNS 解析直接返回关联 Pod IP,适用于:
-
客户端需自主实现负载均衡。
-
需通过域名直接访问单个 Pod(如状态 ful 应用)。
3. 跨集群 DNS 解析(Federation)
Kubernetes 支持集群联邦(Federation),通过 DNS 服务实现跨集群 Service 发现,需部署联邦插件并配置跨集群 DNS 转发规则,具体参考 集群联邦官方文档。
六、总结与最佳实践
-
优先使用短域名 :同命名空间直接使用 Service 名称解析(如
my-nginx),跨命名空间使用服务名.命名空间(如my-nginx.prod)。 -
避免硬编码 IP:所有集群内服务访问均通过 DNS 域名,适配 Pod 动态扩缩容和 IP 变更。
-
启用 Pod 域名解析 :如需通过域名访问特定 Pod,配置
hostname、subdomain并关联无头服务。 -
定期检查 DNS 状态:将 DNS Pod 运行状态、Endpoints 关联情况纳入集群监控,避免服务发现中断。