Kubernetes creates DNS records for services and pods. You can contact services with consistent DNS names instead of IP addresses.

k8s为service和pods创建DNS记录。你可以使用service相关联的DNS名称而不是IP地址来进行访问

Introduction

Kubernetes DNS schedules a DNS Pod and Service on the cluster, and configures the kubelets to tell individual containers to use the DNS Service’s IP to resolve DNS names.

k8s DNS 在集群上调度DNS Pod和服务,并配置kubelet,来告知单独的容器使用DNS服务器IP来解析DNS名称、

Every Service defined in the cluster (including the DNS server itself) is assigned a DNS name. By default, a client Pod’s DNS search list includes the Pod’s own namespace and the cluster’s default domain.

集群中定义的每个服务(包括DNS服务器自身)都被赋予了一个DNS名称。默认情况下,客户端Pod的DNS搜索列表

Namespaces of Services

A DNS query may return different results based on the namespace of the pod making it. DNS queries that don’t specify a namespace are limited to the pod’s namespace. Access services in other namespaces by specifying it in the DNS query.

DNS 查询可能会根据创建pod的命名空间,返回不同的结果。未指定命名空间的DNS查询会被限制在pod自身的命名空间中。可以在DNS查询中定义命名空间来访问其他命名空间的service

For example, consider a pod in a test namespace. A data service is in the prod namespace.

A query for data returns no results, because it uses the pod’s test namespace.

A query for data.prod returns the intended result, because it specifies the namespace.

DNS queries may be expanded using the pod’s /etc/resolv.conf. Kubelet sets this file for each pod. For example, a query for just data may be expanded to data.test.cluster.local. The values of the search option are used to expand queries. To learn more about DNS queries, see the resolv.conf manual page.

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

In summary, a pod in the test namespace can successfully resolve either data.prod or data.prod.cluster.local.

DNS Records DNS记录

What objects get DNS records?

  1. Services
  2. Pods

哪些对象可以获取DNS记录?

  1. services
  2. Pods

The following sections detail the supported DNS record types and layout that is supported. Any other layout or names or queries that happen to work are considered implementation details and are subject to change without warning. For more up-to-date specification, see Kubernetes DNS-Based Service Discovery.

Services

A/AAAA records

“Normal” (not headless) Services are assigned a DNS A or AAAA record, depending on the IP family of the service, for a name of the form my-svc.my-namespace.svc.cluster-domain.example. This resolves to the cluster IP of the Service.

  • <serviceName>.<namespaceName>.svc.<k8sClusterDomainName>

普通service 被分配了一个DNS A或AAAA记录,根据服务所属的IP族,其域名的形式为my-svc.my-namespace.svc.cluster-domain.exmaple.此域名可用于解析service的集群IP

“Headless” (without a cluster IP) Services are also assigned a DNS A or AAAA record, depending on the IP family of the service, for a name of the form my-svc.my-namespace.svc.cluster-domain.example. Unlike normal Services, this resolves to the set of IPs of the pods selected by the Service. Clients are expected to consume the set or else use standard round-robin selection from the set.

headless service(没有集群IP),同样也被分配了一个DNS A或AAAA记录,根据service所属的ip族。其形式为my-svc.my-namespaces.svc.cluster-domain.example。和普通service不同的是,解析此域名得到的是该service捕获的pod的IP的集合。客户端可以使用此集合或使用标准的转轮策略从这组IP中进行选择

SRV records

SRV Records are created for named ports that are part of normal or Headless Services. For each named port, the SRV record would have the form _my-port-name._my-port-protocol.my-svc.my-namespace.svc.cluster-domain.example. For a regular service, this resolves to the port number and the domain name: my-svc.my-namespace.svc.cluster-domain.example. For a headless service, this resolves to multiple answers, one for each pod that is backing the service, and contains the port number and the domain name of the pod of the form auto-generated-name.my-svc.my-namespace.svc.cluster-domain.example.

k8s会为普通或无头service的命名端口创建SRV记录。对于每个命名端口,SRV记录使用_my-port-name._my-port-protocol,my-svc.my-namespace.svc.cluster-domain.exmaple的格式。

对于常规服务,会解析出端口名和域名:my-svc.my-namespace.svc.cluster-domain.example

对于无头service,会得到多个结果,每个结果对应一个服务背后的Pod,并包含端口号和pod的域名,该域名使用以下形式auto-generated-name.my-svc.my-namespace.svc.cluster-domain.example

