服务和 Pod 的 DNS

您的工作负载可以使用 DNS 在集群内发现服务;此页面解释其工作原理。

Kubernetes 为服务和 Pod 创建 DNS 记录。 您可以使用一致的 DNS 名称而不是 IP 地址来联系服务。

Kubernetes 发布关于 Pod 和服务的信息,用于编程 DNS。 Kubelet 配置 Pod 的 DNS,以便正在运行的容器可以通过名称而不是 IP 查找服务。

集群中定义的服务会分配 DNS 名称。 默认情况下,客户端 Pod 的 DNS 搜索列表包括 Pod 自己的命名空间和集群的默认域。

服务的命名空间

DNS 查询可能会根据发出查询的 Pod 的命名空间返回不同的结果。 未指定命名空间的 DNS 查询仅限于 Pod 的命名空间。 通过在 DNS 查询中指定其他命名空间来访问这些命名空间中的服务。

例如,考虑一个位于 test 命名空间中的 Pod。一个 data 服务位于 prod 命名空间中。

data 的查询不返回任何结果,因为它使用 Pod 的 test 命名空间。

data.prod 的查询返回预期结果,因为它指定了命名空间。

可以使用 Pod 的 /etc/resolv.conf 扩展 DNS 查询。 Kubelet 为每个 Pod 配置此文件。 例如,对 data 的查询可能会扩展为 data.test.svc.cluster.localsearch 选项的值用于扩展查询。 要了解有关 DNS 查询的更多信息,请参阅 resolv.conf 手册页。

nameserver 10.32.0.10
search <namespace>.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

总而言之,*test* 命名空间中的 Pod 可以成功解析 data.proddata.prod.svc.cluster.local

DNS 记录

哪些对象会获得 DNS 记录?

  1. 服务
  2. Pod

以下部分详细介绍了支持的 DNS 记录类型和支持的布局。任何其他恰好可以工作的布局或名称或查询都被认为是实现细节,可能会在没有警告的情况下更改。 有关最新的规范,请参阅 基于 Kubernetes DNS 的服务发现

服务

A/AAAA 记录

“普通”(非无头)服务会分配 DNS A 和/或 AAAA 记录,具体取决于服务的 IP 系列,名称格式为 my-svc.my-namespace.svc.cluster-domain.example。 这解析为服务的集群 IP。

无头服务(没有集群 IP)也会分配 DNS A 和/或 AAAA 记录,名称格式为 my-svc.my-namespace.svc.cluster-domain.example。 与普通服务不同,这解析为服务选择的所有 Pod 的 IP 集。 客户端应使用该集合,否则应使用该集合中的标准轮循选择。

SRV 记录

为属于普通或无头服务的命名端口创建 SRV 记录。 对于每个命名端口,SRV 记录的格式为 _port-name._port-protocol.my-svc.my-namespace.svc.cluster-domain.example。 对于常规服务,这会解析为端口号和域名:my-svc.my-namespace.svc.cluster-domain.example。 对于无头服务,这会解析为多个答案,每个答案对应一个支持该服务的 Pod,并包含端口号和 Pod 的域名,格式为 hostname.my-svc.my-namespace.svc.cluster-domain.example

Pod

A/AAAA 记录

在实现 DNS 规范之前,Kube-DNS 版本具有以下 DNS 解析

pod-ipv4-地址.我的命名空间.pod.集群域名.示例.

例如,如果 default 命名空间中的 Pod 的 IP 地址为 172.17.0.3,并且你的集群的域名为 cluster.local,则该 Pod 的 DNS 名称为

172-17-0-3.default.pod.cluster.local.

由服务公开的任何 Pod 都具有以下可用的 DNS 解析

pod-ipv4-地址.服务名称.我的命名空间.svc.集群域名.示例.

Pod 的主机名和子域字段

目前,创建 Pod 时,它的主机名(从 Pod 内部观察)是 Pod 的 metadata.name 值。

Pod 规约有一个可选的 hostname 字段,可用于指定不同的主机名。 指定后,它将优先于 Pod 的名称成为 Pod 的主机名(同样,从 Pod 内部观察)。 例如,如果 Pod 的 spec.hostname 设置为 "my-host",则该 Pod 的主机名将设置为 "my-host"

