在 Kubernetes 1.7 版本中,DNS 服务是集群功能正常运作的基石,它承担了至关重要的服务发现任务,当时,集群内部署的默认 DNS 解决方案是 kube-dns,它作为一个附加组件运行,为 Pod 提供解析服务名和 Pod 名的能力,从而实现了微服务之间通过易于记忆的名称进行通信,而非依赖不稳定的 IP 地址。

kube-dns 的核心架构
kube-dns 并非单一程序,而是由三个紧密协作的容器组成的 Pod,这种设计将不同的职责解耦,提高了系统的可维护性,其架构可以通过下表清晰地展示:
| 容器名称 | 主要职责 | 技术实现 |
|---|---|---|
kubedns |
DNS 数据源与权威服务器 | 监听 Kubernetes API,将 Service 和 Endpoint 的变化转换为 DNS 记录,并对外提供 DNS 查询服务。 |
dnsmasq |
DNS 缓存与转发器 | 作为轻量级的 DNS 缓存,接收来自 Pod 的查询请求,如果缓存中有记录则直接返回,否则转发给 kubedns 容器,它也负责将集群外部的域名查询请求转发给上游 DNS 服务器。 |
sidecar (或 healthz) |
健康检查与状态上报 | 定期检查 kubedns 和 dnsmasq 的健康状态,如果发现异常,会通过 Kubernetes 的健康检查机制,将 kube-dns Service 的端点移除,从而避免将流量导向一个已损坏的 DNS Pod。 |
这种三容器架构在当时被认为是稳定且高效的,它将数据同步、查询服务和缓存功能清晰地分离开来。
DNS 解析的工作原理
当一个 Pod 在 Kubernetes 1.7 集群中被创建时,它的 /etc/resolv.conf 文件会被自动注入,其内容通常如下所示:
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
这里的 nameserver 指向的就是 kube-dns 服务的虚拟 IP(ClusterIP)。search 域定义了 DNS 查询的搜索路径,使得 Pod 可以使用简短的服务名进行访问。
当一个 Pod 尝试访问 my-service 时,DNS 解析过程如下:

- Pod 的本地解析库首先尝试解析
my-service。 - 如果失败,它会根据
search路径依次尝试my-service.default.svc.cluster.local、my-service.svc.cluster.local等。 - 完整的域名请求被发送到
kube-dns的 ClusterIP。 - 请求由
dnsmasq接收,检查缓存,若无缓存,则转发给kubedns。 kubedns查询其内存中的 Service 数据,找到my-service对应的 ClusterIP,并返回给dnsmasq。dnsmasq缓存该结果并返回给发起请求的 Pod。
对于“无头服务”,kube-dns 不会返回一个 ClusterIP,而是直接返回该服务背后所有 Pod 的 IP 地址列表,这对于实现有状态服务(如数据库集群)的对等发现至关重要。
关键配置与策略
Kubernetes 1.7 提供了 dnsPolicy 字段,允许用户为 Pod 定制 DNS 行为,主要有以下几种策略:
Default:Pod 继承其所在节点的 DNS 配置,即直接使用节点的/etc/resolv.conf,这意味着 Pod 无法解析集群内的服务名。ClusterFirst(默认策略):Pod 的 DNS 配置指向kube-dns,优先在集群内部进行解析,对于无法解析的域名,会转发给上游 DNS(通过dnsmasq实现)。ClusterFirstWithHostNet:对于使用hostNetwork: true的 Pod,其 DNS 行为与ClusterFirst类似,但配置方式略有不同,确保即使共享了主机网络,依然能解析集群内服务。
Kubernetes 1.7 时代的挑战与考量
尽管 kube-dns 在 1.7 版本中表现稳健,但也暴露出一些挑战。dnsmasq 的缓存能力有限,在大型、高并发的集群中可能成为性能瓶颈。kubedns 需要持续监控 API Server 的所有资源变化,在资源数量巨大的情况下,其 CPU 和内存消耗也值得关注,这些挑战也为后续社区引入更现代、更灵活的 CoreDNS 奠定了基础。
相关问答FAQs
问题1:在 Kubernetes 1.7 中,如果一个 Pod 无法解析服务名,最可能的原因是什么?
解答: 排查此类问题应遵循以下思路:

- 检查
kube-dnsPod 状态:首先确认kube-dns相关的 Pod 是否在kube-system命名空间中正常运行,可以使用kubectl get pods -n kube-system -l k8s-app=kube-dns查看。 - 检查 Pod 的
/etc/resolv.conf:进入问题 Pod,查看其/etc/resolv.conf文件,确认nameserver指向的 IP 是否正确,以及search域是否符合预期。 - 检查网络策略:确认是否有网络策略阻止了该 Pod 与
kube-dnsService IP 之间的通信。 - 检查
dnsPolicy:确认该 Pod 的dnsPolicy是否被错误地设置为Default,导致其无法使用集群 DNS。 - 直接测试 DNS:在 Pod 内部使用
nslookup或dig命令直接测试解析kube-dns的 ClusterIP 或一个已知的服务名,以定位问题是在 DNS 服务本身还是网络连通性上。
问题2:kube-dns 和 CoreDNS 有什么主要区别?为什么后来社区会转向 CoreDNS?
解答: 主要区别在于架构和扩展性:
- 架构:
kube-dns是由kubedns、dnsmasq和sidecar三个容器组成的“组合体”,而 CoreDNS 是一个单一的二进制文件,通过插件链的方式实现各种功能,架构更简洁、高效。 - 性能与扩展性:
kube-dns中的dnsmasq存在缓存大小限制和并发瓶颈,CoreDNS 的缓存和性能更优,且其插件机制提供了无与伦比的扩展性,可以轻松集成 Prometheus 监控、日志、自定义 DNS 记录等功能。 - 灵活性:CoreDNS 的配置通过一个名为
Corefile的文件完成,语法清晰,可以非常灵活地为不同的域名配置不同的解析逻辑。
社区转向 CoreDNS 的根本原因是为了解决 kube-dns 在大规模集群下的性能瓶颈和扩展性问题,CoreDNS 凭借其现代化的设计、卓越的性能和强大的灵活性,最终成为了 Kubernetes 集群中 DNS 的新标准。
来源互联网整合,作者:小编,如若转载,请注明出处:https://www.aiboce.com/ask/251569.html