- Home
- Configuration
- NodeLocalDNS
NodeLocalDNS#
NodeLocalDNS runs a local DNS caching agent on each node in the MKE cluster, improving performance by caching DNS responses locally and reducing latency compared to resolving external DNS records through a centralized CoreDNS service.
NodeLocalDNS is supported on both the iptables dataplane and the Calico eBPF dataplane. The configuration is the same for both, though the way DNS queries reach the local cache differs, as do the operational characteristics. Refer to NodeLocalDNS on the Calico eBPF dataplane for more information.
NodeLocalDNS network requirements#
NodeLocalDNS requires the Calico CNI provider. The supported combinations of CNI provider and kube-proxy configuration are detiled below:
| CNI provider | kube-proxy | Supported |
|---|---|---|
| Calico, iptables dataplane | Enabled, iptables mode |
Yes |
| Calico, eBPF dataplane | Disabled, or enabled in iptables mode |
Yes |
| Calico, iptables dataplane | Disabled | No |
| Calico, any dataplane | Enabled, ipvs, nftables, or userspace mode |
No |
| Any provider other than Calico | Any | No |
Configurations that are not supported are rejected by mkectl and by the MKE
admission webhooks, with one of the following messages:
NodeLocalDNS is only supported when CNI provider is CalicoNodeLocalDNS requires kube-proxy to be enabled, unless Calico runs the eBPF dataplane (linuxDataplane: BPF)NodeLocalDNS is only supported when kube-proxy runs in the Iptables mode
In addition, MKE rejects the configuration if an instance of NodeLocalDNS that MKE does not manage is already present in the cluster.
Note
Support for NodeLocalDNS with the Calico eBPF dataplane is available in MKE 4.2.1 and later, and only for parent and standalone clusters. The Calico eBPF dataplane is not supported on child clusters.
NodeLocalDNS Configuration#
NodeLocalDNS is configured through the spec.nodeLocalDNS section of the mke4.yaml
configuration file. The function is disabled by default, and thus to enable
NodeLocalDNS, you must set the spec.nodeLocalDNS.enabled parameter to true.
NodeLocalDNS example configuration:
nodeLocalDNS:
enabled: false
nodeLocalConfigPersist: false
resources:
requests: {}
| Parameter | Description | Default | Equivalent MKE 3 parameter |
|---|---|---|---|
enabled |
Enables the NodeLocalDNS service in the cluster. Valid values: true, false |
false |
[cluster_config.node_local_dns] |
nodeLocalConfigPersist |
Retains the NodeLocalDNS configmap. | false |
[cluster_config.node_local_dns_config_persist] |
resources.requests.cpu |
Specifies the minimum CPU to guarantee for the NodeLocalDNS container. | 25m |
N/A |
resources.requests.memory |
Specifies the minimum memory to guarantee for the NodeLocalDNS container. | 5Mi |
N/A |
The address that the local cache serves is the kube-dns ClusterIP, which MKE
derives from the cluster service CIDR set in spec.network.serviceCIDR. On a
cluster that uses the default service CIDR, 10.96.0.0/12, the derived address
is 10.96.0.10. There is no configuration parameter for this address.
To configure NodeLocalDNS:
-
Obtain the default
mke4.yamlconfiguration file:mkectl init -
In the
mke4.yamlconfiguration file, add thenodeLocalDNSsection underspecand set theenabledparameter totrue, as nodelocalDNS is disabled by default. -
Apply the configuration:
mkectl apply -f mke4.yaml -
Verify the successful deployment of NodeLocalDNS in the cluster:
kubectl get all,configmap -n kube-system | grep nodeExample output:
pod/node-local-dns-7z5k9 1/1 Running 0 4m23s pod/node-local-dns-8wgzc 1/1 Running 0 4m23s pod/node-local-dns-xnr7q 1/1 Running 0 4m23s service/node-local-dns ClusterIP None <none> 9253/TCP 4m24s daemonset.apps/node-local-dns 3 3 3 3 3 kubernetes.io/os=linux 4m24s configmap/node-local-dns 1 4m47s
NodeLocalDNS on the Calico eBPF dataplane#
On the iptables dataplane, kube-proxy programs the rules that send pod DNS queries for the kube-dns ClusterIP to the local cache on the node. The Calico eBPF dataplane has no kube-proxy, and connect-time load balancing resolves the kube-dns ClusterIP at the socket layer, so the queries never reach the local cache.
To make interception work, the kube-dns ClusterIP must be excluded from eBPF
NAT, through the Calico Felix bpfExcludeCIDRsFromNAT setting. MKE manages
this exclusion for you, adding the address when NodeLocalDNS is enabled and
removing it when NodeLocalDNS is disabled. For background information, refer to the Tigera
article, Optimizing Kubernetes DNS with NodeLocal DNSCache and Calico
eBPF.
Warning
Do not manually add or remove the kube-dns ClusterIP in
bpfExcludeCIDRsFromNAT. MKE sequences this exclusion against the
node-local-dns DaemonSet. If the exclusion is in place while the local
cache is not serving, DNS queries to the kube-dns ClusterIP have no
destination and cluster DNS fails.
Enable NodeLocalDNS on an eBPF cluster#
You enable NodeLocalDNS the same way as on any other cluster, as described in
NodeLocalDNS Configuration. Set spec.nodeLocalDNS.enabled to true in
the mke4.yaml configuration file and run the mkectl apply command. No Calico or Felix
configuration is required, and you do not need to change the values.yaml file
that you provide for Calico.
spec:
network:
kubeProxy:
disabled: true
providers:
- provider: calico
enabled: true
extraConfig:
"values.yaml": |
installation:
calicoNetwork:
linuxDataplane: BPF
defaultFelixConfiguration:
enabled: true
nodeLocalDNS:
enabled: true
Info
The spec.network.kubeProxy.disabled parameter can be left at its default or
set to true. Both are accepted on an eBPF cluster.
During mkectl apply, two phases manage the eBPF NAT exclusion:
-
Apply NodeLocalDNS BPF DNS exclusion
Runs when you enable NodeLocalDNS. Waits until the
node-local-dnsDaemonSet is Ready on every Linux node, then adds the kube-dns ClusterIP tobpfExcludeCIDRsFromNAT. -
Remove NodeLocalDNS BPF DNS exclusion
Runs when you disable NodeLocalDNS. Removes the kube-dns ClusterIP from bpfExcludeCIDRsFromNAT before MKE 4 removes the node-local-dns DaemonSet.
Because of this sequencing, you can enable or disable NodeLocalDNS in a single
mkectl apply run.
Verify the eBPF NAT exclusion#
A Ready node-local-dns DaemonSet does not on its own confirm that the local
cache is serving DNS on an eBPF cluster. Verify that MKE has excluded the
kube-dns ClusterIP from eBPF NAT:
kubectl get felixconfiguration default -o jsonpath='{.spec.bpfExcludeCIDRsFromNAT}'
The output must contain the ClusterIP of the kube-dns Service as a /32, for
example ["10.96.0.10/32"].
Operational considerations#
Review the following behavior before you enable NodeLocalDNS on an eBPF cluster:
-
There is no fallback to CoreDNS.
On the iptables dataplane, kube-proxy provides a path to CoreDNS if the local cache stops serving. On the eBPF dataplane there is no such path. If the
node-local-dnspod on a node stops serving, DNS resolution fails for all pods on that node until the pod recovers, typically within two minutes for a routine pod replacement. A pod that cannot recover leaves DNS unavailable on that node indefinitely. Pods on all other nodes are unaffected. -
Enabling NodeLocalDNS briefly interrupts DNS on each node.
DNS resolution can be unavailable on a node for up to approximately 45 seconds while the node cache pod starts. The switchover to the local cache that follows is not disruptive, and disabling NodeLocalDNS does not interrupt DNS resolution.
-
Changing
spec.nodeLocalDNS.enabledcannot be combined with an upgrade.On an eBPF cluster, changing the parameter in the same operation that changes the MKE version is rejected, because the upgrade flow does not perform the sequencing described above. Complete the upgrade first, then change the parameter in a separate
mkectl apply. -
Your own eBPF NAT exclusions are preserved.
Values that you set through
defaultFelixConfiguration.bpfExcludeCIDRsFromNATin the Calicovalues.yamlfile are combined with the kube-dns ClusterIP that MKE manages, rather than replacing it. Do not include the kube-dns ClusterIP among them, as MKE adds and removes that address on its own schedule.