配置 NodeLocal DNSCache

概览

NodeLocal DNSCache 是一个集群插件,通过在集群节点上运行 DNS 缓存代理来提升集群 DNS 性能。该插件会在每个节点本地缓存 DNS 响应,从而降低 DNS 查询延迟并提升集群稳定性,同时减轻中心 DNS 服务的负载。

主要特性

  • 本地 DNS 缓存:在每个节点本地缓存 DNS 响应,以降低查询延迟
  • 性能提升:显著缩短应用程序的 DNS 查询时间

重要说明

WARNING

部署注意事项:

  1. Kube-OVN Underlay 模式:该插件不支持在 Kube-OVN Underlay 模式下部署。如果部署,可能会导致 DNS 查询失败。

  2. kubelet 重启:部署此插件会导致 kubelet 重启。

  3. 需要重启 Pod:插件成功部署后,不会影响正在运行的 Pods,仅对新创建的 Pods 生效。当 CNI 为 Kube-OVN 时,需要手动向 kube-ovn-controller 添加参数 --node-local-dns-ip=(本地 DNS 缓存服务器的 IP 地址)。

  4. NetworkPolicy 配置:如果集群中配置了 NetworkPolicy,需要在 networkPolicy 中额外放通 node CIDR 和 nodeLocalDNSIP 的入方向与出方向,以确保正常通信。

  5. 通过重建进行集群升级:如果集群通过重建节点(re-provisioning)进行升级,kubelet 配置更改将会丢失。为了使 NodeLocal DNS 配置在升级后保持持久化,需要在集群模板的以下三个位置的 kubeletExtraArgs 中添加 --cluster-dns 参数:

    • KubeadmControlPlane → initConfiguration → nodeRegistration → kubeletExtraArgs
    • KubeadmControlPlane → joinConfiguration → nodeRegistration → kubeletExtraArgs
    • KubeadmConfigTemplate → template → spec → joinConfiguration → nodeRegistration → kubeletExtraArgs

    在上述每个 kubeletExtraArgs 部分中添加以下参数:

    cluster-dns: "<NodeLocal_DNS_IP>"  # e.g., 169.254.20.10
WARNING

4.2.x 升级说明

当将该插件从 4.2.0 以下版本(不包括 4.2.0 本身)升级到 4.2.x 时,由于 ResourcePatch 兼容性问题,需要执行以下步骤:

升级前:

  • 记录 kube-ovn-controller ResourcePatch 配置中的 --node-local-dns-ip 参数值
  • 删除 deploy/kube-ovn-controller 资源的 ResourcePatch

升级后:

  • 手动将记录的 --node-local-dns-ip 参数重新添加到 kube-ovn-controller 配置中

注意:该兼容性问题已在 4.3 及以上版本中解决,因此升级到 4.3+ 时无需人工干预。

安装

通过 Marketplace 安装

  1. 导航到 Administrator > Marketplace > Cluster Plugins。

  2. 在插件列表中搜索 "Alauda Build of NodeLocal DNSCache"。

  3. 点击 Install 打开安装配置页面。

  4. 配置所需参数:

    参数说明示例值
    IP节点本地 DNS 缓存服务器的 IP 地址。对于 IPv4,建议使用 169.254.0.0/16 范围内的地址,最好是 169.254.20.10。对于 IPv6,建议使用 fd00::/8 范围内的地址,最好是 fd00::10。169.254.20.10
  5. 查看部署说明,并确保环境满足要求。

  6. 点击 Install 完成安装。

  7. 等待插件状态变为 "Ready"。

工作原理

架构

Pod → NodeLocal DNSCache → [Cache Hit] → Pod
           ↓
    [Cache Miss] → CoreDNS → Response → Cache & Pod

配置

Network Policy 配置

重要:如果集群已启用 NetworkPolicy,则必须配置正确的规则,以允许 DNS 流量到达 NodeLocal DNSCache。若没有这些规则,Pods 可能无法解析 DNS 查询。

使用 NetworkPolicy 时,请确保允许以下 DNS 流量:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns-cache
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
        - ipBlock:
            cidr: 169.254.20.10/32 # NodeLocal DNS IP address
      ports:
        - protocol: UDP
          port: 53
        - protocol: TCP
          port: 53
  egress:
    - to:
        - ipBlock:
            cidr: 169.254.20.10/32 # NodeLocal DNS IP address
      ports:
        - protocol: UDP
          port: 53
        - protocol: TCP
          port: 53

已知风险与临时解决方案

请将此能力视为适用于生产就绪的 Alpha 版本。推荐用于测试或预生产环境。对于生产环境或类生产集群,在启用 NodeLocal DNSCache 前请评估以下风险。如果这些风险不适合你的工作负载,请继续直接使用 CoreDNS。