Pods

A/AAAA records

In general a pod has the following DNS resolution:

一般而言,pod对应以下DNS解析形式:

pod-ip-address.my-namespace.pod.cluster-domain.example.

For example, if a pod in the default namespace has the IP address 172.17.0.3, and the domain name for your cluster is cluster.local, then the Pod has a DNS name:

例如,一个在default命名空间,ip地址为172.17.0.3的pod,其cluster的域名为cluster.local,则该pod的DNS域名为:

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

Any pods created by a Deployment or DaemonSet exposed by a Service have the following DNS resolution available:

由Deployment或DaemonSet创建,使用service暴露出去的pod有以下DNS解析形式

pod-ip-address.deployment-name.my-namespace.svc.cluster-domain.example.

Pod’s hostname and subdomain fields Pod的hostname和subdomain字段

Currently when a pod is created, its hostname is the Pod’s metadata.name value.

pod被创建后,hostname就是其metadata.name的值

The Pod spec has an optional hostname field, which can be used to specify the Pod’s hostname. When specified, it takes precedence over the Pod’s name to be the hostname of the pod. For example, given a Pod with hostname set to “my-host“, the Pod will have its hostname set to”my-host“.

Pod 的spec中有一个可选的hostname字段,该字段可以用于指定pod的hostname.

当定义此字段时,该字段会优先于pod的名称被设置为hostname。例如,将一个pod的hostname设置为my-host则该pod的hostname就为my-host

The Pod spec also has an optional subdomain field which can be used to specify its subdomain. For example, a Pod with hostname set to “foo“, and subdomain set to “bar“, in namespace”my-namespace“, will have the fully qualified domain name (FQDN) “foo.bar.my-namespace.svc.cluster-domain.example“.

pod 的spec字段也有一个可选的subdomain字段,该字段可用于定义subdomain,例如,一个pod的hostname为’foo’,subdomain为’bar’,位于mynamespace的命名空间中。则其完整有效的域名为foo.bar.my-namespace.svc.cluster-domain.example

Example:

apiVersion: v1
kind: Service
metadata:
  name: default-subdomain
spec:
  selector:
    name: busybox
  clusterIP: None
  ports:
  - name: foo # Actually, no port is needed.
    port: 1234
    targetPort: 1234
---
apiVersion: v1
kind: Pod
metadata:
  name: busybox1
  labels:
    name: busybox
spec:
  hostname: busybox-1
  subdomain: default-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: default-subdomain
  containers:
  - image: busybox:1.28
    command:
      - sleep
      - "3600"
    name: busybox

If there exists a headless service in the same namespace as the pod and with the same name as the subdomain, the cluster’s DNS Server also returns an A or AAAA record for the Pod’s fully qualified hostname. For example, given a Pod with the hostname set to “busybox-1“and the subdomain set to”default-subdomain“, and a headless Service named”default-subdomain“ in the same namespace, the pod will see its own FQDN as “busybox-1.default-subdomain.my-namespace.svc.cluster-domain.example“. DNS serves an A or AAAA record at that name, pointing to the Pod’s IP. Both pods”busybox1“and”busybox2“ can have their distinct A or AAAA records.

如果无头服务和pod处于同一命名空间中,并且和其子域名一致,那么集群的DNS服务器也会为该Pod的全限定主机名返回一个A或AAAA记录。例如,给定一个hostname为”busybox-1”,子域名为”default-subdomain”的pod,以及同命名空间内一个名字为”default-subdomain”的无头service,则pod将看到自己的FQDN为”busybox-1.default-subdomain.my-namespace.svc.cluster-domain.exmaple”.DNS服务器会为该名称提供A或AAAA记录,指向POD的IP地址。”busybox1”和”busybox2”者两个pod会有自己独立的域名

The Endpoints object can specify the hostname for any endpoint addresses, along with its IP.

Note: Because A or AAAA records are not created for Pod names, hostname is required for the Pod’s A or AAAA record to be created. A Pod with no hostname but with subdomain will only create the A or AAAA record for the headless service (default-subdomain.my-namespace.svc.cluster-domain.example), pointing to the Pod’s IP address. Also, Pod needs to become ready in order to have a record unless publishNotReadyAddresses=True is set on the Service.

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

注意:

由于没有为POD名称创建A或AAAA记录,所以要创建Pod的A记录或AAAA记录需要hostname

