[问题记录]k8s集群中coredns解析失败
[问题记录]k8s集群中coredns解析失败
故障现象
在k8s集群,使用coredns提供集群内部dns服务
但是在使用过程中,偶现解析公网域名失败的情况,应用内日志记录显示UnknownHost
问题排查
对有问题的集群进行网络抓包解析,在服务侧记录到DNS解析失败的现象时,观察当时的DNS解析记录,发现:
- DNS最终是解析完成并将正确的结果返回给服务了
- 服务在获取到最终的正确解析结果前就抛出了UnknownHost
- 服务在向DNS服务器请求域名解析时,并未第一时间将完整域名申请解析,而是添加了k8s集群内部域名(如.svc.cluster.local)进行解析
问题解析
这个现象的根本原因是k8s集群内部的DNS解析优先级
在k8s集群内部,每个pod内都会有 /etc/resolv.conf 配置,具体内容如下
search c-moon.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.10.10.5
options ndots:2
文件中有 search 与 ndots 两个参数需要重点关注
- search 主机名列表;目前仅限6个域名,共计256个字符
- ndots 可理解为 点号 . 的个数
对于一个域名,如果不是完整域名,且域名中的点号小于ndots值,则会优先按照search的顺序依次解析
对于一个域名,如果不是完整域名,且域名中的点号小于ndots值,则会优先按照search的顺序依次解析
对于一个域名,如果不是完整域名,且域名中的点号小于ndots值,则会优先按照search的顺序依次解析
对于一个域名,如果不是完整域名,但域名中的点号大于/等于ndots值,则会直接解析完整域名
PS 完整域名: 以.结尾的域名(baidu.com 不是完整域名 baidu.com. 是完整域名)
完整域名
举例说明:
若在集群内需要解析 baidu.com 域名,按照本文上述 /etc/resolv.conf 配置,则真实的解析顺序为:
1、 baidu.com.c-moon.svc.cluster.local
2、 baidu.com.svc.cluster.local
3、 baidu.com.cluster.local
4、 baidu.com
解决方案
既然清楚了问题的原因,那么一共有两个解决思路
1、 服务请求DNS解析时多等一会
2、 修改 ndots 参数,减少不必要的解析请求
修改ndots参数
ndots参数默认为1,而coredns将其修改成了5,我们并不会去修改coredns,而是针对DP进行单独配置
spec:
dnsConfig:
options:
- name: ndots
value: '2'
containers:
image: nginx
imagePullPolicy: Always
name: nginx
... ...