在插件安装页面公开相关参数之前,仅在目标环境中验证后,才使用以下临时解决方案。

风险 1:主机网络端口冲突

node-cache Pod 运行在主机网络命名空间中。其健康检查端点使用主机网络端口,这可能与使用相同端口的工作负载或节点级进程冲突。例如,默认健康检查端点监听 8080 端口。

安装前,请确认目标节点上的工作负载未依赖相同的主机网络端口,例如 8080 端口:

ss -lntp | grep ':8080'

编辑 NodeLocal DNSCache ConfigMap:

kubectl -n <namespace> edit cm <configmap-name>

将 Corefile 中的 health 端口修改为相同的未使用端口,例如:

health 127.0.0.1:18080

编辑 NodeLocal DNSCache DaemonSet:

kubectl -n <namespace> edit ds <daemonset-name>

将 node-cache 容器的探针端口改为相同的端口:

livenessProbe:
  httpGet:
    host: 127.0.0.1
    path: /health
    port: 18080

等待 DaemonSet 滚动更新完成:

kubectl -n <namespace> rollout status ds/<daemonset-name>

如果当前插件版本未在安装页面暴露健康端口参数,请使用站点级补丁,使 Corefile 的 health 端口与 DaemonSet 的探针端口保持一致。

WARNING

重要: 这只是一个临时的站点补丁,不是持久化的插件配置。插件升级、重新安装或平台协调操作可能会重新生成 ConfigMap 和 DaemonSet,并覆盖你自定义的端口设置。如果在这些操作后仍需要非默认健康端口,请在将插件视为可用之前重新应用补丁。

风险 2:节点级 DNS 依赖

当 NodeLocal DNSCache 生效后,节点上的 Pods 会使用本地的 node-cache Pod 进行 DNS 解析。如果该 Pod 在插件升级、驱逐或崩溃期间不可用,同一节点上的 Pods 的 DNS 解析可能会失败。请为 node-cache 的就绪状态配置监控和告警。

如果 DNS 解析已经失败,且事先没有配置备用 DNS 服务器,可临时将 kubelet 的 cluster-dns 指回 CoreDNS 的 ClusterIP,并重新创建受影响的 Pods。

你可以将 kubelet 的 cluster-dns 同时配置为 NodeLocal DNSCache IP 和 CoreDNS ClusterIP。在需要变更的每个节点上,编辑 kubelet 参数文件:

vi /var/lib/kubelet/kubeadm-flags.env

将 --cluster-dns 从单个 NodeLocal DNSCache IP 修改为同时包含 NodeLocal DNSCache IP 和 CoreDNS ClusterIP:

--cluster-dns=169.254.20.10,10.96.0.10

保存文件后重启 kubelet:

systemctl restart kubelet

此变更仅影响新创建的 Pods。请重新创建受影响的 Pods,以便重新生成它们的 /etc/resolv.conf,例如:

kubectl -n <namespace> rollout restart deployment/<deployment-name>

当 NodeLocal DNSCache 不可用时,可以使用 CoreDNS 作为备用,但这并不是透明故障切换。对于 glibc 解析器,DNS 故障切换可能会在多个 search 查询超时后才使用下一个 DNS 服务器。基于 musl 的镜像,例如 Alpine Linux,通常没有这种延迟,因为 musl 可以并行查询 nameserver。

如果工作负载对 DNS 解析延迟敏感,请为该工作负载调优解析器的 timeout 和 attempts。例如:

spec:
  dnsConfig:
    options:
      - name: timeout
        value: "1"
      - name: attempts
        value: "1"
WARNING

重要: 在节点上编辑 kubelet 文件同样属于临时的站点变更。节点重建、重新部署,或任何会重新生成 kubelet 配置的流程,都可能完全丢失多 DNS 设置。如果在这些操作后仍需要 CoreDNS 备用,请重新应用 kubelet 变更,然后再次重新创建受影响的 Pods。

风险 3:通过节点 IP 进行指标采集

如果外部监控无法通过节点 IP 采集 node-cache 指标,请编辑 NodeLocal DNSCache ConfigMap:

kubectl -n <namespace> edit cm <configmap-name>

在 Corefile 中,移除 prometheus 指令中的 IP 绑定。不要更改 DNS 服务端口。

prometheus 169.254.20.10:9253
prometheus :9253

重启 node-cache Pods 或滚动 DaemonSet,以使更新后的 Corefile 生效。

WARNING

重要: 这同样是一个临时的站点补丁,不是持久化的插件配置。如果直接修改生成的 ConfigMap,插件升级、重新安装或平台协调可能会覆盖 prometheus 绑定,并将指标端点恢复为之前的默认值。如果在这些操作后仍需要通过节点 IP 进行外部指标采集,请重新应用该变更。