操作场景
通过在集群节点上以 Daemonset 的形式运行 NodeLocal DNS Cache,能够大幅提升集群内 DNS 解析性能,以及有效避免 conntrack 冲突引发的 DNS 五秒延迟。
操作原理
通过 DaemonSet 在集群的每个节点上部署一个 hostNetwork 的 Pod,该 Pod 是 node-cache,可以缓存本节点上 Pod 的 DNS 请求。如果存在 cache misses ,该 Pod 将会通过 TCP 请求上游 kube-dns 服务进行获取。原理图如下所示:
NodeLocal DNS Cache 没有高可用性(High Availability,HA),会存在单点 nodelocal dns cache 故障(Pod Evicted/ OOMKilled/ConfigMap error/DaemonSet Upgrade),但是该现象其实是任何的单点代理(例如 kube-proxy,cni pod)都会存在的常见故障问题。
<!--more-->
前提条件
创建了 Kubernetes 版本为 1.15 及以上的集群,且该集群中存在节点。
操作步骤
wget -O nodelocaldns.yaml "https://github.com/kubernetes/kubernetes/raw/master/cluster/addons/dns/nodelocaldns/nodelocaldns.yaml"
该资源清单文件中包含几个变量,其中:
__PILLAR__DNS__SERVER__
:表示kube-dns
这个 Service 的 ClusterIP,可以通过命令kubectl get svc -n kube-system | grep kube-dns | awk '{ print $3 }'
获取__PILLAR__LOCAL__DNS__
:表示 DNSCache 本地的 IP,默认为 169.254.20.10__PILLAR__DNS__DOMAIN__
:表示集群域,默认就是cluster.local
修改相关配置
sed -i 's/k8s.gcr.io/harbor.emarbox.com/g' nodelocaldns.yaml && \ sed -i 's/__PILLAR__DNS__SERVER__/10.96.0.10/g' nodelocaldns.yaml && \ sed -i 's/__PILLAR__LOCAL__DNS__/169.254.20.10/g' nodelocaldns.yaml && \ sed -i 's/__PILLAR__DNS__DOMAIN__/cluster.local/g' nodelocaldns.yaml
查看是否安装成功
$ kubectl get pods -n kube-system | grep node-local-dns node-local-dns-658t4 1/1 Running 0 19s node-local-dns-6bsjv 1/1 Running 0 19s node-local-dns-wcxpw 1/1 Running 0 19s
需要注意的是这里使用 DaemonSet 部署 node-local-dns 使用了
hostNetwork=true,会占用宿主机的 8080 端口,所以需要保证该端口未被占用。或者你自己修改 health 169.254.20.10:8080
修改配置,启用dns cache
本文提供以下两种配置方法,请根据实际情况进行选择:
如果 kube-proxy 组件使用的是 ipvs 模式的话我们还需要修改 kubelet 的
--cluster-dns参数,将其指向169.254.20.10,Daemonset 会在每个节点创建一个网卡来绑这个 IP,Pod 向本节点这个 IP 发 DNS 请求,缓存没有命中的时候才会再代理到上游集群 DNS 进行查询。iptables模式下 Pod 还是向原来的集群 DNS 请求,节点上有这个 IP 监听,会被本机拦截,再请求集群上游 DNS,所以不需要更改--cluster-dns参数。
- 依次执行以下命令,修改 kubelet 启动参数并重启。
sed -i 's/10.96.0.10/169.254.20.10/g' /var/lib/kubelet/config.yaml systemctl restart kubelet
- 根据需求配置单个 Pod 的 dnsconfig 后重启。YAML 核心部分参考如下:
- 需要将 nameserver 配置为169.254.20.10。
- 为确保集群内部域名能够被正常解析,需要配置 searches。
- 适当降低 ndots 值有利于加速集群外部域名访问。
- 当 Pod 没有使用带有多个 dots 的集群内部域名的情况下,建议将值设为2
dnsConfig: nameservers: ["169.254.20.10"] searches: - default.svc.cluster.local - svc.cluster.local - cluster.local options: - name: ndots value: "2"
验证
待
node-local-dns安装配置完成后,我们可以部署一个新的 Pod 来验证下:(test-node-local-dns.yaml)
apiVersion: v1 kind: Pod metadata: name: test-node-local-dns spec: containers: - name: local-dns image: busybox command: ["/bin/sh", "-c", "sleep 60m"] dnsConfig: nameservers: ["169.254.20.10"] searches: - default.svc.cluster.local - svc.cluster.local - cluster.local options: - name: ndots value: "2"
直接部署:
$ kubectl apply -f test-node-local-dns.yaml $ kubectl exec -it test-node-local-dns /bin/sh / # cat /etc/resolv.conf nameserver 169.254.20.10 search default.svc.cluster.local svc.cluster.local cluster.local options ndots:5
我们可以看到
nameserver已经变成
169.254.20.10了,当然对于之前的历史 Pod 要想使用
node-local-dns则需要重建,当然如果要想去跟踪 DNS 的解析过程的话可以去通过抓包来观察。
相关文章推荐
- Coredns+Nodelocaldns cache解决Coredns域名解析延迟
- 浅析Node.js:DNS模块的使用
- java.net.UnknownHostException: promote.cache-dns.local: unknown error
- node.js中的dns.getServers方法使用说明
- Node.js:DNS模块的使用
- 【Cocos2dx 3.3 Lua】SpriteBatchNode和SpriteFrameCache使用
- Using a local cache for pip packages[pip使用本地cache安装包]
- 浅析Node.js:DNS模块的使用
- node.js中的dns.getServers方法使用说明
- 详解使用 Node.js 开发简单的脚手架工具
- Spring配置文件中使用ref local与ref bean的区别.
- node.js使用express框架进行文件上传详解
- 使用bind9 的rndc 控制dns
- 在Node.js应用中使用Redis的方法简介
- node.js中的url.resolve方法使用说明
- RabbitMQ学习之:(十二)在Node.js环境下使用RabbitMQ
- 教你如何在Node.js中使用jQuery
- Oracle数据库动态注册和参数local_listener使用
- BOOST:使用local_date_time 计算当前时间戳
- teb_local_planner安装及使用