Installing NodeLocalDNS in IPVS Mode
Background
TKE has productized support for NodeLocalDNS, can be installed into cluster with one click in extension components, refer to NodeLocalDNSCache Extension Component Description. But one scenario is unsupported: cluster network is GlobalRouter and kube-proxy forwarding mode is IPVS.
This article introduces how to install NodeLocalDNS for TKE clusters with GlobalRouter + IPVS.
Prerequisites
- Cluster network mode is GlobalRouter.
- kube-proxy mode is IPVS.
- Configured TKE cluster kubeconfig, can operate TKE cluster with kubectl.
- Installed helm and kustomize.
Installation Method
git clone --depth 1 https://github.com/tke-apps/nodelocaldns.git
cd nodelocaldns
make
Principle:
- Automatically fetches latest kubernetes nodelocaldns plugin yaml template and current cluster
kube-dns'sClusterIP, fills template to generate finalnodelocaldns.yamlin current directory. - Automatically deploys generated
nodelocaldns.yamlto current cluster.
If using GitOps deployment, only execute
make yamlto generatenodelocaldns.yaml, then put this yaml file into GitOps repository.
Modifying Kubelet Parameters
For DNS cache component to take effect, need to configure kubelet parameter on nodes: --cluster-dns=169.254.20.10.
IPVS mode clusters need to bind corresponding Cluster IP for all Services on
kube-ipvs0dummy interface for IPVS forwarding, so localdns cannot listen on cluster DNS's Cluster IP. Kubelet's--cluster-dnsdefaults to cluster DNS's Cluster IP instead of localdns listening address. After installing localdns, cluster Pods still use cluster DNS resolution by default, so we need to modify kubelet's--cluster-dnsparameter.
Modify and restart kubelet via script:
sed -i 's/CLUSTER_DNS.*/CLUSTER_DNS="--cluster-dns=169.254.20.10"/' /etc/kubernetes/kubelet
systemctl restart kubelet
Manual configuration for each node is impractical. Below introduces automated configuration methods.
Configuring Incremental Nodes
Specify 【Custom Script】 in new nodes or node pools for node initialization, enabling automatic kubelet parameter configuration after node initialization:

Existing node pools can also specify custom scripts by modifying node pool configuration.
Modifying Existing Nodes
Use ansible for batch modification. Ansible installation refer to Official Documentation: Installing Ansible.
After installing ansible, follow these steps:
-
Export all node IPs to
hosts.ini:kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="InternalIP")].address}' | tr ' ' '\n' | grep -vE '^169\.254\.*' > hosts.ini -
Prepare script
modify-kubelet.sh:sed -i 's/CLUSTER_DNS.*/CLUSTER_DNS="--cluster-dns=169.254.20.10"/' /etc/kubernetes/kubelet
systemctl restart kubelet -
Prepare ssh key or password for node login (rename key to key, execute
chmod 0600 key) -
Use ansible to run script
modify-kubelet.shon all nodes:- Example using key:
ansible all -i hosts.ini --ssh-common-args="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" --user root --private-key=key -m script -a "modify-kubelet.sh" - Example using password:
ansible all -i hosts.ini --ssh-common-args="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" -m script --extra-vars "ansible_user=root ansible_password=yourpassword" -a "modify-kubelet.sh"
Note: If nodes use ubuntu system, default user is ubuntu, can replace accordingly. Also add
--become --become-user=rootto ansible parameters for root privileges during script execution, avoiding operation failures. - Example using key:
Regarding Existing Pods
Running existing Pods in cluster still use old cluster DNS. After recreation, they automatically switch to localdns. Newly created Pods also default to localdns.
Generally, if no special need, existing Pods can be ignored - they'll automatically switch to localdns after next update when Pods recreate. For immediate switching, trigger Pod recreation via workload rolling updates for manual switching.
Regarding NodeLocalDNS Version
Installation method uses open-source project employing NodeLocalDNS addon YAML from Kubernetes Official YAML automatically replaced generation, keeping latest version real-time.
Official dependency image
registry.k8s.io/dns/k8s-dns-node-cachecannot be pulled domestically, replaced with DockerHub mirror image k8smirror/k8s-dns-node-cache, periodically auto-syncing latest tags, safe to use.