---
# System prepended metadata

title: RKE2 啟用 NodeLocal DNSCache
tags: [K8S]

---

# RKE2 啟用 NodeLocal DNSCache


* NodeLocal DNSCache 是 Kubernetes 叢集的插件，透過在叢集中每個節點本地快取 DNS 記錄來提高 DNS 解析的效能和穩定性。這減少了 kube-dns pod （Kubernetes 叢集中的主要 DNS 伺服器）的負載，並且還可以改善 DNS 查詢的延遲。

![image](https://hackmd.io/_uploads/SybzQTh_A.png)
運作原理
1. NodeLocal DNSCache 以 DaemonSet 部署，這表示 NodeLocal DNSCache 的 pod 運行在叢集中的每個節點上。
2. 每個 NodeLocal DNSCache Pod 都會在本機快取 DNS 記錄。當 Pod 進行 DNS 查詢時，相同節點上的 NodeLocal DNSCache Pod 會先檢查其本機快取中的記錄。
3. 如果在本機快取中找不到該記錄，NodeLocal DNSCache pod 將查詢上游 DNS 伺服器（通常是 kube-dns pod）以取得該記錄。
4. 從上游 DNS 伺服器取得記錄後，NodeLocal DNSCache pod 會將其新增至本機快取以供日後查詢。


## rke2 部屬

```
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
  name: rke2-coredns
  namespace: kube-system
spec:
  valuesContent: |-
    nodelocal:
      enabled: true
```
* node-local-dns 會以 ds 方式部屬
```
$ kubectl -n kube-system get po -l k8s-app=node-local-dns
NAME                   READY   STATUS    RESTARTS   AGE
node-local-dns-28lwz   1/1     Running   0          26m
node-local-dns-6x74v   1/1     Running   0          26m
node-local-dns-7thb4   1/1     Running   0          26m
```
* 設定好後每個節點都會多一張網卡
```
$ ip a s nodelocaldns
26: nodelocaldns: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default
    link/ether ba:70:f7:50:36:3f brd ff:ff:ff:ff:ff:ff
    inet 169.254.20.10/32 scope global nodelocaldns
       valid_lft forever preferred_lft forever
    inet 10.43.0.10/32 scope global nodelocaldns
       valid_lft forever preferred_lft forever
```
* 編輯 `kube-system` 的 `node-local-dns` configmap 新增 log 可以看到 pod 查詢紀錄
```
    .:53 {
        log
        errors
        cache 30
```

## cilium cni 啟用 NodeLocal DNSCache
1. 叢集管理頁面編輯 yaml 修改如下配置，要 disable kube-proxy
```
  rkeConfig:
    chartValues:
      rke2-cilium:
        k8sServiceHost: 127.0.0.1
        k8sServicePort: 6443
        kubeProxyReplacement: true
        localRedirectPolicy: true
......
    machineGlobalConfig:
      cni: cilium
      disable-kube-proxy: true
      etcd-expose-metrics: false
```
![image](https://hackmd.io/_uploads/r1wq3GJf1e.png)

2. coredns 啟用 nodelocal
```
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
  name: rke2-coredns
  namespace: kube-system
spec:
  valuesContent: |-
    nodelocal:
      enabled: true
      use_cilium_lrp: true
```
> 注意 coredns 1.29.002 版本以前都沒有 `use_cilium_lrp` 參數
> https://github.com/rancher/rke2-charts/blob/main/charts/rke2-coredns/rke2-coredns/1.29.002/values.yaml
3. 檢查 `ciliumlocalredirectpolicies` crd
```
$ kubectl rollout restart deploy cilium-operator -n kube-system

$ kubectl rollout restart ds cilium -n kube-system

$ kubectl get crd ciliumlocalredirectpolicies.cilium.io
NAME                                    CREATED AT
ciliumlocalredirectpolicies.cilium.io   2024-11-11T04:57:54Z
```

4. 創建的 lrp-nodelocal，這會讓原本到 `rke2-coredns-rke2-coredns`  service 的流量重新指向到 `k8s-app: node-local-dns` label 的 pod。

```
$ kubectl -n kube-system get CiliumLocalRedirectPolicy
NAME            AGE
lrp-nodelocal   7m35s

$ kubectl -n kube-system get po -l k8s-app=node-local-dns -owide
NAME                   READY   STATUS    RESTARTS   AGE     IP            NODE    NOMINATED NODE   READINESS GATES
node-local-dns-hrktk   1/1     Running   0          9m22s   10.42.0.243   demo1   <none>           <none>
node-local-dns-qtmnj   1/1     Running   0          9m22s   10.42.1.172   demo2   <none>           <none>
```

* 確認有 LocalRedirect 
```
$ kubectl exec -it -n kube-system cilium-7bjc7 -- cilium-dbg service list | grep 10.43.0.10
Defaulted container "cilium-agent" out of: cilium-agent, install-portmap-cni-plugin (init), config (init), mount-cgroup (init), apply-sysctl-overwrites (init), mount-bpf-fs (init), clean-cilium-state (init), install-cni-binaries (init)
4    10.43.0.10:53        LocalRedirect   1 => 10.42.0.243:53 (active)
```

5. 驗證
* 編輯 `kube-system` 的 `node-local-dns` configmap 新增 log 可以看到 pod 查詢紀錄
```
    .:53 {
        log
        errors
        cache 30
```
![image](https://hackmd.io/_uploads/S1xDq8MJzJl.png)

* 創建 pod 並測試名稱解析
```
$ kubectl exec test-7895cc554-45z4k -- curl www.google.com
```
* 在跟 test pod 相同節點確認 `node-local-dns` log 有負責名稱解析

![image](https://hackmd.io/_uploads/BJ4PQQyzke.png)

## 參考
https://www.suse.com/support/kb/doc/?id=000020174

