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

Posted c-moon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[问题记录]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 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

k8s中的dns应用

参考技术A 所有通过ingress来负载均衡的服务的域名解析都是基于ingress的svc external ip来访问的

集群内部可以基于ingress 查到域名和traefik-ingress-controller的关联。
但是 域名和external ip(fip)的解析记录是在集群外部统一维护的,一般每个办公区域都有一个统一的dns服务。
比如 coredns,dnsmasq,每个模拟的可用区的dns记录,都统一在外部的dns服务内解析。

以上是关于[问题记录]k8s集群中coredns解析失败的主要内容,如果未能解决你的问题,请参考以下文章

K8S CoreDNS部署失败,问题分析

k8s中的dns应用

k8s集群coredns无法解析外部域名

k8s集群coredns无法解析外部域名

K8S集群部署Coredns服务

Kubernetes 0-1 K8S部署coredns