DNS for Services and Pods

    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.

    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.

    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.

    For example, consider a pod in a 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.svc.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.

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

    DNS Records

    What objects get DNS records?

    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.

    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.

    “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.

    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.

    A/AAAA records

    In general a pod has the following DNS resolution:

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

    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:

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

    Pod’s hostname and subdomain fields

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

    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“.

    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“.

    Example:

    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. apiVersion: v1
    14. kind: Pod
    15. metadata:
    16. name: busybox1
    17. labels:
    18. spec:
    19. hostname: busybox-1
    20. subdomain: default-subdomain
    21. containers:
    22. - image: busybox:1.28
    23. command:
    24. - sleep
    25. - "3600"
    26. name: busybox
    27. ---
    28. apiVersion: v1
    29. kind: Pod
    30. metadata:
    31. name: busybox2
    32. labels:
    33. name: busybox
    34. spec:
    35. hostname: busybox-2
    36. subdomain: default-subdomain
    37. containers:
    38. - image: busybox:1.28
    39. command:
    40. - sleep
    41. 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.

    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.

    FEATURE STATE: Kubernetes v1.22 [stable]

    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.

    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 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 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.

    Pod’s DNS Config

    FEATURE STATE: Kubernetes v1.14 [stable]

    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:

    service/networking/custom-dns.yaml

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. namespace: default
    5. name: dns-example
    6. spec:
    7. containers:
    8. - name: test
    9. image: nginx
    10. dnsPolicy: "None"
    11. dnsConfig:
    12. nameservers:
    13. - 1.2.3.4
    14. searches:
    15. - ns1.svc.cluster-domain.example
    16. - my.dns.search.suffix
    17. options:
    18. - name: ndots
    19. value: "2"
    20. - name: edns0

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

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

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

    The output is similar to this:

    Expanded DNS Configuration

    FEATURE STATE: Kubernetes 1.22 [alpha]

    By default, for Pod’s DNS Config, Kubernetes allows at most 6 search domains and a list of search domains of up to 256 characters.

    If the feature gate ExpandedDNSConfig is enabled for the kube-apiserver and the kubelet, it is allowed for Kubernetes to have at most 32 search domains and a list of search domains of up to 2048 characters.

    For guidance on administering DNS configurations, check Configure DNS Service