Pod 规约还有一个可选的 subdomain 字段,可用于指示 Pod 是命名空间的子组的一部分。 例如,在命名空间 "my-namespace" 中,如果 Pod 的 spec.hostname 设置为 "foo",并且 spec.subdomain 设置为 "bar",则其主机名将设置为 "foo",并且其完全限定域名 (FQDN) 将设置为 "foo.bar.my-namespace.svc.cluster.local"(再次,从 Pod 内部观察)。

如果在与 Pod 相同的命名空间中存在一个无头服务,并且该服务的名称与子域名相同,则集群的 DNS 服务器还会为 Pod 的完全限定主机名返回 A 和/或 AAAA 记录。

示例

apiVersion: v1
kind: Service
metadata:
  name: busybox-subdomain
spec:
  selector:
    name: busybox
  clusterIP: None
  ports:
  - name: foo # name is not required for single-port Services
    port: 1234
---
apiVersion: v1
kind: Pod
metadata:
  name: busybox1
  labels:
    name: busybox
spec:
  hostname: busybox-1
  subdomain: busybox-subdomain
  containers:
  - image: busybox:1.28
    command:
      - sleep
      - "3600"
    name: busybox
---
apiVersion: v1
kind: Pod
metadata:
  name: busybox2
  labels:
    name: busybox
spec:
  hostname: busybox-2
  subdomain: busybox-subdomain
  containers:
  - image: busybox:1.28
    command:
      - sleep
      - "3600"
    name: busybox

给定以上服务 "busybox-subdomain" 和将 spec.subdomain 设置为 "busybox-subdomain" 的 Pod,第一个 Pod 将看到其自身的 FQDN 为 "busybox-1.busybox-subdomain.my-namespace.svc.cluster-domain.example"。 DNS 在该名称处提供 A 和/或 AAAA 记录,指向 Pod 的 IP。 Pod "busybox1" 和 "busybox2" 都将有自己的地址记录。

EndpointSlice 可以指定任何端点地址的 DNS 主机名及其 IP。

Pod 的 setHostnameAsFQDN 字段

特性状态:Kubernetes v1.22 [稳定]

当 Pod 配置为具有完全限定域名 (FQDN) 时,其主机名是短主机名。 例如,如果你的 Pod 的完全限定域名为 busybox-1.busybox-subdomain.my-namespace.svc.cluster-domain.example,则默认情况下,该 Pod 内的 hostname 命令会返回 busybox-1,而 hostname --fqdn 命令会返回 FQDN。

当你在 Pod 规约中设置 setHostnameAsFQDN: true 时,kubelet 会将 Pod 的 FQDN 写入该 Pod 的命名空间的主机名中。 在这种情况下,hostnamehostname --fqdn 都返回 Pod 的 FQDN。

Pod 的 DNS 策略

可以根据每个 Pod 设置 DNS 策略。 目前,Kubernetes 支持以下特定于 Pod 的 DNS 策略。 这些策略在 Pod 规约的 dnsPolicy 字段中指定。

  • Default”:Pod 从运行 Pod 的节点继承名称解析配置。 有关更多详细信息,请参阅相关讨论
  • "ClusterFirst":任何不匹配配置的集群域后缀(例如 "www.kubernetes.io")的 DNS 查询都会被 DNS 服务器转发到上游名称服务器。集群管理员可能配置了额外的存根域和上游 DNS 服务器。有关 DNS 查询在这些情况下如何处理的详细信息,请参阅相关讨论
  • "ClusterFirstWithHostNet":对于使用 hostNetwork 运行的 Pod,您应该显式将其 DNS 策略设置为 "ClusterFirstWithHostNet"。否则,使用 hostNetwork 运行且 DNS 策略为 "ClusterFirst" 的 Pod 将会回退到 "Default" 策略的行为。
    • 注意:Windows 不支持此策略。有关详细信息,请参阅下面的DNS on Windows部分。
  • "None":它允许 Pod 忽略 Kubernetes 环境中的 DNS 设置。所有 DNS 设置都应使用 Pod 规约中的 dnsConfig 字段提供。请参阅下面的Pod 的 DNS 配置小节。

下面的示例显示了一个 Pod,其 DNS 策略设置为 "ClusterFirstWithHostNet",因为它将 hostNetwork 设置为 true

