CoreDNS不断重启问题排查

问题概述

客户反馈CoreDNS不断报错重启,pod报错日志如下:

1
2
3
4
5
.:53
[INFO] plugin/reload: Running configuration MD5 = 801a899438c9341e1de6cf893d986920
CoreDNS-1.6.9
linux/amd64, go1.14.1, 1766568
[FATAL] plugin/loop: Loop (127.0.0.1:40650 -> :53) detected for zone ".", see https://coredns.io/plugins/loop#troubleshooting. Query: "HINFO 5862268011232388643.388723831076506841."

log-1

问题原因

根据报错我们可以看到,coredns抛出了一个致命的日志,coredns的loop插件检测到上游DNS服务器的无限转发循环,无限转发循环会不断的消耗内存和 CPU,直到主机最终因内存不足而死亡。

转发循环一般是CoreDNS将请求转发给自身导致的,例如127.0.0.1::1127.0.0.53

这种报错一般发生在Ubuntu操作系统上,由于Ubuntu操作系统会启动systemd-resolved服务管理DNS系统进行DNS缓存,此时会将主机的/etc/resolv.conf文件配置成127.0.0.53的地址。coredns会拿这个配置进行转发,最终导致无限转发的情况。

解决问题

有几种解决方法:

方法一

  1. 禁用systemd-resolved服务,并手动配置/etc/resolv.conf
1
2
3
4
systemctl disable systemd-resolved.service 
systemctl stop systemd-resolved.service
mv /etc/resolv.conf /opt
echo nameserver 114.114.114.114 >> /etc/resolv.conf
  1. 由于coredns会去拿kubelet的resolv.conf,而rancher的k8s组件是容器运行的,也就是说kubelet是容器运行,所以需要重启一下kubelet容器去让kubelet拿主机的resolv.conf文件配置(其他k8s集群可以不用这个操作)
1
docker restart kubelet
  1. 重启coredns即可
1
kubectl -n kube-system delete pods -l k8s-app=kube-dns 

方法二

如果因为某些原因暂时无法禁用systemd-resolved服务,可以先修改Corefile配置,该配置在kube-system命名空间的coredns configmap下,将forward . /etc/resolv.conf替换成DNS服务器的地址,例如替换成forward . 114.114.114.114,完成配置参考如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.:53 {
log
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . 114.114.114.114
cache 30
loop
reload
loadbalance
}

参考:https://coredns.io/plugins/loop/#troubleshooting