[问题记录]k8s集群中coredns解析失败

发布时间 2023-04-25 15:00:50作者: 大胡萝卜没有须

[问题记录]k8s集群中coredns解析失败

故障现象

在k8s集群,使用coredns提供集群内部dns服务
但是在使用过程中,偶现解析公网域名失败的情况,应用内日志记录显示UnknownHost

问题排查

对有问题的集群进行网络抓包解析,在服务侧记录到DNS解析失败的现象时,观察当时的DNS解析记录,发现:

  • DNS最终是解析完成并将正确的结果返回给服务了
  • 服务在获取到最终的正确解析结果前就抛出了UnknownHost
  • 服务在向DNS服务器请求域名解析时,并未第一时间将完整域名申请解析,而是添加了k8s集群内部域名(如.svc.cluster.local)进行解析

问题解析

这个现象的根本原因是k8s集群内部的DNS解析优先级
在k8s集群内部,每个pod内都会有 /etc/resolv.conf 配置,具体内容如下

search cube-robot.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.10.10.5
options ndots:2

文件中有 searchndots 两个参数需要重点关注

  • search 主机名列表;目前仅限6个域名,共计256个字符
  • ndots 可理解为 点号 . 的个数

对于一个域名,如果不是完整域名,且域名中的点号小于ndots值,则会优先按照search的顺序依次解析
对于一个域名,如果不是完整域名,且域名中的点号小于ndots值,则会优先按照search的顺序依次解析
对于一个域名,如果不是完整域名,且域名中的点号小于ndots值,则会优先按照search的顺序依次解析

对于一个域名,如果不是完整域名,但域名中的点号大于/等于ndots值,则会直接解析完整域名

PS 完整域名: 以.结尾的域名(baidu.com 不是完整域名 baidu.com. 是完整域名)
完整域名

举例说明:

若在集群内需要解析 baidu.com 域名,按照本文上述 /etc/resolv.conf 配置,则真实的解析顺序为:
1、 baidu.com.cube-robot.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
      ... ...

参考文档

DNS for Services and Pods