欢迎光临
我们一直在努力

CoreDNS 运行机制详解:为什么 Pod 内部可以直接通过服务名访问数据库

在 Kubernetes 集群中,Pod 能够仅仅通过服务名(例如 my-database)就访问到集群内部的其他服务,这对于微服务间的通信至关重要。实现这一“魔法”的核心组件就是 CoreDNS。

本文将深入解析 CoreDNS 在 K8s 中的运行机制,并具体解释 Pod 内部 DNS 解析的流程。

1. CoreDNS 在 K8s 中的角色

CoreDNS 是 Kubernetes 官方推荐的 DNS 服务解决方案,取代了早期的 Kube-DNS。它作为集群内部的权威 DNS 服务器运行,主要职责是将 Kubernetes Service 和 Pod 的名字解析成对应的 IP 地址。

CoreDNS 通常部署在 kube-system 命名空间下,作为一个 Deployment 运行,并通过一个 ClusterIP Service 暴露服务(通常是 kube-system/kube-dns,IP 地址在集群中是固定的,例如 10.96.0.10)。

2. Pod 的 DNS 配置:/etc/resolv.conf

当 Kubelet 启动一个 Pod 时,它会根据集群的配置自动注入 DNS 配置信息到 Pod 的 /etc/resolv.conf 文件中。这是 Pod 能够解析服务名的关键。

让我们在一个运行中的 Pod 内部查看这个文件:

# 假设我们有一个测试Pod
kubectl run debug --image=alpine --restart=Never -- sleep 3600
kubectl exec debug -- cat /etc/resolv.conf

输出通常类似于(取决于您的集群配置):

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

关键配置解析:

  1. ****nameserver 10.96.0.10****: 这是 CoreDNS Service (即 kube-dns) 的 ClusterIP。所有 Pod 的 DNS 查询请求都会被导向这个地址。
  2. ****search …****: 这是 DNS 搜索列表。这是 Pod 能够使用短名称访问服务的核心原因。
  3. ****options ndots:5****: ndots 定义了一个域名中必须包含多少个点(.),系统才将其视为完全限定域名(FQDN)并直接查询,否则将使用 search 列表进行尝试。

3. 为什么短名称有效:DNS 搜索路径

假设您在 default 命名空间中有一个名为 my-database 的 Service,其完全限定域名(FQDN)是 my-database.default.svc.cluster.local

当 Pod 尝试连接 my-database 时,操作系统解析器发现查询名称中不包含点(或点数少于 ndots 定义的值 5),因此会开始遍历 search 列表:

  1. 第一次尝试: 将 my-database 拼接上搜索列表中的第一个项 (default.svc.cluster.local),查询 my-database.default.svc.cluster.local
  2. CoreDNS 响应: CoreDNS 成功找到对应的 Service IP 地址,并返回给 Pod。
  3. 连接成功: Pod 使用返回的 IP 成功连接到数据库。

如果 Pod 处于不同的命名空间,例如 app-ns,那么它的 search 列表第一项将是 app-ns.svc.cluster.local。如果它尝试访问 default 命名空间中的 my-database,它将需要使用稍微长一点的名字:my-database.default

此时,查询会依次尝试:
1. my-database.default.app-ns.svc.cluster.local (失败)
2. my-database.default.svc.cluster.local (成功)

4. 实践:验证 DNS 解析流程

我们可以使用 nslookup 在 Pod 内部验证这一流程。首先,创建一个测试服务。

# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: simple-db
  namespace: default
spec:
  selector:
    app: db-placeholder
  ports:
    - protocol: TCP
      port: 3306
      targetPort: 3306

部署服务后,进入 debug Pod 并测试解析:

# 1. 在 Pod 内部,使用短名称查询 (仅服务名)
kubectl exec debug -- nslookup simple-db

# 输出示例 (显示了 CoreDNS 自动补全并解析成功)
# Server:     10.96.0.10
# Address:    10.96.0.10#53
# 
# Name:   simple-db.default.svc.cluster.local
# Address: 10.104.10.20 

# 2. 使用 FQDN 查询(CoreDNS 直接解析)
kubectl exec debug -- nslookup simple-db.default.svc.cluster.local

# 3. 如果在不同命名空间,需要带上命名空间名
# nslookup simple-db.default

总结: Pod 能够直接通过服务名访问数据库并非CoreDNS拥有特殊的魔力,而是因为 Kubelet 为 Pod 配置了 CoreDNS 地址作为 nameserver,并设置了包含当前命名空间的 DNS 搜索路径,使得短名称(如 my-database)可以被操作系统自动补全为完全限定域名(FQDN),从而成功查询到 CoreDNS 中的 Service IP。

【本站文章皆为原创,未经允许不得转载】:汤不热吧 » CoreDNS 运行机制详解:为什么 Pod 内部可以直接通过服务名访问数据库
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址