Using kube-dns


This page describes how Google Kubernetes Engine (GKE) implements service discovery using kube-dns, the default DNS provider for GKE clusters.

Architecture

When you create a cluster, GKE automatically deploys kube-dns pods in the kube-system namespace. Pods access the kube-dns deployment through a corresponding Service that groups the kube-dns pods and gives them a single IP address (ClusterIP). By default, all pods in a cluster use this Service to resolve DNS queries. The following diagram shows the relationship between pods and the kube-dns Service.

kube-dns Pods relationship with the kube-dns service

kube-dns scales to meet the DNS demands of the cluster. This scaling is controlled by the kube-dns-autoscaler, a Pod that is deployed by default in all GKE clusters. The kube-dns-autoscaler adjusts the number of replicas in the kube-dns Deployment based on the number of nodes and cores in the cluster.

How Pod DNS is configured

The kubelet running on each Node configures the Pod's etc/resolv.conf to use the kube-dns service's ClusterIP. The following example configuration shows that the IP address of the kube-dns service is 10.0.0.10. This IP address is different in other clusters.

nameserver 10.0.0.10
search default.svc.cluster.local svc.cluster.local cluster.local c.my-project-id.internal google.internal
options ndots:5

kube-dns is the authoritative name server for the cluster domain (cluster.local) and it resolves external names recursively. Short names that are not fully qualified, such as myservice, are completed first with local search paths.

Adding custom resolvers for stub domains

You can modify the ConfigMap for kube-dns to set stub domains as part of DNS infrastructure within your clusters.

Stub domains let you configure custom per-domain resolvers so that kube-dns forwards DNS requests to specific upstream DNS servers when resolving these domains.

The following example ConfigMap manifest for kube-dns includes a stubDomains configuration that sets custom resolvers for the domain example.com.

apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    addonmanager.kubernetes.io/mode: EnsureExists
  name: kube-dns
  namespace: kube-system
data:
  stubDomains: |
    {
      "example.com": [
        "8.8.8.8",
        "8.8.4.4",
        "1.1.1.1",
        "1.0.0.1"
      ]
    }

Run the following command to open a text editor:

kubectl edit configmap kube-dns -n kube-system

Replace the contents of the file with the manifest and then exit the text editor to apply the manifest to the cluster.

Upstream nameservers

If you modify the ConfigMap for kube-dns to include upstreamNameservers, kube-dns forwards all DNS requests except *.cluster.local to those servers. This includes metadata.internal and *.google.internal, which are not resolvable by the upstream server.

If you enable Workload Identity or any workloads that rely on metadata.internal resolution, do not use upstreamNameservers. Use stubDomains instead.

What's next