在集群中部署NodeLocal DNSCache可以提升服务发现的稳定性和性能,NodeLocal DNSCache通过在集群节点运行DNS缓存代理来提高集群DNS性能。
本文介绍如何安装NodeLocal DNSCache,并在应用中使用NodeLocal DNSCache。
NodeLocal DNSCache简介
云容器引擎NodeLocal DNSCache插件是基于社区开源项目NodeLocal DNSCache的一套DNS本地缓存解决方案,该方案主要由DNS本地缓存和DNSConfig动态注入控制器组成:
- DNSConfig动态注入控制器,基于Admission Webhook机制拦截Pod创建的请求,自动注入使用DNS缓存的Pod DNSConfig配置;
- DNS缓存代理,在每个集群节点上创建一个虚拟网络接口(默认监听IP 169.254.20.10),配合Pod的DNSConfig和节点上的网络配置,Pod内产生的DNS请求会被该服务所代理。
工作原理图如下图所示:
说明1、已注入DNS本地缓存的Pod,默认会通过NodeLocal DNSCache的服务地址(169.254.20.10)解析域名;
2、NodeLocal DNSCache本地若无缓存应答解析请求,则将请求转发到CoreDNS进行解析;
3、CoreDNS对于非集群内域名,会通过节点配置的DNS服务进行解析;
4、已注入DNS本地缓存的Pod,当无法连通NodeLocal DNSCache时,会继续通过CoreDNS进行解析,此链路为备用链路;
5、未注入DNS本地缓存的Pod,会通过CoreDNS进行解析。
安装NodeLocal DNSCache
可在云容器引擎控制台安装NodeLocal DNSCache插件,步骤请参考安装插件。
Pod使用NodeLocal DNSCache
Pod需调整resolv.conf的nameservers配置,以将原本请求CoreDNS改为请求DNS缓存代理,有如下几种方式可以配置:
- 借助DNSConfig动态注入控制器在Pod创建时配置DNSConfig自动注入,推荐使用此方式;
- 创建Pod时手动指定DNSConfig;
- 修改kubelet参数,并重启节点kubelet。
注意第三种存在业务中断风险,不推荐使用此方式。
配置DNSConfig自动注入
DNSConfig动态注入控制器可用于自动注入DNSConfig至新建的Pod中,无需手工配置Pod YAML进行注入。该控制器默认会监听包含node-local-dns-injection=enabled标签的命名空间中新建Pod的请求,可以通过以下命令给命名空间打上该标签:
kubectl label namespace default node-local-dns-injection=enabled
开启自动注入后,后续新创建的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缓存服务地址,请检查Pod是否满足以下条件:
- 新建Pod不位于kube-system和kube-public命名空间;
- 新建Pod所在命名空间的Labels标签包含node-local-dns-injection=enabled;
- 新建Pod所在命名空间的Labels不包含ECI Pod相关标签,例如virtual-node-affinity-injection、eci等,或打上禁用DNS注入node-local-dns-injection=disabled标签;
- 新建Pod的网络为hostNetwork且DNSPolicy为ClusterFirstWithHostNet,或Pod为非hostNetwork且DNSPolicy为ClusterFirst。
手动指定DNSConfig
可以通过修改Pod进行手动指定DNSConfig,示例配置如下:
apiVersion: v1
kind: Pod
metadata:
name: nginx-demo
namespace: default
spec:
containers:
- image: registry-vpc-gzsyj.crs.ctyun.cn:30015/library/nginx-photon:v1.8.6
name: demo
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"
说明1、dnsPolicy:必须为None;
2、nameservers:配置成169.254.20.10和kube-dns的ClusterIP对应的IP地址;
3、searches:设置搜索域,保证集群内部域名能够被正常解析;
4、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重启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。
配置Pod使用NodeLocal DNSCache示例
通过在default命名空间下部署示例应用,演示如何配置应用使用NodeLocal DNSCache.执行以下命令,给接入NodeLocal DNSCache的应用所在的命名空间(default)设置标签:
kubectl label namespace default node-local-dns-injection=enabled
在集群的default命名空间下部署示例应用:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-demo
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: nginx-demo
template:
metadata:
labels:
app: nginx-demo
spec:
containers:
- image: registry-vpc-gzsyj.crs.ctyun.cn:30015/library/nginx-photon:v2.5.3
name: demo
查看创建的Pods:
# kubectl get po -l app=nginx-demo
NAME READY STATUS RESTARTS AGE
nginx-demo-748fb499d7-2xtd8 1/1 Running 0 4s
nginx-demo-748fb499d7-q84dc 1/1 Running 0 4s
执行以下命令,查看Pod的dnsConfig是否已经接入NodeLocal DNSCache:
kubectl get pod nginx-demo-748fb499d7-2xtd8 -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