距离上一次更新该文章已经过了 519 天,文章所描述的內容可能已经发生变化,请留意。
参看此篇章前可先查看记录一次k3s网络DNS问题排查
篇
参考:
https://v1-24.docs.kubernetes.io/zh-cn/docs/tasks/administer-cluster/nodelocaldns/
https://www.suse.com/support/kb/doc/?id=000020174
https://stackoverflow.com/questions/70913822/kubernetes-k3s-pod-gets-enotfound-after-5-20-hours-of-airing-time
https://icode.best/i/10017745505921
https://hub.docker.com/r/dyrnq/k8s-dns-node-cache/tags
https://github.com/coredns/deployment/blob/master/kubernetes/Scaling_CoreDNS.md
https://lework.github.io/2020/11/09/node-local-dns/
简介 NodeLocal DNSCache
通过在集群节点上运行一个 DaemonSet 来提高 clusterDNS 性能和可靠性。处于 ClusterFirst
的 DNS 模式下的 Pod 可以连接到 kube-dns
的 serviceIP 进行 DNS 查询。通过 kube-proxy
组件添加的 iptables
规则将其转换为 CoreDNS
端点。
通过在每个集群节点上运行 DNS 缓存,NodeLocal DNSCache 可以缩短 DNS 查找的延迟时间、使 DNS 查找时间更加一致,以及减少发送到 kube-dns 的 DNS 查询次数。
在集群中运行 NodeLocal DNSCache 有如下几个好处:
如果本地没有 CoreDNS 实例,则具有最高 DNS QPS 的 Pod 可能必须到另一个节点进行解析,使用 NodeLocal DNSCache 后,拥有本地缓存将有助于改善延迟 跳过 iptables DNAT 和连接跟踪将有助于减少 conntrack
竞争并避免 UDP DNS 条目填满 conntrack
表(常见的5s超时问题就是这个原因造成的) 从本地缓存代理到 kube-dns 服务的连接可以升级到 TCP,TCP conntrack 条目将在连接关闭时被删除,而 UDP 条目必须超时(默认 nf_conntrack_udp_timeout 是 30 秒 ) 将 DNS 查询从 UDP 升级到 TCP 将减少归因于丢弃的 UDP 数据包和 DNS 超时的尾部等待时间,通常长达 30 秒(3 次重试+ 10 秒超时) 要安装 NodeLocal DNSCache 也非常简单,直接获取官方的资源清单即可:
1 $ wget https://github.com/kubernetes/kubernetes/raw/master/cluster/addons/dns/nodelocaldns/nodelocaldns.yaml
该资源清单文件中包含几个变量,其中:
__PILLAR__DNS__SERVER__
:表示 kube-dns
这个 Service 的 ClusterIP,可以通过命令 kubectl get service --namespace kube-system kube-dns -o jsonpath='{.spec.clusterIP}'
获取__PILLAR__LOCAL__DNS__
:表示 DNSCache 本地的 IP,默认为 169.254.20.10
,该地址可以是任何地址,只要该地址不和你的集群里现有的 IP 地址发生冲突。 推荐使用本地范围内的地址,例如 IPv4 链路本地区段 169.254.0.0/16 内的地址(默认一般取 169.254.20.10 即可 )__PILLAR__DNS__DOMAIN__
:表示集群域,默认就是 cluster.local
部署 kube-proxy为iptables模式 另外还有两个参数 __PILLAR__CLUSTER__DNS__
和 __PILLAR__UPSTREAM__SERVERS__
,镜像 1.15.6
版本以上这两个参数会自动进行配置,对应的值来源于 kube-dns 的 ConfigMap 和定制的 Upstream Server 配置。直接执行如下所示的命令即可安装:
registry.k8s.io
墙内可能下载不下来, 所以可以选择将其替换成docker源dyrnq
地址: https://hub.docker.com/r/dyrnq/k8s-dns-node-cache/tags
1 2 3 4 5 6 cat nodelocaldns.yaml \| sed -e "s/registry.k8s.io\/dns/dyrnq/g" \ | sed -e "s/__PILLAR__DNS__DOMAIN__/cluster.local/g" \ | sed -e "s/__PILLAR__DNS__SERVER__/$(kubectl get service --namespace kube-system kube-dns -o jsonpath='{.spec.clusterIP}') /g" \ | sed -e "s/__PILLAR__LOCAL__DNS__/169.254.20.10/g" \ | kubectl apply -f -
可以通过如下命令来查看对应的 Pod 是否已经启动成功:
1 2 3 4 5 6 7 $ kubectl get pods -n kube-system | grep node-local-dns node-local-dns-8zm2f 1/1 Running 0 9m54s node-local-dns-dd4xg 1/1 Running 0 9m54s node-local-dns-hs8qq 1/1 Running 0 9m54s node-local-dns-pxfxn 1/1 Running 0 9m54s node-local-dns-stjm9 1/1 Running 0 9m54s node-local-dns-wjxvz 1/1 Running 0 9m54s
iptables
模式下 Pod 还是向原来的集群 DNS 请求,节点上有这个 IP 监听,会被本机拦截,再请求集群上游 DNS,所以不需要更改 --cluster-dns
参数。
需要注意的是这里使用 DaemonSet 部署 node-local-dns 使用了 hostNetwork=true
,会占用宿主机的 8080 端口,所以需要保证该端口未被占用。
kube-proxy为ipvs模式 当kube-proxy为ipvs模式, 则需要进行如下调整
1 2 3 4 5 6 cat nodelocaldns.yaml \| sed -e "s/registry.k8s.io\/dns/dyrnq/g" \ | sed -e "s/,__PILLAR__DNS__SERVER__//g" \ | sed -e "s/__PILLAR__DNS__SERVER__/$(kubectl get service --namespace kube-system kube-dns -o jsonpath='{.spec.clusterIP}') /g" \ | sed -e "s/__PILLAR__LOCAL__DNS__/169.254.20.10/g" \ | kubectl apply -f -
在此模式下,node-local-dns Pods 只会侦听 <node-local-address>
的地址。 node-local-dns 接口不能绑定 kube-dns 的集群 IP 地址,因为 IPVS 负载均衡 使用的接口已经占用了该地址。 node-local-dns Pods 会设置 __PILLAR__UPSTREAM__SERVERS__
。
我们还需要修改 kubelet 的 --cluster-dns
参数,将其指向 169.254.20.10
,Daemonset 会在每个节点创建一个网卡来绑这个 IP,Pod 向本节点这个 IP 发 DNS 请求,缓存没有命中的时候才会再代理到上游集群 DNS 进行查询。
**关于 iptables
模式为什么不需要修改--cluster-dns
**:Daemonset 会在每个节点创建一个网卡来绑这个 IP,Pod 向本节点这个 IP 发 DNS 请求,缓存没有命中的时候才会再代理到上游集群 DNS 进行查询。 iptables
模式下 Pod 还是向原来的集群 DNS 请求,节点上有这个 IP 监听,会被本机拦截,再请求集群上游 DNS,所以不需要更改 --cluster-dns
参数。
使用 如果希望使用上node-local-dns的解析,有两种设置方式:
单独配置 Pod 的 dnsconfig
配置 kubelet的 cluster-dns
单独配置 Pod 的 dnsconfig
使用此方法,仅针对某个pod设置,不影响其他组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 apiVersion: v1 kind: Pod metadata: name: test-node-local-dns spec: containers: - name: local-dns image: busybox:glibc command: ["/bin/sh" , "-c" , "sleep 60m" ] dnsPolicy: "None" dnsConfig: nameservers: - 169.254 .20 .10 searches: - default.svc.cluster.local - svc.cluster.local - cluster.local options: - name: ndots value: "2"
配置 kubelet 的 cluster-dns
使用此方法,生效的对象则是kubelet所管理的所有pod,但需要重启 kubelet
如果使用的是 kubeadm 安装的 1.16 版本的集群,只需要替换节点上 /var/lib/kubelet/config.yaml
文件中的 clusterDNS
这个参数值,然后重启即可 ,我们也可以完全在官方的 DaemonSet 资源对象中添加一个 initContainer 来完成这个工作:
替换10.96.0.10
为$(kubectl get service --namespace kube-system kube-dns -o jsonpath='{.spec.clusterIP}')
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 initContainers: - name: setup image: alpine tty: true stdin: true securityContext: privileged: true command: - nsenter - --target - "1" - --mount - --uts - --ipc - --net - --pid - -- - bash - -c - | # 确保 kubelet --cluster-dns 被设置为 169.254.20.10 echo "Configuring kubelet --cluster-dns=169.254.20.10" sed -i 's/10.96.0.10/169.254.20.10/g' /var/lib/kubelet/config.yaml systemctl daemon-reload && systemctl restart kubelet
但是需要注意的是对于线上环境还是不推荐用上面的方式,因为它会优先将 kubelet 的 cluster-dns
参数进行修改,然后再去安装 NodeLocal
,这中间毕竟有一段真空期,我们完全可以手动去一个节点一个节点验证:
1 2 $ sed -i 's/10.96.0.10/169.254.20.10/g' /var/lib/kubelet/config.yaml $ systemctl daemon-reload && systemctl restart kubelet
验证 Iptables OUTPUT 链 iptables 有一个 OUTPUT 链,用于将发往我们的 CoreDNS 集群服务 IP 的 DNS 请求路由到分配给 localdns 变量的 IP
使用如下命令进行查看iptables -nL OUTPUT
1 2 3 4 5 6 7 8 9 Chain OUTPUT (policy ACCEPT) target prot opt source destination KUBE-ROUTER-OUTPUT all -- 0.0.0.0/0 0.0.0.0/0 /* kube-router netpol - VEAAIY32XVBHCSCY */ KUBE-SERVICES all -- 0.0.0.0/0 0.0.0.0/0 ctstate NEW /* kubernetes service portals */ KUBE-FIREWALL all -- 0.0.0.0/0 0.0.0.0/0 ACCEPT udp -- 10.43.0.10 0.0.0.0/0 udp spt:53 ACCEPT tcp -- 10.43.0.10 0.0.0.0/0 tcp spt:53 ACCEPT udp -- 169.254.20.10 0.0.0.0/0 udp spt:53 ACCEPT tcp -- 169.254.20.10 0.0.0.0/0 tcp spt:53
查询本地缓存实例:
$dig +short @169.254.20.10 prefetch.net
$dig +short @169.254.20.10 prefetch.net
以上会得到相同的结果。但是检查日志,第一个请求会到达本地缓存服务器,然后被转发到主 CoreDNS 服务 IP。当第二个查询进来时,缓存的条目将返回给请求者,从而减少主 CoreDNS 服务器的负载。如果 pod 配置为指向上游 CoreDNS 服务器,iptables 将确保查询命中本地 DNS 缓存。
创建pod并测试解析 创建测试pod 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 apiVersion: v1 kind: Pod metadata: name: test-node-local-dns spec: containers: - name: local-dns image: busybox:glibc command: ["/bin/sh" , "-c" , "sleep 60m" ] dnsPolicy: "None" dnsConfig: nameservers: - 169.254 .20 .10 searches: - default.svc.cluster.local - svc.cluster.local - cluster.local options: - name: ndots value: "2" EOF
注意: busybox 的 新版本 uclibc 中的nslookup 有问题,请使用 glibc 。
待 pod 启动后,查看 /etc/resolv.conf
1 2 3 4 # kubectl exec test-node-local-dns -- cat /etc/resolv.conf nameserver 169.254.20.10 search default.svc.cluster.local svc.cluster.local cluster.local options ndots:2
在 pod 的节点上,监听 53 端口 我这里是 k8s-worker-node2
节点,可以通过kubectl get pods test-node-local-dns -o jsonpath='{$.spec.nodeName}'
获取
1 2 3 # yum install tcpdump -y # tcpdump -i any src host 169.254.20.10 and port 53 -vv tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
在 pod 中查询 外部域名 A 记录 1 2 3 4 5 6 7 8 9 10 11 12 13 # kubectl exec test-node-local-dns -- nslookup www.baidu.com Server: 169.254.20.10 Address: 169.254.20.10:53 Non-authoritative answer: www.baidu.com canonical name = www.a.shifen.com Non-authoritative answer: www.baidu.com canonical name = www.a.shifen.com Name: www.a.shifen.com Address: 180.101.49.12 Name: www.a.shifen.com Address: 180.101.49.11
正常返回,没有问题。
在 pod 的节点上,观察 tcpdump 接收到的信息 1 2 3 4 5 6 7 k8s-worker-node2.domain > 10.244.4.24.38514: [bad udp cksum 0xcd77 -> 0x112f!] 41730 q: AAAA? www.baidu.com. 1/0/0 www.baidu.com. CNAME www.a.shifen.com. (74) 8:03.164521 IP (tos 0x0, ttl 64, id 33106, offset 0, flags [DF], proto UDP (17), length 102) k8s-worker-node2.domain > 10.244.4.24.38514: [bad udp cksum 0xcd77 -> 0x112f!] 41730 q: AAAA? www.baidu.com. 1/0/0 www.baidu.com. CNAME www.a.shifen.com. (74) 8:03.164646 IP (tos 0x0, ttl 64, id 33107, offset 0, flags [DF], proto UDP (17), length 166) k8s-worker-node2.domain > 10.244.4.24.38514: [bad udp cksum 0xcdb7 -> 0x60ed!] 33472 q: A? www.baidu.com. 3/0/0 www.baidu.com. CNAME www.a.shifen.com., www.a.shifen.com. A 180.101.49.12, www.a.shifen.com. A 180.101.49.11 (138) 8:03.164649 IP (tos 0x0, ttl 64, id 33107, offset 0, flags [DF], proto UDP (17), length 166) k8s-worker-node2.domain > 10.244.4.24.38514: [bad udp cksum 0xcdb7 -> 0x60ed!] 33472 q: A? www.baidu.com. 3/0/0 www.baidu.com. CNAME www.a.shifen.com., www.a.shifen.com. A 180.101.49.12, www.a.shifen.com. A 180.101.49.11 (138)
到这里就说明NodeLocal DNSCache 组件部署成功了,但是域名解析我们还是要多测试测试。
测试 service 域名解析 1 2 3 4 5 6 7 8 9 10 11 12 # kubectl exec test-node-local-dns -- nslookup -type =a kubernetes Server: 169.254.20.10 Address: 169.254.20.10:53 ** server can't find kubernetes.cluster.local: NXDOMAIN ** server can't find kubernetes.svc.cluster.local: NXDOMAIN Name: kubernetes.default.svc.cluster.local Address: 10.96.0.1 command terminated with exit code 1
因为使用了相对域名,使用搜索域,进行了所有域的查询操作。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 Server: 169.254 .20 .10 Address: 169.254 .20 .10 :53 ** server can't find kubernetes.: SERVFAIL command terminated with exit code 1 [root@k8s-master-node1 ~ ] Server: 169.254 .20 .10 Address: 169.254 .20 .10 :53 ** server can't find kubernetes.default: NXDOMAIN command terminated with exit code 1 [root@k8s-master-node1 ~ ] Server: 169.254 .20 .10 Address: 169.254 .20 .10 :53 Name: kubernetes.default.svc.cluster.local Address: 10.96 .0 .1
ExternalName Service 解析 ExternalName Service 是 Service 的一个特例,没有选择器,可以用于给外部服务取一个内部别名。
创建 ExternalName Service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 apiVersion: v1 kind: Service metadata: name: baidu namespace: default spec: type: ExternalName externalName: www.baidu.com EOF Name: baidu Namespace: default Labels: <none> Annotations: <none> Selector: <none> Type: ExternalName IP: External Name: www.baidu.com Session Affinity: None Events: <none>
测试解析内部服务 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 # kubectl exec test-node-local-dns -- nslookup baidu Server: 169.254.20.10 Address: 169.254.20.10:53 ** server can't find baidu.cluster.local: NXDOMAIN baidu.default.svc.cluster.local canonical name = www.baidu.com www.baidu.com canonical name = www.a.shifen.com Name: www.a.shifen.com Address: 180.101.49.12 Name: www.a.shifen.com Address: 180.101.49.11 baidu.default.svc.cluster.local canonical name = www.baidu.com www.baidu.com canonical name = www.a.shifen.com ** server can't find baidu.svc.cluster.local: NXDOMAIN ** server can't find baidu.svc.cluster.local: NXDOMAIN ** server can't find baidu.cluster.local: NXDOMAIN command terminated with exit code 1
baidu.default.svc.cluster.local 将会被映射到 www.baidu.com , 这是通过 DNS 的 CNAME 记录实现的。
压测 使用 dnsperf 项目进行 dns 查询压力测试
创建pod 1 2 3 4 5 6 7 8 9 10 11 12 cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: perf-node-dns spec: containers: - name: perf-node-dns image: guessi/dnsperf:alpine command: ["/bin/sh" , "-c" , "sleep 60m" ] dnsPolicy: "None" EOF
测试coredns的性能 coredns 在集群中默认是2个节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 # kubectl exec -ti perf-node-local-dns -- sh cat <<EOF >records.txt baidu.com A www.baidu.com A mail.baidu.com A github.com A www.yahoo.com A www.microsoft.com A www.aliyun.com A developer.aliyun.com A kubernetes.io A kubernetes A kubernetes.default.svc.cluster.local A kube-dns.kube-system.svc.cluster.local A EOF / # dnsperf -l 60 -s 10.96.0.10 -Q 100000 -d records.txt DNS Performance Testing Tool Version 2.2.1 [Status] Command line: dnsperf -l 60 -s 10.96.0.10 -Q 100000 -d records.txt [Status] Sending queries (to 10.96.0.10) [Status] Started at: Tue Nov 10 05:00:35 2020 [Status] Stopping after 60.000000 seconds [Status] Testing complete (time limit) Statistics: Queries sent: 835613 Queries completed: 835613 (100.00%) Queries lost: 0 (0.00%) Response codes: NOERROR 765979 (91.67%), SERVFAIL 69634 (8.33%) Average packet size: request 35, response 163 Run time (s): 60.005840 Queries per second: 13925.527915 Average Latency (s): 0.005713 (min 0.000170, max 0.067250) Latency StdDev (s): 0.003657
dnsperf 参数 -l 60
: 测试 60s-s 10.96.0.10
: dns 服务器-Q 100000
: 最高qps-d records.txt
: 查询的列表在 Statistics 区域中,我们可以看到发送查询835613 ,查询完成度**100%**,qps 为 13925.527915 。 返回码有SERVFAIL 是因为 kubernetes 域名查询的错误。
测试使用NodeLocal DNSCache 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 / # dnsperf -l 60 -s 169.254.20.10 -Q 100000 -d records.txt DNS Performance Testing Tool Version 2.2.1 [Status] Command line: dnsperf -l 60 -s 169.254.20.10 -Q 100000 -d records.txt [Status] Sending queries (to 169.254.20.10) [Status] Started at: Tue Nov 10 05:08:16 2020 [Status] Stopping after 60.000000 seconds [Status] Testing complete (time limit) Statistics: Queries sent: 1515112 Queries completed: 1515112 (100.00%) Queries lost: 0 (0.00%) Response codes: NOERROR 1388853 (91.67%), SERVFAIL 126259 (8.33%) Average packet size: request 35, response 163 Run time (s): 60.010329 Queries per second: 25247.520306 Average Latency (s): 0.003299 (min 0.000035, max 0.052578) Latency StdDev (s): 0.002136
在 Statistics 区域中,我们可以看到发送查询1515112 ,查询完成度**100%**,qps 为 25247.520306 。 其性能比使用coredns提升了55%
左右。
高可用 NodeLocal DNS Cache 并没有高可用性的特征,但是我们通过设置DaemonSet的属性,可以提高本地 dns缓存服务的稳定性。
在常规的pod终止过程中,pod会删除dummy interface
& iptables
规则。这样就会将流量从自身切换到集群中运行的常规 kube-dns
pod上。但是如果我们强行杀死 pod,将不会去除 iptable 规则,这样就会破坏该节点的所有DNS流量,因为nodelocaldns接口上没有任何应用在监听。
为了避免这个不必要的麻烦,默认的 DaemonSet 没有设置内存/CPU限制。我建议你保持这种方式,以避免内存终止或任何CPU节流。另外pods被标记为 system-node-critical
优先级,这使得nodelocaldns几乎可以保证在节点资源耗尽的情况下,首先被调度,不太可能被驱逐。
如果你想安全起见,建议把DaemonSet更新策略改为OnDelete
,并通过排空Kubernetes节点来进行维护/升级,排空成功后逐一删除Node Local DNS pods。
在pod中,增加一个备用nameserver
,也就是我们的 kube-dns
的 cluster ip,从而在 node-local-dns 不可用的情况下,能使用集群中的dns服务解析域名,保障服务不中断业务。
故障演练 模拟 node-local-dns
pod 意外宕机
进入测试pod容器中 1 2 3 4 5 6 # kubectl exec -ti test-node-local-dns -- sh / # cat /etc/resolv.conf nameserver 169.254.20.10 search default.svc.cluster.local svc.cluster.local cluster.local options ndots:2 / #
定时查询解析 1 / # while true; do date; nslookup -type=a www.baidu.com; sleep 0.5; done
在测试pod节点上kill掉node-local-dns
pod 1 2 # docker kill $(docker ps | grep node-cache_node-local-dns | awk '{print $1}' ) 939d90728c43
在测试pod容器中,查看解析情况
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 Wed Nov 11 03:43:55 UTC 2020 Server: 169.254.20.10 Address: 169.254.20.10:53 Non-authoritative answer: www.baidu.com canonical name = www.a.shifen.com Name: www.a.shifen.com Address: 180.101.49.11 Name: www.a.shifen.com Address: 180.101.49.12 ...... Wed Nov 11 03:43:58 UTC 2020 Server: 169.254.20.10 Address: 169.254.20.10:53 www.baidu.com canonical name = www.a.shifen.com Name: www.a.shifen.com Address: 180.101.49.11 Name: www.a.shifen.com Address: 180.101.49.12 Wed Nov 11 03:43:59 UTC 2020 nslookup: read: Connection refused nslookup: read: Connection refused ;; connection timed out; no servers could be reached ...... Wed Nov 11 03:46:39 UTC 2020 nslookup: read: Connection refused nslookup: read: Connection refused ;; connection timed out; no servers could be reached Wed Nov 11 03:46:44 UTC 2020 Server: 169.254.20.10 Address: 169.254.20.10:53 Non-authoritative answer: www.baidu.com canonical name = www.a.shifen.com Name: www.a.shifen.com Address: 180.101.49.11 Name: www.a.shifen.com Address: 180.101.49.12 Wed Nov 11 03:46:45 UTC 2020 Server: 169.254.20.10 Address: 169.254.20.10:53 www.baidu.com canonical name = www.a.shifen.com Name: www.a.shifen.com Address: 180.101.49.11 Name: www.a.shifen.com Address: 180.101.49.12
解析日志做了缩减处理。
从上列日志中可以看到,在Wed Nov 11 03:43:59 UTC 2020
到 Wed Nov 11 03:46:44 UTC 2020
时间内,解析域名是不成功的,也就意味着近4分钟内应用是无法连接外网的。node-local-dns pod 在此时间内完成了重建,后续解析才能够成功。
对于这种情况,我们可以增加一个备用nameserver
,也就是我们的 kube-dns
的 cluster,从而在 node-local-dns 不可用的情况下,能使用集群中的dns服务。
添加备用 nameserver 1 2 3 4 5 6 / # cat /etc/resolv.conf nameserver 169.254.20.10 nameserver 10.96.0.10 search default.svc.cluster.local svc.cluster.local cluster.local options ndots:2 options timeout:2
定时查询解析 1 / # while true; do date; nslookup -type=a www.baidu.com; sleep 0.5; done
在测试pod节点上kill掉 node-local-dns
pod 1 2 # docker kill $(docker ps | grep node-cache_node-local-dns | awk '{print $1}' ) eaf8e75858e0
在测试pod容器中,查看解析情况
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 Wed Nov 11 04:36:58 UTC 2020 Server: 169.254.20.10 Address: 169.254.20.10:53 www.baidu.com canonical name = www.a.shifen.com Name: www.a.shifen.com Address: 180.101.49.12 Name: www.a.shifen.com Address: 180.101.49.11 ...... Wed Nov 11 04:36:59 UTC 2020 nslookup: read: Connection refused nslookup: read: Connection refused Server: 10.96.0.10 Address: 10.96.0.10:53 Non-authoritative answer: www.baidu.com canonical name = www.a.shifen.com Name: www.a.shifen.com Address: 180.101.49.12 Name: www.a.shifen.com Address: 180.101.49.11 ...... Wed Nov 11 04:37:10 UTC 2020 nslookup: read: Connection refused nslookup: read: Connection refused Server: 10.96.0.10 Address: 10.96.0.10:53 Non-authoritative answer: www.baidu.com canonical name = www.a.shifen.com Name: www.a.shifen.com Address: 180.101.49.12 Name: www.a.shifen.com Address: 180.101.49.11 Wed Nov 11 04:37:16 UTC 2020 Server: 169.254.20.10 Address: 169.254.20.10:53 Non-authoritative answer: www.baidu.com canonical name = www.a.shifen.com Name: www.a.shifen.com Address: 180.101.49.12 Name: www.a.shifen.com Address: 180.101.49.11
解析日志做了缩减处理。
从上列日志中可以看到,在Wed Nov 11 04:36:59 UTC 2020
到 Wed Nov 11 04:37:16 UTC 2020
时间内,169.254.20.10
本地dns 解析域名是不成功的,经过重试 10.96.0.10
集群dns获得了域名A记录。这样就能保障在本地dns出现故障时,可以使用集群dns接替解析任务,从而使业务不中断。