Every Kubernetes cluster has a built-in DNS add-on (Kube-DNS or CoreDNS) to provide domain name resolution for workloads in the cluster. When handling a high concurrency of DNS queries, Kube-DNS/CoreDNS may encounter a performance bottleneck, that is, it may fail occasionally to fulfill DNS queries. Kubernetes workloads occasionally generate unnecessary DNS queries, which can overload the DNS system during periods of high query concurrency. Tuning DNS configuration for workloads will reduce the risks of DNS query failures to some extent.
For more information about DNS, see CoreDNS.
Run the cat /etc/resolv.conf command on a Linux node or container to view the DNS resolver configuration file. The following is an example DNS resolver configuration of a container in a Kubernetes cluster:
nameserver 10.247.x.xsearch default.svc.cluster.local svc.cluster.local cluster.localoptions single-request-reopen timeout:2 ndots:5
Configuration Options
The value ndots:5 means that if a domain name has fewer than 5 dots (.), DNS queries will be attempted by combining the domain name with each domain in the search list in turn. If no match is found after all the domains in the search list are tried, the domain name is then used for DNS query. If the domain name has 5 or more than 5 dots, it will be tried first for DNS query. In case that the domain name cannot be resolved, DNS queries will be attempted by combining the domain name with each domain in the search list in turn.
For example, the domain name www.***.com has only two dots (smaller than the value of ndots), and therefore the sequence of DNS queries is as follows: www.***.com.default.svc.cluster.local, www.***.com.svc.cluster.local, www.***.com.cluster.local, and www.***.com. This means that at least seven DNS queries will be initiated before the domain name is resolved into an IP address. It is clear that when many unnecessary DNS queries will be initiated to access an external domain name. There is room for improvement in workload's DNS configuration.
For details about the configuration items in the Linux DNS resolver configuration file, see https://man7.org/linux/man-pages/man5/resolv.conf.5.html.
Kubernetes provides DNS-related configuration options for applications. The use of application's DNS configuration can effectively reduce unnecessary DNS queries in certain scenarios and improve service concurrency. The following procedure uses an Nginx application as an example to describe how to add DNS configurations for a workload on the console.
When creating a workload using a YAML file, you can configure the DNS settings in the YAML. The following is an example for an Nginx application:
apiVersion: apps/v1kind: Deploymentmetadata:name: nginxnamespace: defaultspec:replicas: 1selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: container-1image: nginx:latestimagePullPolicy: IfNotPresentimagePullSecrets:- name: default-secretdnsPolicy: NonednsConfig:options:- name: ndotsvalue: '5'- name: timeoutvalue: '3'nameservers:- 10.2.3.4searches:- my.dns.search.suffix
The dnsPolicy field is used to configure a DNS policy for an application. The default value is ClusterFirst. The following table lists dnsPolicy configurations.
Parameter | Description |
|---|---|
ClusterFirst (default value) | Custom DNS configuration added to the default DNS configuration. By default, the application connects to CoreDNS (CoreDNS of the CCE cluster connects to the DNS on the cloud by default). The custom dnsConfig will be added to the default DNS parameters. Containers can resolve both the cluster-internal domain names registered by a Service and the external domain names exposed to public networks. The search list (search option) and ndots: 5 are present in the DNS configuration file. Therefore, when accessing an external domain name and a long cluster-internal domain name (for example, kubernetes.default.svc.cluster.local), the search list will usually be traversed first, resulting in at least six invalid DNS queries. The issue of invalid DNS queries disappears only when a short cluster-internal domain name (for example, kubernetes) is being accessed. |
ClusterFirstWithHostNet | By default, the applications configured with the host network are interconnected with the DNS configuration of the node where the pod is located. The DNS configuration is specified in the DNS file that the kubelet --resolv-conf parameter points to. In this case, the CCE cluster uses the DNS on the cloud. If workloads need to use Kube-DNS/CoreDNS of the cluster, set dnsPolicy to ClusterFirstWithHostNet and container's DNS configuration file is the same as ClusterFirst, in which invalid DNS queries still exist.
|
Default | The DNS configuration of the node where the pod is located is inherited, and the custom DNS configuration is added to the inherited configuration. Container's DNS configuration file is the DNS configuration file that the kubelet's --resolv-conf flag points to. In this case, a cloud DNS is used for CCE clusters. Both search and options fields are left unspecified. This configuration can only resolve the external domain names registered with the Internet, and not cluster-internal domain names. This configuration is free from the issue of invalid DNS queries. |
None | The default DNS configuration is replaced by the custom DNS configuration, and only the custom DNS configuration is used. If dnsPolicy is set to None, the dnsConfig field must be specified because all DNS settings are supposed to be provided using the dnsConfig field. |
If the dnsPolicy field is not specified, the default value is ClusterFirst instead of Default.
The dnsConfig field is used to configure DNS parameters for workloads. The configured parameters are merged to the DNS configuration file generated according to dnsPolicy. If dnsPolicy is set to None, the workload's DNS configuration file is specified by the dnsConfig field. If dnsPolicy is not set to None, the DNS parameters configured in dnsConfig are added to the DNS configuration file generated according to dnsPolicy.
Parameter | Description |
|---|---|
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 in dnsPolicy. Duplicate entries are removed. |
nameservers | A list of IP addresses that will be used as DNS servers. If workload'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 nameservers generated from the specified DNS policy in dnsPolicy with duplicate addresses removed. NOTE: A maximum of three DNS addresses can be configured for a nameserver in the container DNS configuration file.
|
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 search domain names generated from the chosen DNS policy in dnsPolicy. Duplicate domain names are removed. Kubernetes allows for at most 6 search domains. |
The following example describes how to configure DNS for workloads.
Scenario
Kubernetes in-cluster Kube-DNS/CoreDNS applies to resolving only cluster-internal domain names or cluster-internal domain names + external domain names. This is the default DNS for workloads.
Example:
apiVersion: v1kind: Podmetadata:namespace: defaultname: dns-examplespec:containers:- name: testimage: nginx:alpinednsPolicy: ClusterFirstimagePullSecrets:- name: default-secret
Container's DNS configuration file:
nameserver 10.247.3.10search default.svc.cluster.local svc.cluster.local cluster.localoptions timeout:2 single-request-reopen ndots:5
Scenario
A DNS cannot resolve cluster-internal domain names and therefore applies to the scenario where workloads access only external domain names registered with the Internet.
Example:
apiVersion: v1kind: Podmetadata:namespace: defaultname: dns-examplespec:containers:- name: testimage: nginx:alpinednsPolicy: Default # The DNS configuration file that the kubelet --resolv-conf parameter points to is used. In this case, the CCE cluster uses the DNS on the cloud.imagePullSecrets:- name: default-secret
The DNS configuration file of the container is as follows: (100.125.x.x is the DNS address of the node subnet.)
nameserver 100.125.x.xoptions timeout:2 single-request-reopen
Scenario
By default, a DNS is used for workloads running with hostNetwork. If workloads need to use Kube-DNS/CoreDNS, set dnsPolicy to ClusterFirstWithHostNet.
Example:
apiVersion: v1kind: Podmetadata:name: nginxspec:hostNetwork: truednsPolicy: ClusterFirstWithHostNetcontainers:- name: nginximage: nginx:alpineports:- containerPort: 80imagePullSecrets:- name: default-secret
Container's DNS configuration file:
nameserver 10.247.3.10search default.svc.cluster.local svc.cluster.local cluster.localoptions ndots:5 single-request-reopen timeout:2
Scenario
You can flexibly customize the DNS configuration file for applications. Using dnsPolicy and dnsConfig together can address almost all scenarios, including the scenarios in which an on-premises DNS will be used, multiple DNSs will be cascaded, and DNS configuration options will be modified.
Example 1: Using Your On-Premises DNS
Set dnsPolicy to None so application's DNS configuration file is generated based on dnsConfig.
apiVersion: v1kind: Podmetadata:namespace: defaultname: dns-examplespec:containers:- name: testimage: nginx:alpinednsPolicy: "None"dnsConfig:nameservers:- 10.2.3.4 # IP address of your on-premises DNSsearches:- ns1.svc.cluster.local- my.dns.search.suffixoptions:- name: ndotsvalue: "2"- name: timeoutvalue: "3"imagePullSecrets:- name: default-secret
Container's DNS configuration file:
nameserver 10.2.3.4search ns1.svc.cluster.local my.dns.search.suffixoptions timeout:3 ndots:2 single-request-reopen
Example 2: Modifying the ndots Option in the DNS Configuration File to Reduce Invalid DNS Queries
Set dnsPolicy to a value other than None so the DNS parameters configured in dnsConfig are added to the DNS configuration file generated based on dnsPolicy.
apiVersion: v1kind: Podmetadata:namespace: defaultname: dns-examplespec:containers:- name: testimage: nginx:alpinednsPolicy: "ClusterFirst"dnsConfig:options:- name: ndotsvalue: "2" # The ndots:5 option in the DNS configuration file generated based on the ClusterFirst policy is changed to ndots:2.imagePullSecrets:- name: default-secret
Container's DNS configuration file:
nameserver 10.247.3.10search default.svc.cluster.local svc.cluster.local cluster.localoptions ndots:2 single-request-reopen timeout:2
Example 3: Using Multiple DNSs in Serial Sequence
apiVersion: v1kind: Podmetadata:namespace: defaultname: dns-examplespec:containers:- name: testimage: nginx:alpinednsPolicy: ClusterFirst # Added DNS configuration. The cluster connects to CoreDNS by default.dnsConfig:nameservers:- 10.2.3.4 # IP address of your on-premises DNSimagePullSecrets:- name: default-secret
A maximum of three DNS addresses can be configured for a nameserver in the container DNS configuration file.
Container's DNS configuration file:
nameserver 10.247.3.10nameserver 10.2.3.4search default.svc.cluster.local svc.cluster.local cluster.localoptions timeout:2 single-request-reopen ndots:5