Skip to content

第8章 Cluster DNS 与服务发现

有了 Service 和 ClusterIP,应用之间如何知道对方的地址?Kubernetes 通过 Cluster DNS(通常是 CoreDNS)实现服务发现。本章详细讲解 DNS 机制。


8.1 什么是服务发现

服务发现就是:调用方如何找到被调用方的地址

在没有 DNS 时,调用方需要知道:

  • 被调用方的 IP(不固定)
  • 被调用方的端口

有了 DNS 后,调用方只需要知道:被调用方的名字

bash
# 不需要记 IP
curl http://user-service:80

8.2 CoreDNS

Kubernetes 集群通常运行 CoreDNS(或旧版 kube-dns),为 Service 提供 DNS 记录。

CoreDNS 作为集群内的 DNS 服务器运行,通常以 Deployment 形式部署在 kube-system 命名空间。

bash
kubectl get pods -n kube-system -l k8s-app=kube-dns

8.3 DNS 记录类型

记录类型示例说明
A / AAAAweb-service.default.svc.cluster.local解析为 ClusterIP
SRV_http._tcp.web-service.default.svc.cluster.local端口服务记录
PTR反向解析 Pod / Service IP用于日志、监控
CNAMEexternal-db.default.svc.cluster.localExternalName 类型

A 记录示例

bash
nslookup web-service.default.svc.cluster.local
# Server:  10.96.0.10
# Address: 10.96.0.10#53
#
# Name:    web-service.default.svc.cluster.local
# Address: 10.96.123.45

8.4 Pod DNS 策略

通过 dnsPolicy 控制 Pod 的 DNS 行为:

策略说明
ClusterFirst(默认)优先使用集群 DNS
Default继承节点 DNS 配置
ClusterFirstWithHostNethostNetwork Pod 使用集群 DNS
None完全自定义 DNS 配置,配合 dnsConfig
yaml
spec:
  dnsPolicy: ClusterFirst

8.5 同命名空间与跨命名空间访问

同命名空间

bash
curl http://web-service
# 或
curl http://web-service:80

跨命名空间

bash
curl http://web-service.production
# 或
curl http://web-service.production.svc.cluster.local:80

完整 FQDN 格式

text
<service-name>.<namespace>.svc.cluster.local

8.6 DNS 解析流程

text
Pod 发起 DNS 查询


/etc/resolv.conf 中的 nameserver(通常是 CoreDNS ClusterIP)


CoreDNS 查询 Kubernetes API 获取 Service 信息


返回 A 记录(ClusterIP)


Pod 拿到 ClusterIP,再发起 HTTP/TCP 请求


kube-proxy 规则将 ClusterIP 流量 DNAT 到后端 Pod

8.7 常见问题

问题1:DNS 解析慢或失败

可能原因:

  • CoreDNS Pod 异常
  • Pod 的 /etc/resolv.conf 配置错误
  • 网络策略阻止了到 CoreDNS 的流量

排查:

bash
kubectl run -it --rm debug --image=busybox:1.28 --restart=Never -- nslookup <svc-name>

问题2:跨命名空间访问失败

检查是否使用了正确的命名空间后缀:

bash
curl http://web-service.production

问题3:ExternalName 没有 A 记录

ExternalName 类型返回的是 CNAME 记录,不是 A 记录。


8.8 本章小结

  • Cluster DNS(CoreDNS)为 Service 提供名称解析。
  • 同命名空间可用短名,跨命名空间需加命名空间后缀。
  • DNS 记录包括 A、SRV、PTR、CNAME 等类型。
  • Pod 通过 /etc/resolv.conf 中的 CoreDNS 地址发起查询。

本章练习

  1. 创建一个 Service,从 Pod 内用 nslookup 验证 DNS 解析。
  2. 测试同命名空间和跨命名空间的 DNS 访问。
  3. 查看 Pod 的 /etc/resolv.conf,确认 nameserver 和 search 域。