Install a per-node DNS cache to reduce query latency and improve resolution reliability.
How it works
NodeLocal DNSCache consists of two components:
DaemonSet (DNS caching agent): Runs on each node, creates a virtual network interface, and listens for DNS queries on
169.254.20.10by default. To change the listen IP address, submit a ticket.Deployment (admission controller): Intercepts pod creation requests via admission webhooks and automatically injects dnsConfig into pod specs.
Built on CoreDNS, the caching agent provides proxy and caching only. Do not enable plugins such as hosts or rewrite on it — configure them in CoreDNS.
DNS query flow after NodeLocal DNSCache is deployed:
DNS query flow after NodeLocal DNSCache is deployed:
No. | Description |
① | By default, a pod with the local dnsConfig injected uses NodeLocal DNSCache, which listens for DNS queries sent to 169.254.20.10 on the node. |
② | If NodeLocal DNSCache does not find a cache hit, it uses the kube-dns Service to forward the query to CoreDNS. |
③ | CoreDNS uses the DNS server deployed in the virtual private cloud (VPC) to resolve domain names that are not cluster-local. |
④ | If the pod with the local dnsConfig injected fails to connect to NodeLocal DNSCache, the pod uses the kube-dns Service to connect to CoreDNS for DNS resolution. |
⑤ | A pod without the local dnsConfig injected uses the kube-dns Service to connect to CoreDNS for DNS resolution. |
Prerequisites
Before you begin, ensure that you have:
An ACK cluster is created.
kubectl is connected to the cluster.
Limitations
Windows nodes are not supported. For pods on virtual nodes (including ECI and ACS pods), DNS caching is supported only when NodeLocal DNSCache v1.6.0 or later and ack-virtual-node v2.14.0 or later are installed.
If the cluster uses Terway, version 1.0.10.301 or later is required. If Terway runs in inclusive ENI mode with IPvlan, configure Terway for IPvlan mode first.
NodeLocal DNSCache acts only as a transparent caching proxy for CoreDNS and does not expose plugin extensibility. Configure plugins such as
hostsorrewritein CoreDNS instead.Configure the CoreDNS forward plugin's default protocol before using NodeLocal DNSCache, or CoreDNS may fail to resolve external domains. See Best practices for DNS services.
Not installed on master nodes by default. If pods run on tainted master nodes, add matching tolerations to the
node-local-dnsDaemonSet in thekube-systemnamespace.
Install NodeLocal DNSCache
Log on to the ACK console. In the left-side navigation pane, click ACK consoleClusters.
Find your cluster and choose More > Operations > Manage Components in the Actions column.
On the Add-ons page, click the Networking tab and find ACK NodeLocal DNSCache.
Click Install. In the dialog box, click OK.
Configure NodeLocal DNSCache
To route DNS queries from pods through NodeLocal DNSCache, set nameservers in pod dnsConfig to 169.254.20.10 and the cluster IP address of kube-dns. Use one of the following methods:
Method | Recommendation | Description |
Recommended | The admission controller injects dnsConfig at pod creation time — no manual YAML edits required. | |
Neutral | Specify dnsConfig directly in pod YAML. | |
Not recommended | Modifies kubelet and requires a restart, which may interrupt workloads. |
Method 1: Automatic dnsConfig injection
The admission controller injects dnsConfig into pods in namespaces labeled node-local-dns-injection=enabled. Label a namespace to enable injection:
kubectl label namespace default node-local-dns-injection=enabledThis enables injection for thedefaultnamespace only. Replacedefaultwith your target namespace as needed.
When enabled, the following dnsConfig is added to new pods. The kube-dns cluster IP is included as a fallback for high availability.
dnsConfig:
nameservers:
- 169.254.20.10
- 172.21.0.10
options:
- name: ndots
value: "3"
- name: attempts
value: "2"
- name: timeout
value: "1"
searches:
- default.svc.cluster.local
- svc.cluster.local
- cluster.local
dnsPolicy: NoneInjection conditions
Injection applies only when all conditions below are met:
The pod is not in the
kube-systemorkube-publicnamespace.The pod's namespace has the
node-local-dns-injection=enabledlabel.The pod's namespace does not have ECI-related labels (
virtual-node-affinity-injection,eci, oralibabacloud.com/eci).The pod does not have
eci,alibabacloud.com/eci, ornode-local-dns-injection=disabledlabels.The pod uses
hostNetworkwith theClusterFirstWithHostNetDNS policy, or does not usehostNetworkand uses theClusterFirstDNS policy.
If injection fails, verify all conditions above.
Opt out of injection for specific pods
To exclude specific pods from injection, add node-local-dns-injection=disabled to the pod template labels:
metadata:
labels:
node-local-dns-injection: "disabled"On NodeLocal DNSCache versions earlier than v1.6.0 or ack-virtual-node versions earlier than v2.14.0, ECI pods cannot use NodeLocal DNSCache, which causes DNS failures. In that case, disable injection for the Deployment by adding node-local-dns-injection=disabled to pod template labels.
Method 2: Manual dnsConfig
Specify dnsConfig directly in the pod spec:
apiVersion: v1
kind: Pod
metadata:
name: alpine
namespace: default
spec:
containers:
- image: alpine
command:
- sleep
- "10000"
imagePullPolicy: Always
name: alpine
dnsPolicy: None
dnsConfig:
nameservers: ["169.254.20.10","172.21.0.10"]
searches:
- default.svc.cluster.local
- svc.cluster.local
- cluster.local
options:
- name: ndots
value: "3"
- name: attempts
value: "2"
- name: timeout
value: "1"Key fields:
Field | Value | Notes |
|
| Required when specifying custom dnsConfig. |
|
| The first entry routes to NodeLocal DNSCache; the second is the kube-dns fallback. |
| Cluster DNS search domains | Ensures internal service names resolve correctly. |
|
| A lower value reduces search-domain lookups before trying the name as-is. Default is |
Method 3: kubelet startup parameters
In /etc/systemd/system/kubelet.service.d/10-kubeadm.conf, add --cluster-dns with the NodeLocal DNSCache IP and the kube-dns IP:
--cluster-dns=169.254.20.10 --cluster-dns=<kube-dns-ip> --cluster-domain=<search-domain>Parameter | Description |
| DNS servers written into pod dnsConfig. Specify |
| DNS search domain written into pod dnsConfig. In most clusters, this is |
After editing the file, apply the changes:
sudo systemctl daemon-reload
sudo systemctl restart kubeletRestarting kubelet may briefly interrupt running workloads.
Example: Configure NodeLocal DNSCache for a Deployment
Enable NodeLocal DNSCache for a Deployment in the default namespace with Method 1 (automatic injection).
Label the namespace to enable automatic dnsConfig injection.
ImportantThe admission controller skips pods in the
kube-systemandkube-publicnamespaces. Do not enable injection for those namespaces.kubectl label namespace default node-local-dns-injection=enabledDeploy a sample application. Save this YAML as
ubuntu-deployment.yaml:apiVersion: apps/v1 kind: Deployment metadata: name: ubuntu labels: app: ubuntu spec: replicas: 2 selector: matchLabels: app: ubuntu template: metadata: labels: app: ubuntu spec: containers: - name: ubuntu image: ubuntu command: ["sh", "-c"] args: ["sleep 100000"]Apply the manifest:
kubectl apply -f ubuntu-deployment.yamlExpected output:
deployment.apps/ubuntu createdVerify the Deployment is running.
kubectl get deployment ubuntuExpected output:
NAME READY UP-TO-DATE AVAILABLE AGE ubuntu 2/2 2 2 7sVerify dnsConfig injection. Get a pod name:
kubectl get podsExpected output:
NAME READY STATUS RESTARTS AGE ubuntu-766448f68c-m**** 1/1 Running 0 4m39s ubuntu-766448f68c-w**** 1/1 Running 0 4m39sCheck a pod's dnsConfig:
kubectl get pod ubuntu-766448f68c-m**** -o=jsonpath='{.spec.dnsConfig}'Expected output:
map[nameservers:[169.254.20.10 172.21.0.10] options:[map[name:ndots value:5]] searches:[default.svc.cluster.local svc.cluster.local cluster.local]]169.254.20.10innameserversconfirms dnsConfig injection.
Update NodeLocal DNSCache
Log on to the ACK console. In the left-side navigation pane, click Clusters.
Click your cluster name. In the left-side navigation pane, choose Operations > Add-ons.
On the Add-ons page, find NodeLocal DNSCache and click Upgrade. In the dialog box, click OK.
Custom tolerations on the node-local-dns DaemonSet are overwritten during upgrade. Reconfigure them afterward. If the upgrade fails, see Component troubleshooting.Uninstall NodeLocal DNSCache
Log on to the ACK console. In the left-side navigation pane, click Clusters.
Click your cluster name. In the left-side navigation pane, choose Operations > Add-ons.
On the Add-ons page, find NodeLocal DNSCache and click Uninstall. In the dialog box, click OK.
After uninstalling, all DNS queries go directly to CoreDNS. Scale out CoreDNS before uninstalling to handle the increased load.
Configure Terway for IPvlan mode
In clusters with early Terway versions, the default configuration may not route DNS traffic to 169.254.20.10 correctly. Update the configuration before installing NodeLocal DNSCache.
Open the Terway ConfigMap for editing:
kubectl -n kube-system edit cm eni-config -o yamlCheck the ConfigMap:
If
eniip_virtual_typeis notIPVlan, no changes are needed. Proceed to Install NodeLocal DNSCache.If
host_stack_cidrsis already present, no changes are needed. Proceed to Install NodeLocal DNSCache.
If
eniip_virtual_typeisIPVlanandhost_stack_cidrsis absent, addhost_stack_cidrsand set it to169.254.20.10/32. Save and exit.10-terway.conf: | { "cniVersion": "0.3.0", "name": "terway", "eniip_virtual_type": "IPVlan", "host_stack_cidrs": ["169.254.20.10/32"], "type": "terway" }List the Terway DaemonSet pods:
kubectl -n kube-system get pod | grep terway-eniipExpected output:
terway-eniip-7**** 2/2 Running 0 30m terway-eniip-s**** 2/2 Running 0 30mDelete the pods to apply the updated configuration:
kubectl -n kube-system delete pod terway-eniip-7**** terway-eniip-s****Log on to a cluster node and verify the update:
cat /etc/cni/net.d/*Expected output:
{ "cniVersion": "0.3.0", "name": "terway-chainer", "plugins": [ { "eniip_virtual_type": "IPVlan", "host_stack_cidrs": [ "169.254.20.10/32" ], "type": "terway" }, { "type": "cilium-cni" } ] }After all Terway pods are running, proceed to Install NodeLocal DNSCache.