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.
The setup and verification process for NodeLocal DNS Cache depends on the CNI (Container Network Interface) plugin used in the cluster: Calico or Cilium. You can check the CNI plugin in the cluster in the control panel: in the top menu, click Products → Managed Kubernetes → cluster page → Settings tab → CNI.
1. Configure NodeLocal DNS Cache
Calico CNI
Cilium CNI
-
Create a
nodelocaldns.yamlYAML file with the manifest:Файл nodelocaldns.yaml
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 apply -f nodelocaldns.yamlThe response will show a list of the created objects:
serviceaccount/node-local-dns createdservice/kube-dns-upstream createdconfigmap/node-local-dns createddaemonset.apps/node-local-dns created
2. Verify NodeLocal DNS Cache operation
Calico CNI
Cilium CNI
-
Enable logging for NodeLocal DNS pods. To do this, in the
nodelocaldns.yamlmanifest, add theConfigMapobject, add thelog:data:Corefile: |cluster.local:53 {logerrorscache {success 9984 30denial 9984 5} -
Apply the manifest:
kubectl apply -f nodelocaldns.yaml -
Run a pod with DNS troubleshooting utilities:
kubectl apply -f https://k8s.io/examples/admin/dns/dnsutils.yamlThe response will confirm that the pod has been created:
pod/dnsutils created -
Make sure the pod status is
Running:kubectl get pods dnsutils -
Connect to the pod:
kubectl exec -i -t dnsutils -- bash -
Run a test query to the DNS server:
dig @169.254.20.25 servercore.comThe response will show that the query was successful:
;; 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 -fThe response will show A and AAAA DNS records with the code
NOERROR:[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