2021-11-30
技术笔记
00
请注意,本文编写于 987 天前,最后修改于 28 天前,其中某些信息可能已经过时。

本文分享一次定位nodelocaldns导致的k8s pod内无法解析业务域名问题的过程

最近在一个新部署的k8s集群上测试时发现,在pod内无法解析业务的域名,导致程序出错。这个业务域名是公司内部域名,集群的coreDNS已经配置forward到公司的DNS,按理来说是可以解析的才对。 进入pod容器内查看,/etc/resolv.conf的内容是这样的:

nameserver 169.254.25.10 search dev.svc.cluster.local svc.cluster.local cluster.local options ndots:5

可以看到,nameserver配置了一个奇怪的地址169.254.25.10. 上网搜了一下,原来这是一个叫nodelocaldns的组件的地址。这个NodeLocal DNS主要是利用cache来提升DNS解析性能的,在每个node上都会部署一个agent,通过169.254.25.10这个IP来访问。也就是说,在业务容器内访问的域名,实际上转发到了本节点nodelocaldns的pod内进行解析。 既然如此,就要看下nodelocaldns的配置了。在kube-system找到nodelocaldns的configmap,其中集群外域名的解析规则是:

.:53 { errors cache 30 reload loop bind 169.254.25.10 forward . /etc/resolv.conf prometheus :9253 }

可以看到,对于业务域名,nodelocaldns会使用自己容器内/etc/resolv.conf的规则来解析,那么这个本地规则是什么样的呢:

nameserver 114.114.114.114

配置的是114服务器,难怪公司内部的域名没法解析了。 解决方法有三种:

  1. 修改nodelocaldns的configmap
forward . /etc/resolv.conf

改成:

forward . __PILLAR__UPSTREAM__SERVERS__

然后重建nodelocaldns的pod 如果报错找不到__PILLAR__UPSTREAM__SERVERS__,可以改成coredns service的地址,比如我的集群coredns地址是10.233.0.3,那就改成

forward . 10.233.0.3
  1. 删掉nodelocaldns的daemonset,kubelet配置里ClusterDNS改成coredns service的地址
  2. 给nodelocaldns的spec添加dnsConfig,nameserver配置成公司的域名服务器

参考文档: https://www.qikqiak.com/post/resolve-coredns-hosts-invalid/https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/https://github.com/kubernetes/kubernetes/blob/master/cluster/addons/dns/nodelocaldns/nodelocaldns.yaml

本文作者:renbear

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC 2.0 许可协议。转载请注明出处!