星驰编程网

免费编程资源分享平台_编程教程_代码示例_开发技术文章

K8s DNS 服务全解:如何解析集群内部服务名

在 Kubernetes 中,服务之间通过服务名进行通信,而不是硬编码 IP 地址。这一机制的核心依赖是 Kubernetes DNS 服务。本文将全面解析 K8s 内部 DNS 的工作原理、服务名解析机制、常见配置结构以及如何进行调试,帮助你彻底搞懂:Pod 内访问服务名到底发生了什么?


一、Kubernetes DNS 服务是什么?

Kubernetes DNS 服务是集群内的一个基础设施组件,负责为集群中的 Service、Pod 等对象提供域名解析能力。默认情况下,Kubernetes 会自动部署一个 DNS 解析服务(如 CoreDNS 或 kube-dns),并在所有 Pod 中自动配置 DNS 服务器地址。

默认的 DNS 实现:CoreDNS

  • 现代版本的 K8s 默认使用 CoreDNS,其部署在 kube-system 命名空间。
  • DNS 服务器的地址通常是:10.96.0.10(取决于 Service CIDR 设置)。
  • 所有 Pod 启动时,都会在 /etc/resolv.conf 中配置此地址作为 DNS 服务器。

二、服务名解析的基础结构

Kubernetes 中服务名是有层级结构的 DNS 名称。一个服务在集群中的完整域名(FQDN)格式如下:

<服务名>.<命名空间>.svc.cluster.local

举例:

  • 服务名:my-svc
  • 命名空间:default
  • 完整 FQDN:my-svc.default.svc.cluster.local

当 Pod 访问一个服务名如 http://my-svc 时,实际上是通过 DNS 补全为完整域名进行解析的。


三、DNS 补全机制详解

每个 Pod 的 /etc/resolv.conf 文件中,通常包含以下搜索域配置:

search default.svc.cluster.local svc.cluster.local cluster.local

这意味着当你在 Pod 中访问 my-svc,DNS 查询会依次尝试以下域名:

  1. my-svc.default.svc.cluster.local
  2. my-svc.svc.cluster.local
  3. my-svc.cluster.local

Kubernetes DNS 服务会尝试解析这些域名,并返回对应的 IP 地址(通常是 ClusterIP)。


四、DNS 是如何解析服务名的?

CoreDNS 使用内置的 kubernetes 插件,动态地将服务名映射为服务 IP。

一个典型的 CoreDNS 配置如下:

.:53 {
    errors
    health
    kubernetes cluster.local in-addr.arpa ip6.arpa {
        pods insecure
        fallthrough in-addr.arpa ip6.arpa
    }
    forward . /etc/resolv.conf
    cache 30
    loop
    reload
    loadbalance
}

其中,kubernetes cluster.local 表示 CoreDNS 负责解析 *.cluster.local 的域名。

当接收到 DNS 查询时,CoreDNS 会:

  1. 查询当前服务注册表;
  2. 根据服务名和命名空间查找对应的服务;
  3. 返回该服务的 ClusterIP 地址。

五、不同服务类型的 DNS 行为差异

1. ClusterIP 服务

最常见的类型,DNS 记录解析为单个 IP 地址,即 Service 的 ClusterIP。

my-svc.default.svc.cluster.local → 10.96.1.25

2. Headless Service(无头服务)

当 clusterIP: None 时,CoreDNS 会返回后端 Pod 的 IP 列表,而不是一个虚拟的 Service IP。

apiVersion: v1
kind: Service
metadata:
  name: my-headless
spec:
  clusterIP: None
  selector:
    app: backend
  ports:
    - port: 80

DNS 查询将返回每个匹配 Pod 的 A 记录,支持 StatefulSet 中使用 Pod 子域名访问。

pod-1.my-headless.default.svc.cluster.local → Pod IP

3. ExternalName 服务

这种服务类型通过 CNAME 把服务名映射到外部域名:

apiVersion: v1
kind: Service
metadata:
  name: external-svc
spec:
  type: ExternalName
  externalName: www.example.com

DNS 查询结果为:

external-svc.default.svc.cluster.local → www.example.com(CNAME)

六、DNS 在 Pod 中的配置路径

在每个 Pod 中:

  1. DNS 服务地址:默认由 kubelet 自动注入,指向 CoreDNS 的 ClusterIP;
  2. 搜索域:确保短名称能自动补全为完整 FQDN;
  3. 使用顺序:应用程序发起域名查询 → 搜索路径补全 → CoreDNS 响应 IP。
cat /etc/resolv.conf

nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

七、实用 DNS 调试命令

当服务间通信失败时,优先排查 DNS 是否解析成功:

1. 查看 DNS 搜索路径

kubectl exec my-pod -- cat /etc/resolv.conf

2. 测试 DNS 解析

kubectl exec my-pod -- nslookup my-svc
kubectl exec my-pod -- dig my-svc.default.svc.cluster.local

3. 检查 CoreDNS 是否正常运行

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

4. 使用 busybox 进行 DNS 测试

kubectl run -it --rm dns-test --image=busybox:1.28 --restart=Never -- nslookup my-svc

八、常见问题与排查建议

问题

原因

排查建议

无法解析服务名

CoreDNS 服务未运行;resolv.conf 配置错误

查看 CoreDNS 状态;验证 Pod 内 DNS 配置

Headless Service 无法解析 Pod IP

Service selector 不匹配;Pod 标签错误

检查 selector、Pod 标签

ExternalName 无法访问

CoreDNS 无外部解析能力;Pod 无网络访问权限

验证是否能直接 ping 外部域名

延迟高、间歇性失败

DNS 缓存冲突;CoreDNS 配置错误

增加 cache 配置,查看 CoreDNS 负载状态


九、进阶:与 Service Mesh(如 Istio)的关系

在引入 Service Mesh(如 Istio)后,DNS 名称依然是服务通信的重要部分,但调用路径会经由 sidecar(如 Envoy)代理处理。

例如:

  • 应用访问 my-svc.default.svc.cluster.local
  • 请求先被拦截到 Envoy,然后转发到真实 IP
  • DNS 仍由 CoreDNS 提供服务名解析

十、总结

Kubernetes DNS 服务是集群中服务发现的基石,它通过 CoreDNS 实现了自动的服务名解析,极大简化了微服务的部署与调用。掌握 DNS 名称结构、补全逻辑和调试方法,是每个 K8s 使用者不可或缺的技能。

当你理解了
my-svc.default.svc.cluster.local 背后的解析机制,你就掌握了 Kubernetes 网络通信的第一道大门。

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言