11 Service Discovery DNS Practical Implementation

11 Service Discovery DNS Practical Implementation #

DNS service is a built-in service discovery component in Kubernetes, which allows container services to find each other’s port services through their unique app names, eliminating the need to maintain the relationship between services and IP addresses. This represents a change in traditional enterprise operation and maintenance habits. In general, traditional enterprises maintain a CMDB system internally to manage the correspondence between servers and IP addresses, so as to effectively plan and manage the application service cluster. After deploying the K8s cluster, it is much more convenient for both operation and development to identify services through app names instead of maintaining IP relationships. Therefore, in this article, we will provide a detailed introduction to the practical use of DNS based on actual demand scenarios.

Introduction to CoreDNS #

The early DNS component in Kubernetes was called KubeDNS. Later, the CNCF community introduced a more mature open-source project called CoreDNS to replace KubeDNS. So when we mention KubeDNS now, it actually refers to the CoreDNS project by default. There are several ways to deploy CoreDNS as the DNS service in a Kubernetes cluster. For example, you can use the Helm Chart in the official Helm Chart library for deployment. For specific instructions, please refer to the CoreDNS Helm Chart.

$ helm install --name coredns --namespace=kube-system stable/coredns

Check the coredns Pods to confirm that all Pods are in the Running state:

kubectl get pods -n kube-system -l k8s-app=kube-dns
NAME                       READY     STATUS    RESTARTS   AGE
coredns-699477c54d-9fsl2   1/1       Running   0          5m
coredns-699477c54d-d6tb2   1/1       Running   0          5m
coredns-699477c54d-qh54v   1/1       Running   0          5m
coredns-699477c54d-vvqj9   1/1       Running   0          5m
coredns-699477c54d-xcv8h   1/1       Running   0          6m

Test whether the DNS function is working:

kubectl run curl --image=radial/busyboxplus:curl -i --tty

nslookup kubernetes.default
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      kubernetes
Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local

Service Discovery Rules #

DNS supports service discovery for both Services and Pods. The rules are as follows.

Services #

A record:

  • A DNS A record is assigned to a Service (excluding headless Services), with the format my-svc.my-namespace.svc.cluster.local. This DNS record resolves to the ClusterIP of the Service.
  • A headless Service (without a ClusterIP) is also assigned a DNS A record, with the format my-svc.my-namespace.svc.cluster.local. This DNS record resolves to a collection of IP addresses of a selected set of Pods associated with the Service. The caller should use this collection of IP addresses or choose one IP address from the collection in a round-robin manner.

SRV record: An SRV record is assigned to the named ports (ports with names) of a Service (including headless Services), with the format _my-port-name._my-port-protocol.my-svc.my-namespace.svc.cluster.local.

  • For a regular Service (non-headless), this SRV record resolves to its port number and the domain name my-svc.my-namespace.svc.cluster.local.
  • For a headless Service, this SRV record resolves to multiple results, each corresponding to a backend Pod of the Service, including its port number and the Pod’s domain name auto-generated-pod-name.my-svc.my-namespace.svc.cluster.local.

Pods #

When creating a Pod, Kubernetes uses the value of metadata.name in the Pod definition as the hostname of the Pod instance.

  • There is an optional field spec.hostname in the Pod definition that can be used to directly specify the hostname of the Pod. For example, if the spec.hostname field of a Pod is set to “my-host”, the hostname of the Pod will be set to “my-host” after creation.
  • There is also an optional field spec.subdomain in the Pod definition that can be used to specify the subdomain of the Pod. For example, if the hostname of a Pod in the “my-namespace” namespace is “foo” and the subdomain is “bar”, the fully qualified domain name (FQDN) of the Pod will be “foo.bar.my-namespace.svc.cluster.local”.

Note: A record is not created based on the Pod name, but based on the hostname. If a Pod does not have a hostname and only has a subdomain, Kubernetes will only create an A record for its headless Service, with the format default-subdomain.my-namespace.svc.cluster-domain.example, which points to the IP address of the Pod.

DNS Optimization #

Based on stress testing data, the community has provided a calculation formula for the memory required by CoreDNS:

MB required (default settings) = (Pods + Services) / 1000 + 54

Annotation:

  • 30 MB is reserved for cache, with a default cache size of 10,000 records.
  • 5 MB is reserved for application queries. A single instance of CoreDNS under stress testing can support approximately 30K QPS.

kubedns-perf

Integrating External DNS Services #

In Kubernetes scenarios, enterprises often have their own DNS services by default. When deploying a container cluster, it is desirable to integrate with external DNS services to facilitate internal use within the enterprise.

The default DNS query strategy is ClusterFirst, which means that the first choice for name resolution of an application is the internal CoreDNS of the cluster. However, in order to allow specified aliases to access external services, the following configuration needs to be made:

apiVersion: v1

kind: ConfigMap

metadata:

  name: kube-dns

  namespace: kube-system

data:

  stubDomains: |

    {"consul.local": ["10.150.0.1"]}

  upstreamNameservers: |

    ["8.8.8.8", "8.8.4.4"]

The above example explains how to integrate an external Consul service into the Kubernetes service. If it is a formal domain, it will directly query the upstream DNS server 8.8.8.8.

Summary #

CoreDNS is the most core and easiest-to-understand component in a Kubernetes cluster. It has a single function and is easy to use. However, it is still necessary for everyone to be familiar with the name resolution rules to avoid unnecessary cognitive errors.

References: