为了解决CoreDNS负载过高或业务Pod所在节点负载过高引发的DNS解析失败的问题,可部署NodeLocal DNSCache组件,在各节点运行DNS缓存代理,降低解析延迟,提高可用性。
工作原理
适用范围
不支持Windows节点。
只有当Pod适用主机网络(
hostNetwork:true)且DNS策略为DNSPolicy: ClusterFirstWithHostNet,或未使用主机网络模式(hostNetwork:false)且DNS策略为DNSPolicy: ClusterFirst时,才会自动注入。若集群网络插件为Terway,要求Terway版本为v1.0.10.301或更高。
若集群创建时使用的网络插件为Terway早期版本且使用了IPvlan模式,请参照为什么配置组件后没有效果判断是否需要修改Terway配置。
虚拟节点在ACK NodeLocal DNSCache版本为v1.6.0或更高,且ACK Virtual Node版本为2.14.0或更高时支持启用DNS缓存。
启用DNS缓存
步骤一:安装组件
登录容器服务管理控制台,在左侧导航栏选择集群列表。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,单击组件管理。
在网络页签中找到ACK NodeLocal DNSCache卡片,单击安装,在弹出的对话框中单击确认。
步骤二:配置并启用
启用DNS缓存有多种方式,作用范围不同:
仅在ACK NodeLocal DNSCache v1.6.0及更高版本支持。
适用于调试与测试的场景,因
dnsConfig会被强制覆盖,不适用于虚拟节点上的Pod。
在集群全局启用(推荐)
NodeLocal DNSCache组件提供了是否默认启用 DNSCache配置。启用此配置后,除系统保留命名空间外的所有命名空间中的Pod在新建时都会被自动注入DNS Cache。
登录容器服务管理控制台,在左侧导航栏选择集群列表。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,单击组件管理。
在网络页签中找到ACK NodeLocal DNSCache卡片,单击配置,在弹出的对话框中勾选是否默认启用 DNSCache,然后单击确认。
为单个命名空间启用
NodeLocal DNSCache组件会自动监听包含了node-local-dns-injection=enabled标签的命名空间,并为其中新建的Pod自动注入DNS Cache相关配置。
为命名空间添加标签:
kubectl label <namespace> node-local-dns-injection=enabled在启用DNS缓存的命名空间中,新建的Pod会自动注入下方的dnsConfig配置,使用DNS缓存:
nameservers中会额外添加CoreDNS的ClusterIP作为备份的DNS服务器,保证DNS请求高可用(不适用于虚拟节点上的Pod)。dnsConfig:
nameservers:
- 169.254.20.10
- <kube-dns> # 自动填入kube-dns Service的ClusterIP
options:
- name: ndots
value: "3"
- name: attempts
value: "2"
- name: timeout
value: "1"
searches:
- default.svc.cluster.local
- svc.cluster.local
- cluster.local
dnsPolicy: None为单个Pod手动启用
在Pod中添加spec.dnsConfig配置,在其中配置nameservers为169.254.20.10和kube-dns Service的IP,可手动为Pod启用DNS缓存。
该方式不适用于虚拟节点,虚拟节点上的Pod的dnsConfig会被强制覆盖,无法使用169.254.20.10作为DNS Server。
apiVersion: v1
kind: Pod
metadata:
name: alpine
namespace: default
spec:
containers:
- image: alpine
command:
- sleep
- "10000"
imagePullPolicy: Always
name: alpine
dnsPolicy: None
dnsConfig:
nameservers: ["169.254.20.10","<kube-dns>"] # 替换为kube-dns Service IP
searches:
- default.svc.cluster.local
- svc.cluster.local
- cluster.local
options:
- name: ndots
value: "3"
- name: attempts
value: "2"
- name: timeout
value: "1"dnsPolicy:必须设置为None。nameservers:配置为169.254.20.10(NodeLocal DNSCache在节点上的IP),<kube-dns>需替换为kube-system命名空间中的kube-dnsService的IP地址。请登录容器服务管理控制台,在左侧中查看。searches:设置搜索域,保证集群内部域名能够被正常解析。ndots:默认为3,适当降低ndots可以提升解析效率。更多信息,请参见resolv.conf。
效果验证
启用DNS缓存后,创建一个新的工作负载,验证是否自动注入DNS缓存配置。
查看Pod信息。
kubectl get pods预期输出:
NAME READY STATUS RESTARTS AGE nginx-766448f68c-m**** 1/1 Running 0 4m39s nginx-766448f68c-w**** 1/1 Running 0 4m39s选择其中一个Pod,查看dnsConfig。
kubectl get pod nginx-766448f68c-m**** -o=jsonpath='{.spec.dnsConfig}'预期输出如下,
nameservers中同时存在两个IP,说明成功为应用接入NodeLocal DNSCache。下方输出中的
172.21.0.10是kube-dns的ClusterIP,请以实际输出为准。map[nameservers:[169.254.20.10 172.21.0.10] options:[map[name:ndots value:5]] searches:[default.svc.cluster.local svc.cluster.local cluster.local]]
使用限制
在命名空间启用DNS Cache的情况下,拥有
node-local-dns-injection=disabled标签的Pod不会进行自动注入。NodeLocal DNSCache不提供Hosts、Rewrite等插件能力,仅作为CoreDNS的透明缓存代理。如有需要,请在CoreDNS配置中修改。
DNS缓存在ACK系统保留的命名空间中不会生效,请查看不生效的命名空间。
常见问题
为什么配置组件后没有效果?
配置组件后没有效果,同时NodeLocal DNSCache的日志中也看不到来自Pod的访问,这是由于在Terway早期版本创建的集群中,默认Terway配置无法使用NodeLocal DNSCache。请参照下方的步骤,对Terway配置进行修改。
查看Terway配置文件。
kubectl -n kube-system get cm eni-config -o yaml | grep eniip_virtual_type kubectl -n kube-system get cm eni-config -o yaml | grep host_stack_cidrs检查配置文件中
eniip_virtual_type字段是否开启IPVLAN模式。如果配置文件中此项不存在或不是IPVLAN,则无需进行后续配置。检查配置文件中是否已配置
host_stack_cidrs字段。如果配置文件中已配置host_stack_cidrs字段,则无需进行后续配置。
在Terway配置文件中添加
host_stack_cidrs字段,并输入网段169.254.20.10/32,保存并退出。10-terway.conf: | { "cniVersion": "0.3.0", "name": "terway", "eniip_virtual_type": "IPVlan", "host_stack_cidrs": ["169.254.20.10/32"], "type": "terway" }查看当前Terway的DaemonSet。
kubectl -n kube-system get daemonset terway-eniip预期输出:
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE terway-eniip 2 2 2 2 2 <none> 15m触发Terway DaemonSet重建。
kubectl rollout restart -n kube-system daemonset terway-eniip登录任意集群节点,查看Terway配置文件。
如果Terway配置文件包含添加的网段,则说明配置成功。
cat /etc/cni/net.d/*预期输出:
{ "cniVersion": "0.3.0", "name": "terway-chainer", "plugins": [ { "eniip_virtual_type": "IPVlan", "host_stack_cidrs": [ "169.254.20.10/32", ], "type": "terway" }, { "type": "cilium-cni" } ] }所有Terway Pod重建并正常后,可以继续安装NodeLocal DNSCache了。
为什么Pod没有注入DNS缓存配置?
下列原因都可能导致Pod没有自动注入DNS配置:
Pod处于ACK系统保留命名空间:
ACK NodeLocal DNSCache版本早于v1.6.0,且Pod处于虚拟节点上、Pod或其所在命名空间拥有ECI相关标签,例如
virtual-node-affinity-injection、eci、alibabacloud.com/eci等。Pod拥有
node-local-dns-injection=disabled标签。Pod的网络为
hostNetwork时,未配置DNSPolicy: ClusterFirstWithHostNet;其他类型的Pod,未配置DNSPolicy: ClusterFirst。
如何查看组件监控?
ack-arms-prometheus组件版本为1.1.33及以上时,才会显示NodeLocal DNSCache大盘。
NodeLocal DNSCache监控大盘记录了包括缓存命中率等关键数据。请通过大盘确认组件状况、评估组件负载,确保NodeLocal DNSCache在生产环境中的稳定性。
登录容器服务管理控制台,在左侧导航栏选择集群列表。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择。
在Prometheus监控页面,单击网络监控页签。然后在NodeLocal DNSCache页签查看监控大盘。
如果监控大盘内无数据,请参见为什么监控大盘内无数据?

为什么监控大盘内无数据?
可能是由于NodeLocal DNSCache未配置Prometheus采集相关配置。
在kube-system命名空间中找到名为node-local-dns的DaemonSet,确认Annotations中是否已存在Prometheus相关配置。如果未存在,请添加相关配置。
apiVersion: apps/v1
kind: DaemonSet
metadata:
annotations:
deprecated.daemonset.template.generation: '1'
meta.helm.sh/release-name: ack-node-local-dns
meta.helm.sh/release-namespace: kube-system
#Prometheus相关配置:
prometheus.io/path: "/metrics"
prometheus.io/port: "9253"
prometheus.io/scrape: "true"
...升级组件时,有哪些注意事项?
及时升级组件版本,可以获取新功能、性能改进或安全修复。
登录容器服务管理控制台,在左侧导航栏选择集群列表。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,单击组件管理。
在组件管理页面单击ACK NodeLocal DNSCache卡片下的升级,在弹出的对话框中单击确认。
重要若对ConfigMap
node-local-dns进行过修改操作,升级时修改配置将会被覆盖。建议在升级前对node-local-dns进行备份,当组件升级完成后,重新配置组件。若对node-local-dns DaemonSet进行过污点容忍等修改操作,升级时污点容忍等操作将会被覆盖,升级后需要再次设置。
如果升级NodeLocal DNSCache失败,需要根据操作异常码查找对应的问题,查看问题原因和解决方案。详细描述,请参见组件异常问题排查。
如何卸载组件?
关闭DNS缓存注入功能:根据DNS缓存的配置方式关闭DNS缓存,例如开启方式为通过组件配置在集群全局开启时,则通过组件配置关闭DNS缓存注入。
调整现有Pod中的DNS配置:
修改现有Pod中的DNS配置,移除
169.254.20.10(NodeLocal DNSCache在节点上的IP)配置,将DNS服务器地址设置为kube-dns Service的ClusterIP),然后重启Pod。检查Pod配置中是否留存DNS缓存,如果没有任何输出,表明所有Pod都已迁移。
kubectl get pods -A -o jsonpath='{range .items[?(@.spec.dnsConfig.nameservers[*] contains "169.254.20.10")]}{.metadata.namespace}{"/"}{.metadata.name}{"\n"}{end}'
登录容器服务管理控制台,在左侧导航栏选择集群列表。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,单击组件管理。
在组件管理页面单击ACK NodeLocal DNSCache卡片下的卸载,在弹出的对话框中单击确认。
重要卸载后所有解析流量会请求至CoreDNS,建议参照DNS最佳实践进行配置以保证DNS的高可用性。