前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >采坑指南——域名解析问题排查过程

采坑指南——域名解析问题排查过程

作者头像
我的小碗汤
发布2019-07-30 15:29:27
4.5K2
发布2019-07-30 15:29:27
举报
文章被收录于专栏:我的小碗汤

前几天,在ucloud上搭建的k8s集群(搭建教程后续会发出)。今天发现域名解析不了。

组件版本:k8s 1.15.0,coredns:1.3.1

过程是这样的:

首先用以下yaml文件创建了一个nginx服务

代码语言:javascript
复制
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc-old
  labels:
    app: nginx-svc
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nginx-old
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

创建好之后:

因只部署了一个master节点。在master宿主机上直接执行以下命令:

代码语言:javascript
复制
nslookup nginx-svc-old.default.svc

发现不能解析域名。事先也在宿主机上/etc/resolv.conf里配置了nameserver {coredns的podIP}

这样一来,就以为可能是coredns有问题。。

然后用以下yaml创建了一个busybox作为调试工具:

代码语言:javascript
复制
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: busybox-deployment
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: busybox
    spec:
      restartPolicy: Always
      containers:
      - name: busybox
        command:
        - sleep
        - "3600"
        image: busybox

这里用的是截止2019/07/20,busybox的最新镜像。创建好之后,exec进入容器,执行测试命令

发现解析不了:

代码语言:javascript
复制
/ # nslookup nginx-svc-old.default.svc
Server:    10.96.0.10
Address:  10.96.0.10:53

** server can't find nginx-svc-old.default.svc: NXDOMAIN

*** Can't find nginx-svc-old.default.svc: No answer

根据coredns解析集群内域名原理可知:

服务 a 访问服务 b,对于同一个 Namespace下,可以直接在 pod 中,通过 curl b 来访问。对于跨 Namespace 的情况,服务名后边对应 Namespace即可,比如 curl b.default。DNS 如何解析,依赖容器内 resolv 文件的配置。

查看busybox容器内的resolve.conf文件:

代码语言:javascript
复制
[root@liabio nginx]# kubectl exec -ti busybox-deployment-59755c8c6d-rmrfq sh
/ # nslookup nginx-svc-old.default.svc
Server:    10.96.0.10
Address:  10.96.0.10:53

** server can't find nginx-svc-old.default.svc: NXDOMAIN

*** Can't find nginx-svc-old.default.svc: No answer

/ # cat /etc/resolv.conf 
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
/ #

这个文件中,配置的 DNS Server,一般就是 K8S 中,kubedns 的 Service 的 ClusterIP,这个IP是虚拟IP,无法ping,但可以访问。

在容器内发请求时,会根据 /etc/resolv.conf 进行解析流程。选择 nameserver 10.96.0.10 进行解析,然后用nginx-svc-old ,依次带入 /etc/resolve.conf 中的 search 域,进行DNS查找,分别是:

search 内容类似如下(不同的pod,第一个域会有所不同)

代码语言:javascript
复制
search default.svc.cluster.local svc.cluster.local cluster.local
代码语言:javascript
复制
nginx-svc-old.default.svc.cluster.local -> nginx-svc-old.svc.cluster.local -> nginx-svc-old.cluster.local 

直到找到为止。所以,我们执行 ping nginx-svc-old,或者执行 ping nginx-svc-old.default,都可以完成DNS请求,这2个不同的操作,会分别进行不同的DNS查找步骤。

根据以上原理,查看到busybox内的域名/etc/resolv.conf没有问题,nameserver指向正确的kube-dns的service clusterIP。

这下更加怀疑core-dns有问题了。

但查看coredns日志,可以看到并没有报错:

那就说明不是coredns问题了。。

把busybox里报的错误,进行搜索google

代码语言:javascript
复制
*** Can't find nginx-svc-old.default.svc: No answer

查到了以下两个issue:

issues1:

https://github.com/kubernetes/kubernetes/issues/66924

issues2:

https://github.com/easzlab/kubeasz/issues/260

发现都说是busybox镜像的问题,从1.28.4以后的镜像都存在这问题。把镜像换成1.28.4试试?修改yaml版本号:

代码语言:javascript
复制
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: busybox-deployment
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: busybox
    spec:
      restartPolicy: Always
      containers:
      - name: busybox
        command:
        - sleep
        - "3600"
        image: busybox:1.28.4

重新apply后,进入容器:

确实可以成功解析域名了。

那为什么宿主机上直接执行测试命令,域名不能解析呢?

继续google,知道resolver域名解析器:

nameserver关键字,如果没指定nameserver就找不到DNS服务器,其它关键字是可选的。nameserver表示解析域名时使用该地址指定的主机为域名服务器。其中域名服务器是按照文件中出现的顺序来查询的,且只有当第一个nameserver没有反应时才查询下面的nameserver,一般不要指定超过3个服务器。

而我在宿主上/etc/resolv.conf中nameserver如下:

且前三个域名解析服务器后可以通。

现在试着把coredns的其中一个podIP:192.168.155.73放到第一个nameserver:

可以看到现在可以解析了。

其实最好把kube-dns service的clusterIP放到/etc/resolv.conf中,这样pod重启后也可以解析。

参考:

Linux中/etc/resolv.conf文件简析

https://blog.csdn.net/lcr_happy/article/details/54867510

CoreDNS系列1:Kubernetes内部域名解析原理、弊端及优化方式

https://hansedong.github.io/2018/11/20/9/

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-07-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 进击云原生 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Linux中/etc/resolv.conf文件简析
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档