• Pod 与 Service 的 DNS
    • 介绍
    • 怎样获取 DNS 名字?
    • 支持的 DNS 模式
      • Service
        • A 记录
        • SRV 记录
    • Pods
      • Pod的 hostname 和 subdomain 字段
      • Pod 的 DNS 设定
      • 可用功能
    • 接下来
    • 反馈

    Pod 与 Service 的 DNS

    该页面概述了Kubernetes对DNS的支持。

    介绍

    Kubernetes DNS 在群集上调度 DNS Pod 和服务,并配置 kubelet 以告知各个容器使用 DNS 服务的 IP 来解析 DNS 名称。

    怎样获取 DNS 名字?

    在集群中定义的每个 Service(包括 DNS 服务器自身)都会被指派一个 DNS 名称。默认,一个客户端 Pod 的 DNS 搜索列表将包含该 Pod 自己的 Namespace 和集群默认域。通过如下示例可以很好地说明:

    假设在 Kubernetes 集群的 Namespace bar 中,定义了一个Service foo。运行在Namespace bar 中的一个 Pod,可以简单地通过 DNS 查询 foo 来找到该 Service。运行在 Namespace quux 中的一个 Pod 可以通过 DNS 查询 foo.bar 找到该 Service。

    以下各节详细介绍了受支持的记录类型和支持的布局。 其中代码部分的布局,名称或查询命令均被视为实现细节,如有更改,恕不另行通知。有关最新规范请查看Kubernetes 基于 DNS 的服务发现.

    支持的 DNS 模式

    下面各段详细说明支持的记录类型和布局。如果任何其它的布局、名称或查询,碰巧也能够使用,这就需要研究下它们的实现细节,以免后续修改它们又不能使用了。

    Service

    A 记录

    “正常” Service(除了 Headless Service)会以 my-svc.my-namespace.svc.cluster-domain.example 这种名字的形式被指派一个 DNS A 记录。这会解析成该 Service 的 Cluster IP。

    “Headless” Service(没有Cluster IP)也会以 my-svc.my-namespace.svc.cluster-domain.example 这种名字的形式被指派一个 DNS A 记录。不像正常 Service,它会解析成该 Service 选择的一组 Pod 的 IP。希望客户端能够使用这一组 IP,否则就使用标准的 round-robin 策略从这一组 IP 中进行选择。

    SRV 记录

    命名端口需要创建 SRV 记录,这些端口是正常 Service或 HeadlessServices 的一部分。对每个命名端口,SRV 记录具有 _my-port-name._my-port-protocol.my-svc.my-namespace.svc.cluster-domain.example 这种形式。对普通 Service,这会被解析成端口号和 CNAME:my-svc.my-namespace.svc.cluster-domain.example。对 Headless Service,这会被解析成多个结果,Service 对应的每个 backend Pod 各一个,包含 auto-generated-name.my-svc.my-namespace.svc.cluster-domain.example 这种形式 Pod 的端口号和 CNAME。

    Pods

    Pod的 hostname 和 subdomain 字段

    当前,创建 Pod 后,它的主机名是该 Pod 的 metadata.name 值。

    在 v1.2 版本中,用户可以配置 Pod annotation, 通过 pod.beta.kubernetes.io/hostname 来设置 Pod 的主机名。如果为 Pod 配置了 annotation,会优先使用 Pod 的名称作为主机名。例如,给定一个 Pod,它具有 annotation pod.beta.kubernetes.io/hostname: my-pod-name,该 Pod 的主机名被设置为 “my-pod-name”。

    在 v1.3 版本中,PodSpec 具有 hostname 字段,可以用来指定 Pod 的主机名。这个字段的值优先于 annotation pod.beta.kubernetes.io/hostname。在 v1.2 版本中引入了 beta 特性,用户可以为 Pod 指定 annotation,其中 pod.beta.kubernetes.io/subdomain 指定了 Pod 的子域名。最终的域名将是 “...svc.”。举个例子,Pod 的主机名 annotation 设置为 “foo”,子域名 annotation 设置为 “bar”,在 Namespace “my-namespace” 中对应的 FQDN 为 “foo.bar.my-namespace.svc.cluster.local”。

    在 v1.3 版本中,PodSpec 具有 subdomain 字段,可以用来指定 Pod 的子域名。这个字段的值优先于 annotation pod.beta.kubernetes.io/subdomain 的值。

    实例:

    1. apiVersion: v1
    2. kind: Service
    3. metadata:
    4. name: default-subdomain
    5. spec:
    6. selector:
    7. name: busybox
    8. clusterIP: None
    9. ports:
    10. - name: foo # Actually, no port is needed.
    11. port: 1234
    12. targetPort: 1234
    13. ---
    14. apiVersion: v1
    15. kind: Pod
    16. metadata:
    17. name: busybox1
    18. labels:
    19. name: busybox
    20. spec:
    21. hostname: busybox-1
    22. subdomain: default-subdomain
    23. containers:
    24. - image: busybox:1.28
    25. command:
    26. - sleep
    27. - "3600"
    28. name: busybox
    29. ---
    30. apiVersion: v1
    31. kind: Pod
    32. metadata:
    33. name: busybox2
    34. labels:
    35. name: busybox
    36. spec:
    37. hostname: busybox-2
    38. subdomain: default-subdomain
    39. containers:
    40. - image: busybox:1.28
    41. command:
    42. - sleep
    43. - "3600"
    44. name: busybox

    如果 Headless Service 与 Pod 在同一个 Namespace 中,它们具有相同的子域名,集群的 KubeDNS 服务器也会为该 Pod 的完整合法主机名返回 A 记录。例如,在同一个 Namespace 中,给定一个主机名为 “busybox-1” 的 Pod,子域名设置为 “default-subdomain”,名称为 “default-subdomain” 的 Headless Service ,Pod 将看到自己的 FQDN 为 “busybox-1.default-subdomain.my-namespace.svc.cluster.local”。DNS 会为那个名字提供一个 A 记录,指向该 Pod 的 IP。“busybox1” 和 “busybox2” 这两个 Pod 分别具有它们自己的 A 记录。

    端点对象可以为任何端点地址及其 IP 指定 hostname

    注意:

    因为没有为 Pod 名称创建A记录,所以要创建 Pod 的 A 记录需要 hostname

    没有 hostname 但带有 subdomain 的 Pod 只会为指向Pod的IP地址的 headless 服务创建 A 记录(default-subdomain.my-namespace.svc.cluster-domain.example)。另外,除非在服务上设置了 publishNotReadyAddresses=True,否则 Pod 需要准备好 A 记录。

    • Default“: Pod从运行所在的节点继承名称解析配置。参考 相关讨论 获取更多信息。
    • ClusterFirst“: 与配置的群集域后缀不匹配的任何DNS查询(例如 “www.kubernetes.io” )都将转发到从节点继承的上游名称服务器。 群集管理员可能配置了额外的存根域和上游DNS服务器。See 相关讨论 获取如何 DNS 的查询和处理信息的相关资料。
    • ClusterFirstWithHostNet“: 对于与 hostNetwork 一起运行的 Pod,应显式设置其DNS策略 “ClusterFirstWithHostNet“。
    • None“: 它允许 Pod 忽略 Kubernetes 环境中的 DN S设置。 应该使用 Pod Spec 中的 dnsConfig 字段提供所有 DNS 设置。
    注意:

    “Default” 不是默认的 DNS 策略。 如果未明确指定 dnsPolicy,则使用 “ClusterFirst”。

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

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: busybox
    5. namespace: default
    6. spec:
    7. containers:
    8. - image: busybox:1.28
    9. command:
    10. - sleep
    11. - "3600"
    12. imagePullPolicy: IfNotPresent
    13. name: busybox
    14. restartPolicy: Always
    15. hostNetwork: true
    16. dnsPolicy: ClusterFirstWithHostNet

    Pod 的 DNS 设定

    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最多允许6个搜索域。
    • options: 对象的可选列表,其中每个对象可能具有 name 属性(必需)和 value 属性(可选)。 此属性中的内容将合并到从指定的 DNS 策略生成的选项。重复的条目将被删除。

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

    service/networking/custom-dns.yamlPod 与 Service 的 DNS - 图1
    1. apiVersion: v1kind: Podmetadata: namespace: default name: dns-examplespec: containers: - name: test image: nginx dnsPolicy: "None" dnsConfig: nameservers: - 1.2.3.4 searches: - ns1.svc.cluster-domain.example - my.dns.search.suffix options: - name: ndots value: "2" - name: edns0

    创建上面的Pod后,容器 test 会在其 /etc/resolv.conf 文件中获取以下内容:

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

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

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

    有以下输出:

    1. nameserver fd00:79:30::a
    2. search default.svc.cluster-domain.example svc.cluster-domain.example cluster-domain.example
    3. options ndots:5

    可用功能

    Pod DNS 配置和 DNS 策略 “None” 的版本对应如下所示。

    k8s versionFeature support
    1.14Stable
    1.10Beta (on by default)
    1.9Alpha

    接下来

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

    反馈

    此页是否对您有帮助?

    感谢反馈。如果您有一个关于如何使用 Kubernetes 的特定的、需要答案的问题,可以访问Stack Overflow.在 GitHub 仓库上登记新的问题报告问题或者提出改进建议.