apiVersion: v1
kind: Pod
metadata:
  name: busybox
  namespace: default
spec:
  containers:
  - image: busybox:1.28
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
    name: busybox
  restartPolicy: Always
  hostNetwork: true
  dnsPolicy: ClusterFirstWithHostNet

Pod 的 DNS 配置

功能状态:Kubernetes v1.14 [stable]

Pod 的 DNS 配置允许用户更好地控制 Pod 的 DNS 设置。

dnsConfig 字段是可选的,它可以与任何 dnsPolicy 设置一起使用。但是,当 Pod 的 dnsPolicy 设置为 "None" 时,必须指定 dnsConfig 字段。

以下是用户可以在 dnsConfig 字段中指定的属性:

  • nameservers:将用作 Pod 的 DNS 服务器的 IP 地址列表。最多可以指定 3 个 IP 地址。当 Pod 的 dnsPolicy 设置为 "None" 时,该列表必须至少包含一个 IP 地址,否则此属性是可选的。列出的服务器将与从指定的 DNS 策略生成的基本名称服务器合并,删除重复的地址。
  • searches:用于在 Pod 中查找主机名的 DNS 搜索域列表。此属性是可选的。指定后,提供的列表将合并到从所选 DNS 策略生成的基本搜索域名中。删除重复的域名。Kubernetes 允许最多 32 个搜索域。
  • options:一个可选的对象列表,其中每个对象可能具有 name 属性(必需)和 value 属性(可选)。此属性中的内容将合并到从指定的 DNS 策略生成的选项中。删除重复的条目。

以下是具有自定义 DNS 设置的 Pod 的示例:

apiVersion: v1
kind: Pod
metadata:
  namespace: default
  name: dns-example
spec:
  containers:
    - name: test
      image: nginx
  dnsPolicy: "None"
  dnsConfig:
    nameservers:
      - 192.0.2.1 # this is an example
    searches:
      - ns1.svc.cluster-domain.example
      - my.dns.search.suffix
    options:
      - name: ndots
        value: "2"
      - name: edns0

创建上述 Pod 时,容器 test 在其 /etc/resolv.conf 文件中获得以下内容:

nameserver 192.0.2.1
search ns1.svc.cluster-domain.example my.dns.search.suffix
options ndots:2 edns0

对于 IPv6 设置,应按如下方式设置搜索路径和名称服务器:

kubectl exec -it dns-example -- cat /etc/resolv.conf

输出类似于以下内容:

nameserver 2001:db8:30::a
search default.svc.cluster-domain.example svc.cluster-domain.example cluster-domain.example
options ndots:5

DNS 搜索域列表限制

功能状态:Kubernetes 1.28 [stable]

Kubernetes 本身不限制 DNS 配置,直到搜索域列表的长度超过 32 个或所有搜索域的总长度超过 2048 个。此限制分别适用于节点的解析器配置文件、Pod 的 DNS 配置以及合并的 DNS 配置。

Windows 节点上的 DNS 解析

  • 对于在 Windows 节点上运行的 Pod,不支持 ClusterFirstWithHostNet。Windows 将所有带有 . 的名称视为 FQDN,并跳过 FQDN 解析。
  • 在 Windows 上,可以使用多个 DNS 解析器。由于它们的行为略有不同,建议使用 Resolve-DNSName powershell cmdlet 进行名称查询解析。
  • 在 Linux 上,您有一个 DNS 后缀列表,它在完全限定名称解析失败后使用。在 Windows 上,您只能有 1 个 DNS 后缀,它是与该 Pod 命名空间关联的 DNS 后缀(示例:mydns.svc.cluster.local)。Windows 可以解析 FQDN、服务或可以使用此单个后缀解析的网络名称。例如,在 default 命名空间中生成的 Pod 将具有 DNS 后缀 default.svc.cluster.local。在 Windows Pod 中,您可以解析 kubernetes.default.svc.cluster.localkubernetes,但不能解析部分限定的名称 (kubernetes.defaultkubernetes.default.svc)。

下一步

有关管理 DNS 配置的指南,请查看配置 DNS 服务

上次修改时间:2024 年 8 月 22 日上午 8:11(太平洋标准时间):更新 content/en/docs/concepts/services-networking/dns-pod-service.md (d4812b0d50)