应用场景
在用户业务采用 Kubernetes 标准服务发现机制的情况下,若 CoreDNS 请求的 QPS 过高,可能导致 DNS 查询延迟增加和负载不均,从而对业务性能和稳定性产生不利影响。
针对这种场景,可以通过部署 NodeLocal DNS Cache,降低 CoreDNS 请求压力,提升集群内 DNS 解析性能以及稳定性。本文将详细介绍如何在 TKE 集群安装并使用 NodeLocal DNS Cache。
使用限制
暂不支持部署在超级节点上的 Pod。
暂不支持网络模式采用 Cilium Overlay,以及独立网卡模式的 Pod。
NodeLocal DNS Cache 当前仅作为 CoreDNS 的缓存代理使用,不支持配置其他插件。如果有需要,请直接配置 CoreDNS。
原理介绍
社区方案
社区版本 NodeLocal DNS Cache 通过 DaemonSet 在集群的每个节点上部署一个 hostNetwork 的 Pod,该 Pod 名称为 node-local-dns,可以缓存本节点上 Pod 的 DNS 请求。如果存在 cache misses ,该 Pod 将会通过 TCP 链接请求上游 kube-dns 服务进行获取。原理图如下所示:
在 kube-proxy 采用不同的转发模式下,支持效果有差异。
iptables 模式下,部署 NodeLocal DNS Cache 后,存量 Pod 和增量 Pod 均可以无感自动切换访问本地 DNS Cache。
ipvs 模式下,增量和存量 Pod 均无法实现 DNS Cache 的无感切换。如果在 ipvs 模式下想使用 NodeLocal DNS Cache 服务,可以采用以下两种方式:
方式1:修改 kubelet 参数
--cluster-dns
,指向169.254.20.10
,然后重启 kubelet 服务。此操作方式存在业务中断的风险。方式2:修改 Pod 的 DNSConfig,指向新的
169.254.20.10
地址,使用本地的 DNS Cache 处理 DNS 解析。TKE 中 NodeLocal DNS Cache 方案
TKE 上的 NodeLocal DNS Cache 方案对社区版本在 ipvs 模式下的缺陷进行了增强,针对增量 Pod 会自动配置 DNSConfig,具备本地 DNS 缓存能力。不过当前仍然无法支持存量 Pod 自动切换,需要用户显式操作(重建 Pod 或手动配置 DNSConfig)。
工作原理:
控制台安装 NodeLocal DNS Cache
您可以通过 TKE 的组件管理部署安装 Nodelocal DNS Cache,操作方式如下:
1. 登录 容器服务控制台,在左侧导航栏中选择集群。
2. 在集群列表中,单击目标集群 ID,进入集群详情页。
3. 选择左侧菜单栏中的组件管理,在组件管理页面单击新建。
4. 在新建组件管理页面中勾选 NodeLocalDNSCache。如下图所示:
5. 单击完成。
6. 返回组件管理列表页,检查 localdns 组件状态置为成功,如下图所示:
使用 NodeLocal DNS Cache
iptables 集群和 ipvs 集群下,对 NodeLocal DNS Cache 的使用方式不同,具体描述如下:
iptables 集群
存量 Pod:用户无需任何操作,存量 Pod 可以直接使用本地 DNS Cache 能力解析 DNS 请求。
增量 Pod:用户无需任何操作,新建 Pod 可以直接使用本地 DNS Cache 能力解析 DNS 请求。
ipvs 集群
针对 ipvs 集群,TKE 会将 DNSConfig 配置动态注入到新建的 Pod 中,同时会将 dnsPolicy 配置为 None,避免手动配置 Pod YAML。自动注入的配置如下:
dnsConfig:nameservers:- 169.254.20.10- 10.23.1.234options:- name: ndotsvalue: "3"- name: attemptsvalue: "2"- name: timeoutvalue: "1"searches:- <pod所在命名空间>.svc.cluster.local- svc.cluster.local- cluster.localdnsPolicy: None
注意:
如果您需要相应的 Pod 能够自动注入 DNSConfig,请确保满足以下条件:
1. 请在 Pod 所在的命名空间打上 Label 标签:
localdns-injector=enabled
。例如:如果您需要 default 命名空间中的新建 Pod 自动注入 DNSConfig,请配置:
kubectl label namespace default localdns-injector=enabled
2. 保证 Pod 不在 kube-system 和 kube-public 命名空间,这两个命名空间下的 Pod 不会自动注入 DNSConfig。
3. 保证 Pod label 不包含
localdns-injector=disabled
,包含此 label 的 Pod 不会被注入 DNSConfig。4. 新建 Pod 网络配置非 hostNetwork,需要配置 DNSPolicy 为 ClusterFirst;如果 Pod 网络为 hostNetwork,需要配置 DNSPolicy 为ClusterFirstWithHostNet。
5. 暂不支持 GR 网络模式。
存量 Pod:存量 Pod 暂时无法做到无感切换。如果需要存量 Pod 使用本地 DNS Cache 代理能力,用户需要重建 Pod。重建后,Pod 会自动注入 DNSConfig,从而使用本地 DNS Cache 能力解析 DNS 请求。
增量 Pod:当满足上述注意事项后,新建 Pod 会自动注入 DNSConfig 配置,访问本节点
169.254.20.10:53
,使用本地 DNS Cache 能力解析 DNS 请求。验证 NodeLocal DNS Cache
NodeLocal DNS Cache 成功开启后,可以在节点上验证 Pod 访问 CoreDNS 服务是否通过了本地 DNS Cache 进行解析。以下是分别验证 iptables 集群和 ipvs 集群的 NodeLocal DNS Cache 开启效果的方法。
说明:
如果您想通过日志验证节点上 NodeLocal DNS Cache 是否代理了本节点的 DNS 请求,需要修改 kube-system 命名空间下 node-local-dns 的 ConfigMap 配置,在对应的 Corefile 配置中添加 log 日志能力。如下图所示:
iptables 集群验证
在 iptables 集群中,需要验证存量 Pod 以及增量 Pod 是否可以自动通过本地 NodeLocal DNS Cache 代理 Pod 的 DNS 请求。
存量 Pod
1. 登录存量 Pod。
2. 使用 nslookup 命令解析 kube-dns 的 svc。如下图所示:
3. 检查本节点上 node-cache Pod 日志。如下图所示:
可以确认存量 Pod 对 kube-dns 的解析请求通过了本节点上的 NodeLocal DNS Cache 服务。
增量 Pod
1. 登录新建 Pod。
2. 使用 nslookup 命令解析 kube-dns 的 svc。如下图所示:
3. 检查本节点上 node-cache Pod 日志。如下图所示:
可以确认新增 Pod 对 kube-dns 的解析请求通过了本节点上的 NodeLocal DNS Cache 服务。
ipvs 集群验证
在 ipvs 集群中,存量 Pod 暂时无法自动切换使用本地 DNS Cache,需要验证增量 Pod 是否可以自动通过本地 NodeLocal DNS Cache 代理 Pod 的 DNS 请求。操作步骤如下:
1. 将需要的命名空间添加 label:
localdns-injector=enabled
2. 在需要的命名空间中,新建 Pod,确认 Pod 注入了 DNSConfig 配置。如下图所示:
3. 登录新建 Pod。
4. 使用 nslookup 命令解析 kube-dns 的 svc。如下图所示:
5. 检查本节点上 node-cache Pod 日志。如下图所示:
可以确认 ipvs 集群中新增 Pod 对 kube-dns 的解析请求通过了本节点上的 NodeLocal DNS Cache 服务。
卸载 NodeLocal DNS Cache
1. 登录 容器服务控制台,在左侧导航栏中选择集群。
2. 在集群列表中,单击目标集群 ID,进入集群详情页。
3. 选择左侧菜单栏中的组件管理,在组件管理页面单击需要删除组件所在行右侧的删除,如下图所示:
相关问题
关于 prefer_udp 相关配置
问题描述
在 TKE 集群中,CoreDNS 使用腾讯云默认的 DNS 服务(183.60.83.19/183.60.82.98)作为上游 DNS。腾讯云默认的 DNS 服务支持在 VPC 内进行私有域解析的 DNS 请求,但目前仅支持 UDP 协议,不支持 TCP 协议。然而,NodeLocal DNS 默认会通过 TCP 方式连接到 CoreDNS。如果 CoreDNS 未配置 prefer_udp,它将默认通过 TCP 方式访问上游的腾讯云默认 DNS 服务,这将导致一定几率的域名解析失败。
解决方案
1. 新创建的 TKE 集群:CoreDNS 已经默认配置了 prefer_udp,用户无需处理。
2. 存量集群:如果用户已经部署了 NodeLocal DNS Cache 组件,建议用户配置 CoreDNS 服务的相关 Corefile,添加 prefer_udp 并 reload 配置。示例如下:
3. 未安装 NodeLocal DNS Cache 的集群:在安装 NodeLocal DNS Cache 组件时,会强制判断 CoreDNS Corefile 是否添加了 prefer_udp 配置。用户需要手动配置后,才能继续安装 NodeLocal DNS Cache 组件。
关于 kube-proxy 版本适配问题
问题描述
TKE 集群中低版本的 kube-proxy 存在 iptables(legacy/nftable)多后端问题,触发条件如下:
1. 集群 kube-proxy 代理模式为 iptables。
2. 对应不同版本的 k8s 集群,集群中的 kube-proxy 版本小于下面的版本号。
TKE 集群版本 | 问题修复版本 |
1.24 | 升级 kube-proxy 到 v1.24.4-tke.5 及以上 |
1.22 | 升级 kube-proxy 到 v1.22.5-tke.11 及以上 |
1.20 | 升级 kube-proxy 到 v1.20.6-tke.31 及以上 |
1.18 | 升级 kube-proxy 到 v1.18.4-tke.35 及以上 |
1.16 | 升级 kube-proxy 到 v1.16.3-tke.34 及以上 |
1.14 | 升级 kube-proxy 到 v1.14.3-tke.28 及以上 |
1.12 | 升级 kube-proxy 到 v1.12.4-tke.32 及以上 |
1.10 | 升级 kube-proxy 到 v1.10.5-tke.20 及以上 |
此时,如果客户部署了 NodeLocal DNS Cache 组件,会概率性触发多后端问题,导致集群内 service 服务无法正常访问。
解决方案
1. 如果用户现有集群配置符合上述触发条件,建议用户将 kube-proxy 版本升级到最新版本。
2. 当前 TKE 集群安装 NodeLocal DNS Cache 组件时,会对集群的 kube-proxy 进行判断,如果版本不符合条件,会禁止用户安装组件。此时请主动升级 kube-proxy 版本到最新版本。