subdomain没有hostname的pod只会为无头服务创建A或AAAA记录,指向Pod的IP地址。(default-subdomain.my-namespace.svc.cluster-domain.example)

另外,除非在服务上设置了publishNotReadyAddresses=True,否则只有Pod进行就绪状态,才会有与之对应的记录。

Pod’s setHostnameAsFQDN field

FEATURE STATE: Kubernetes v1.20 [beta]

When a Pod is configured to have fully qualified domain name (FQDN), its hostname is the short hostname. For example, if you have a Pod with the fully qualified domain name busybox-1.default-subdomain.my-namespace.svc.cluster-domain.example, then by default the hostname command inside that Pod returns busybox-1 and the hostname --fqdn command returns the FQDN.

When you set setHostnameAsFQDN: true in the Pod spec, the kubelet writes the Pod’s FQDN into the hostname for that Pod’s namespace. In this case, both hostname and hostname --fqdn return the Pod’s FQDN.

Note:

In Linux, the hostname field of the kernel (the nodename field of struct utsname) is limited to 64 characters.

If a Pod enables this feature and its FQDN is longer than 64 character, it will fail to start. The Pod will remain in Pending status (ContainerCreating as seen by kubectl) generating error events, such as Failed to construct FQDN from pod hostname and cluster domain, FQDN long-FQDN is too long (64 characters is the max, 70 characters requested). One way of improving user experience for this scenario is to create an admission webhook controller to control FQDN size when users create top level objects, for example, Deployment.

Pod’s DNS Policy

DNS policies can be set on a per-pod basis. Currently Kubernetes supports the following pod-specific DNS policies. These policies are specified in the dnsPolicy field of a Pod Spec.

  • Default“: The Pod inherits the name resolution configuration from the node that the pods run on. See related discussion for more details.
  • ClusterFirst“: Any DNS query that does not match the configured cluster domain suffix, such as “www.kubernetes.io“, is forwarded to the upstream nameserver inherited from the node. Cluster administrators may have extra stub-domain and upstream DNS servers configured. See related discussion for details on how DNS queries are handled in those cases.
  • ClusterFirstWithHostNet“: For Pods running with hostNetwork, you should explicitly set its DNS policy “ClusterFirstWithHostNet“.
  • None“: It allows a Pod to ignore DNS settings from the Kubernetes environment. All DNS settings are supposed to be provided using the dnsConfig field in the Pod Spec. See Pod’s DNS config subsection below.

Note: “Default” is not the default DNS policy. If dnsPolicy is not explicitly specified, then “ClusterFirst” is used.

The example below shows a Pod with its DNS policy set to “ClusterFirstWithHostNet“ because it has hostNetwork set to 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’s DNS Config

Pod’s DNS Config allows users more control on the DNS settings for a Pod.

The dnsConfig field is optional and it can work with any dnsPolicy settings. However, when a Pod’s dnsPolicy is set to “None“, the dnsConfig field has to be specified.

Below are the properties a user can specify in the dnsConfig field:

  • nameservers: a list of IP addresses that will be used as DNS servers for the Pod. There can be at most 3 IP addresses specified. When the Pod’s dnsPolicy is set to “None“, the list must contain at least one IP address, otherwise this property is optional. The servers listed will be combined to the base nameservers generated from the specified DNS policy with duplicate addresses removed.
  • searches: a list of DNS search domains for hostname lookup in the Pod. This property is optional. When specified, the provided list will be merged into the base search domain names generated from the chosen DNS policy. Duplicate domain names are removed. Kubernetes allows for at most 6 search domains.
  • options: an optional list of objects where each object may have a name property (required) and a value property (optional). The contents in this property will be merged to the options generated from the specified DNS policy. Duplicate entries are removed.

The following is an example Pod with custom DNS settings:

apiVersion: v1
kind: Pod
metadata:
  namespace: default
  name: dns-example
spec:
  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

When the Pod above is created, the container test gets the following contents in its /etc/resolv.conf file:

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

For IPv6 setup, search path and name server should be setup like this:

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

The output is similar to this:

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

Feature availability

The availability of Pod DNS Config and DNS Policy “None“ is shown as below.

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

What’s next

For guidance on administering DNS configurations, check Configure DNS Service

Last modified February 05, 2021 at 11:25 PM PST: revise docs for service DNS (5ead4bf8e)