Configure NodeLocal DNS Cache in a Managed Kubernetes cluster
To reduce the load on DNS in a Managed Kubernetes cluster and speed up response times from external and internal resources, you can use NodeLocal DNS Cache.
NodeLocal DNS Cache is a DNS query caching mechanism that runs on all Managed Kubernetes nodes and provides a local cache for the DNS resolver. When user pods send requests, they first pass through the local DNS cache. If these requests match previously saved records, additional requests to an external DNS server are avoided. This allows for reduced DNS request processing time and saves network traffic in the cluster.
Read more about NodeLocal DNS Cache in the Kubernetes documentation.
Configure NodeLocal DNS Cache
-
Create a
nodelocaldns.yamlyaml file with the manifest:nodelocaldns.yaml file
apiVersion: v1kind: ServiceAccountmetadata:name: node-local-dnsnamespace: kube-systemlabels:kubernetes.io/cluster-service: "true"addonmanager.kubernetes.io/mode: Reconcile---apiVersion: v1kind: Servicemetadata:name: kube-dns-upstreamnamespace: kube-systemlabels:k8s-app: kube-dnskubernetes.io/cluster-service: "true"addonmanager.kubernetes.io/mode: Reconcilekubernetes.io/name: "KubeDNSUpstream"spec:ports:- name: dnsport: 53protocol: UDPtargetPort: 53- name: dns-tcpport: 53protocol: TCPtargetPort: 53selector:k8s-app: kube-dns---apiVersion: v1kind: ConfigMapmetadata:name: node-local-dnsnamespace: kube-systemlabels:addonmanager.kubernetes.io/mode: Reconciledata:Corefile: |cluster.local:53 {errorscache {success 9984 30denial 9984 5}reloadloopbind 169.254.20.25 10.96.0.10forward . __PILLAR__CLUSTER__DNS__ {force_tcp}prometheus :9253health 169.254.20.25:8080}in-addr.arpa:53 {errorscache 30reloadloopbind 169.254.20.25 10.96.0.10forward . __PILLAR__CLUSTER__DNS__ {force_tcp}prometheus :9253}ip6.arpa:53 {errorscache 30reloadloopbind 169.254.20.25 10.96.0.10forward . __PILLAR__CLUSTER__DNS__ {force_tcp}prometheus :9253}.:53 {errorscache 30reloadloopbind 169.254.20.25 10.96.0.10forward . __PILLAR__UPSTREAM__SERVERS__prometheus :9253}---apiVersion: apps/v1kind: DaemonSetmetadata:name: node-local-dnsnamespace: kube-systemlabels:k8s-app: kube-dnskubernetes.io/cluster-service: "true"addonmanager.kubernetes.io/mode: Reconcilespec:updateStrategy:rollingUpdate:maxUnavailable: 10%selector:matchLabels:k8s-app: kube-dnstemplate:metadata:labels:k8s-app: kube-dnsannotations:prometheus.io/port: "9253"prometheus.io/scrape: "true"spec:priorityClassName: system-node-criticalserviceAccountName: node-local-dnshostNetwork: truednsPolicy: Default # Do not use cluster DNS.tolerations:- key: "CriticalAddonsOnly"operator: "Exists"- effect: "NoExecute"operator: "Exists"- effect: "NoSchedule"operator: "Exists"containers:- name: node-cacheimage: registry.k8s.io/dns/k8s-dns-node-cache:1.22.20resources:requests:cpu: 25mmemory: 5Miargs: [ "-localip", "169.254.20.25,10.96.0.10", "-conf", "/etc/Corefile", "-upstreamsvc", "kube-dns-upstream" ]securityContext:capabilities:add:- NET_ADMINports:- containerPort: 53name: dnsprotocol: UDP- containerPort: 53name: dns-tcpprotocol: TCP- containerPort: 9253name: metricsprotocol: TCPlivenessProbe:httpGet:host: 169.254.20.25path: /healthport: 8080initialDelaySeconds: 60timeoutSeconds: 5volumeMounts:- mountPath: /run/xtables.lockname: xtables-lockreadOnly: false- name: config-volumemountPath: /etc/coredns- name: kube-dns-configmountPath: /etc/kube-dnsvolumes:- name: xtables-lockhostPath:path: /run/xtables.locktype: FileOrCreate- name: kube-dns-configconfigMap:name: kube-dnsoptional: true- name: config-volumeconfigMap:name: node-local-dnsitems:- key: Corefilepath: Corefile.base -
Apply the manifest:
kubectl create -f nodelocaldns.yamlThe list of created objects will appear in the response:
serviceaccount/node-local-dns createdservice/kube-dns-upstream createdconfigmap/node-local-dns createddaemonset.apps/node-local-dns created
Check the operation of NodeLocal DNS Cache
-
enable logging mode for NodeLocal DNS pods. In the
nodelocaldns.yamlmanifest, add theConfigMapobject linelog:data:Corefile: |cluster.local:53 {logerrorscache {success 9984 30denial 9984 5} -
Apply the manifest:
kubectl apply -f nodelocaldns.yaml -
Start a pod with DNS testing utilities:
kubectl apply -f https://k8s.io/examples/admin/dns/dnsutils.yamlThe response will show confirmation that the pod has been created:
pod/dnsutils created -
ensure the pod is in the
Runningstatus:kubectl get pods dnsutils -
Connect to the pod:
kubectl exec -i -t dnsutils -- bash -
Execute a test domain request to the DNS server:
dig @169.254.20.25 servercore.comThe response will show that the request was successfully executed:
;; ANSWER SECTION:servercore.com. 30 IN A 85.119.149.3;; Query time: 437 msec;; SERVER: 169.254.20.25#53(169.254.20.25);; WHEN: Wed Sep 20 15:43:46 UTC 2023;; MSG SIZE rcvd: 67 -
Check the logs:
kubectl logs --namespace=kube-system -l k8s-app=kube-dns -fin the response, A and AAAA DNS records with the
NOERRORcode:[INFO] 10.10.71.3:45929 - 55864 "A IN ru-2.cloud.api.selcloud.ru.kube-system.svc.cluster.local. udp 85 false 1232" NOERROR qr,aa,rd,ra 212 3.975488442s[INFO] 10.10.71.3:36099 - 21119 "AAAA IN ru-2.cloud.api.selcloud.ru.kube-system.svc.cluster.local. udp 85 false 1232" NOERROR qr,aa,rd 74 3.976010334s