在ACK集群中部署NodeLocal DNSCache可以提升服务发现的稳定性和性能,NodeLocal DNSCache通过在集群节点上作为DaemonSet运行DNS缓存代理来提高集群DNS性能。本文介绍如何安装NodeLocal DNSCache,并在应用中使用NodeLocal DNSCache。
前提条件
已创建ACK集群。具体操作,请参见创建Kubernetes托管版集群。
使用kubectl命令连接集群。具体操作,请参见获取集群KubeConfig并通过kubectl工具连接集群。
使用限制
NodeLocal DNSCache不支持ACK Serverless集群、以及托管版、专有版集群中部署的ECI类型的Pod。
如果集群网络类型为Terway,请更新Terway至v1.0.10.301及以上版本。如果是基于IPVLAN的Terway多IP模式,需要对Terway进行配置修改。更多信息,请参见修改Terway配置。
组件管理中的NodeLocal DNSCache和应用目录中的ack-node-local-dns为同一应用,不需要重复安装。
NodeLocal DNSCache不提供Hosts、Rewrite等插件能力,仅作为CoreDNS的透明缓存代理。如有需要,可在CoreDNS配置中修改。
使用NodeLocal DNSCache前,您需要对CoreDNS配置进行修改,否则可能导致集群外部域名解析异常。具体操作,请参见配置Forward插件与上游VPC DNS服务器的默认协议。
NodeLocal DNSCache简介
ACK NodeLocal DNSCache是基于社区开源项目NodeLocal DNSCache的一套DNS本地缓存解决方案。ACK NodeLocal DNSCache在Helm Chart中的名称是ack-node-local-dns。该方案主要由DNS本地缓存DaemonSet和DNSConfig动态注入控制器Deployment组成:
DNSConfig动态注入控制器Deployment,基于Admission Webhook机制拦截Pod创建的请求,自动注入使用DNS缓存的Pod DNSConfig信息。
说明如果不启用DNSConfig动态注入控制器Deployment,您需要手动注入DNS域名相关配置至Pod配置中。具体操作,请参见在应用中使用NodeLocal DNSCache下的方式二:手动指定DNSConfig。
DNS缓存DaemonSet可以在每个节点上创建一个虚拟网络接口(默认监听IP 169.254.20.10,如需修改请提交工单咨询),配合Pod的DNSConfig和节点上的网络配置,Pod内产生的DNS请求会被该DaemonSet服务所代理。
重要DaemonSet服务内同样基于CoreDNS提供服务,但其仅具有代理和缓存的功能,请勿启用额外的插件能力(如Hosts、Rewrite等)。
关于NodeLocal DNSCache的缓存策略,请参见DNS解析及缓存策略说明。
序号 | 描述 |
① | 已注入DNS本地缓存的Pod,默认会通过NodeLocal DNSCache监听于节点上的IP(169.254.20.10)解析域名。 |
② | NodeLocal DNSCache本地若无缓存应答解析请求,则会通过kube-dns服务请求CoreDNS进行解析。 |
③ | CoreDNS对于非集群内域名,会通过VPC DNS服务器进行解析。 |
④ | 已注入DNS本地缓存的Pod,当无法连通NodeLocal DNSCache时,会继而直接通过kube-dns服务连接到CoreDNS进行解析,此链路为备用链路。 |
⑤ | 未注入DNS本地缓存的Pod,会通过标准的kube-dns服务链路连接到CoreDNS进行解析。 |
安装NodeLocal DNSCache
您可以通过组件管理或者应用目录页面安装NodeLocal DNSCache,建议您通过组件管理安装NodeLocal DNSCache。
方式一:通过组件管理安装NodeLocal DNSCache
登录容器服务管理控制台,在左侧导航栏选择集群。
在集群列表页面,选择目标集群名称或者目标集群右侧操作列下的 。
在组件管理页面,单击网络页签,找到ACK NodeLocal DNSCache。
单击ACK NodeLocal DNSCache的安装,在弹出的对话框中单击确定。
方式二:通过应用目录安装NodeLocal DNSCache
登录容器服务管理控制台,在左侧导航栏选择 。
在应用市场页面单击应用目录页签,然后搜索并选中ack-node-local-dns。
在ack-node-local-dns页面,单击一键部署。
在创建面板中,选择集群和命名空间,然后单击下一步。
在参数配置页面,设置相应参数,然后单击确定。
需设置的参数说明如下表。
参数
描述
获取路径
upstream_ip
kube-system命名空间下 kube-dns服务的ClusterIP。NodeLocal DNSCache通过该服务与CoreDNS通信来解析集群内域名。
如果您需要指定不同的上游DNS服务器,可以修改此参数。
clusterDomain
集群主域名。
查看节点上kubelet进程的--cluster-domain参数,默认为cluster.local。
在应用中使用NodeLocal DNSCache
NodeLocal DNSCache默认不会部署至Master节点。如果您的业务需要部署至Master节点,且您的Master节点设置了污点,您需要修改命名空间kube-system下node-local-dns DaemonSet的污点容忍。
为了将应用原本请求CoreDNS的流量改为由DNS缓存DaemonSet代理,需要将Pod内部的nameservers配置成169.254.20.10和kube-dns对应的IP地址,您有以下几种方式可以选择:
方式一:借助DNSConfig动态注入控制器在Pod创建时配置DNSConfig自动注入,推荐使用此方式。
方式二:创建Pod时手动指定DNSConfig。
方式三:修改kubelet参数,并重启节点kubelet。存在业务中断风险,不推荐使用此方式。
方式一:配置DNSConfig自动注入
DNSConfig动态注入控制器可用于自动注入DNSConfig至新建的Pod中,避免您手工配置Pod YAML进行注入。本应用默认会监听包含node-local-dns-injection=enabled
标签的命名空间中新建Pod的请求,您可以通过以下命令给命名空间打上Label标签。
kubectl label namespace default node-local-dns-injection=enabled
上述命令仅会开启default命名空间的自动注入,如需对其他命名空间开启自动注入,则需要替换
default
为目标命名空间名称。在命名空间DNSConfig自动注入开启的情况下,如需对部分Pod进行豁免(即不进行注入),可以调整其Pod Template中Labels标签字段,加上
node-local-dns-injection=disabled
标签。ECI不支持NodeLocal DNSCache。当Deployment动态弹性扩容至ECI节点时,ECI上Pod会因无法连通NodeLocal DNSCache导致域名解析超时,此时必须对整个Deployment进行注入豁免,可以调整其Pod Template中的Labels标签字段加上
node-local-dns-injection=disabled
。
开启自动注入后,您创建的Pod会被增加以下字段,为了最大程度上保证业务DNS请求高可用,nameservers中会额外加入kube-dns的ClusterIP地址作为备份的DNS服务器。
dnsConfig:
nameservers:
- 169.254.20.10
- 172.21.0.10
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在同时满足以下条件时,才会自动注入DNS缓存。如果您的Pod容器未注入DNS缓存服务器的IP地址,请检查Pod是否未满足以下条件。
新建Pod不位于kube-system和kube-public命名空间。
新建Pod所在命名空间的Labels标签包含
node-local-dns-injection=enabled
。新建Pod所在命名空间的Labels不包含ECI Pod相关标签,例如
virtual-node-affinity-injection
、eci
、alibabacloud.com/eci
等。新建Pod没有被打上
eci
、alibabacloud.com/eci
等ECI相关标签,或打上禁用DNS注入node-local-dns-injection=disabled
标签。新建Pod的网络为
hostNetwork
且DNSPolicy为ClusterFirstWithHostNet
,或Pod为非hostNetwork
且DNSPolicy为ClusterFirst
。
方式二:手动指定DNSConfig
如果不适用Admission Webhook Deployment自动注入,您可以通过修改Pod进行手动指定DNSConfig。
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","172.21.0.10"]
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和kube-dns的ClusterIP对应的IP地址。
searches:设置搜索域,保证集群内部域名能够被正常解析。
ndots:默认为5,可以适当降低ndots以提升解析效率。更多信息,请参见resolv.conf。
方式三:配置kubelet启动参数
kubelet通过--cluster-dns和--cluster-domain两个参数来全局控制Pod DNSConfig。在/etc/systemd/system/kubelet.service.d/10-kubeadm.conf 配置文件中需要增加一个--cluster-dns参数,设置值为链路本地地址169.254.20.10。修改后执行sudo systemctl daemon-reload
和sudo systemctl restart kubelet
来生效。
--cluster-dns=169.254.20.10 --cluster-dns=<kube-dns ip> --cluster-domain=<search domain>
cluster-dns:部署Pod时,默认采用的DNS服务器地址,默认只引用了
`kube-dns`
的服务IP,需要增加一个对链路本地地址169.254.20.10的引用。cluster-domain:部署Pod时,默认采用的DNS搜索域,保持原有搜索域即可,一般为
`cluster.local`
。
配置应用使用NodeLocal DNSCache示例
通过在default命名空间下部署Deployment类型示例应用,演示如何配置应用使用NodeLocal DNSCache。
执行以下命令,给接入NodeLocal DNSCache的应用所在的命名空间(default)设置标签。
kubectl label namespace default node-local-dns-injection=enabled
重要Admission Controller会忽略kube-system和kube-public命名空间下的应用,请勿在这两个命名空间下进行自动注入dnsConfig操作。
在集群的default命名空间下部署示例应用。
使用以下YAML模板创建名为ubuntu-deployment的示例应用。
apiVersion: apps/v1 # for versions before 1.8.0 use apps/v1beta1 kind: Deployment metadata: name: ubuntu labels: app: ubuntu spec: replicas: 2 selector: matchLabels: app: ubuntu template: metadata: labels: app: ubuntu spec: containers: - name: ubuntu image: ubuntu command: ["sh", "-c"] args: ["sleep 100000"]
执行以下命令,使示例应用在集群中生效。
kubectl apply -f ubuntu-deployment.yaml
预期输出:
deployment.apps/ubuntu created
执行以下命令,查看应用信息。
kubectl get deployment ubuntu
预期输出:
NAME READY UP-TO-DATE AVAILABLE AGE ubuntu 2/2 2 2 7s
查看是否成功注入dnsConfig。
执行以下命令,查看Pod信息。
kubectl get pods
预期输出:
NAME READY STATUS RESTARTS AGE ubuntu-766448f68c-m**** 1/1 Running 0 4m39s ubuntu-766448f68c-w**** 1/1 Running 0 4m39s
执行以下命令,查看Pod的dnsConfig是否已经接入NodeLocal DNSCache。
kubectl get pod ubuntu-766448f68c-m**** -o=jsonpath='{.spec.dnsConfig}'
预期输出:
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]]
当输出以上内容时,说明成功为应用接入NodeLocal DNSCache。
开启自动注入后,您创建的Pod会被增加以下字段,为了最大程度上保证业务DNS请求高可用,nameservers中会额外加入kube-dns服务的ClusterIP地址(172.21.0.10)作为备份的DNS服务器。
dnsConfig: nameservers: - 169.254.20.10 - 172.21.0.10 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
升级NodeLocal DNSCache
如果您是在组件管理页面安装NodeLocal DNSCache,您需要在组件管理页面升级NodeLocal DNSCache。如果您是在应用目录页面安装NodeLocal DNSCache,您需要在Helm页面卸载NodeLocal DNSCache,然后再重新安装NodeLocal DNSCache。
通过组件管理页面升级NodeLocal DNSCache
登录容器服务管理控制台,在左侧导航栏选择集群。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择 。
在组件管理页面单击NodeLocal DNSCache下的升级,在弹出的对话框中单击确定。
说明若您对node-local-dns DaemonSet进行过污点容忍等修改操作,升级时污点容忍等操作将会被覆盖,升级后需要再次设置。
如果升级NodeLocal DNSCache失败,您需要根据操作异常码查找对应的问题,查看问题原因和解决方案。详细描述,请参见组件异常问题排查。
通过应用目录页面升级NodeLocal DNSCache
如果您是通过应用目录页面安装NodeLocal DNSCache,您可以先卸载NodeLocal DNSCache,再重新安装。具体操作,请参见卸载NodeLocal DNSCache和安装NodeLocal DNSCache。
卸载NodeLocal DNSCache
如果您是在组件管理页面安装NodeLocal DNSCache,您需要在组件管理页面卸载NodeLocal DNSCache。如果您是在应用目录页面安装NodeLocal DNSCache,您需要在Helm页面卸载NodeLocal DNSCache。
通过组件管理页面卸载NodeLocal DNSCache
登录容器服务管理控制台,在左侧导航栏选择集群。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择 。
在组件管理页面单击NodeLocal DNSCache下的卸载,在弹出的对话框中单击确定。
说明卸载后所有解析流量会请求至CoreDNS,建议提前对CoreDNS副本数进行扩容。
通过应用目录页面卸载NodeLocal DNSCache
卸载前检查。
登录容器服务管理控制台,在左侧导航栏选择集群。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择 。
在Helm页面单击ack-node-local-dns-default。
单击参数配置页签,检查参数。
如果本地监听IP地址(local_dns_ip)等同于kube-dns的ClusterIP地址,则您可以执行步骤2卸载NodeLocal DNSCache。
如果高可用开关(high_availability)为打开状态,且本地监听IP地址(local_dns_ip)为169.254.20.10。则您可以执行步骤2卸载NodeLocal DNSCache。
如果参数不满足以上条件,请按照以下流程进行卸载:
执行
kubectl get ns -o yaml
命令,检查哪些命名空间被打上了node-local-dns-injection=enabled的标签,并将标签删除。执行
kubectl get pod -o yaml
命令,检查哪些业务Pod被注入DNSConfig,删除这些Pod并重建。执行步骤2卸载NodeLocal DNSCache。
卸载NodeLocal DNSCache。
在控制台左侧导航栏,单击集群。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择 。
在Helm页面单击ack-node-local-dns-default操作列的删除,在弹出的对话框中选中清除发布记录,然后单击确定。
修改Terway配置
执行以下命令,查看Terway配置文件。
kubectl -n kube-system edit cm eni-config -o yaml
检查Terway配置文件。
检查配置文件中
eniip_virtual_type
字段是否开启IPVLAN模式。如果配置文件中此项不存在或不是IPVLAN,则您不需要按后续步骤进行配置,可以直接安装NodeLocal DNSCache。具体操作,请参见安装NodeLocal DNSCache。检查配置文件中是否已配置
host_stack_cidrs
字段。如果配置文件中已配置host_stack_cidrs
字段,则您不需要按后续步骤进行配置,可以直接安装NodeLocal DNSCache。具体操作,请参见安装NodeLocal DNSCache。
在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 pod | grep terway-eniip
预期输出:
terway-eniip-7**** 2/2 Running 0 30m terway-eniip-s**** 2/2 Running 0 30m
执行以下命令,触发Terway容器组重建。
kubectl -n kube-system delete pod terway-eniip-7**** terway-eniip-s****
登录任意集群节点,执行以下命令,查看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了。