采坑指南——k8s域名解析coredns问题排查过程
<h2 id="正文">正文</h2><p>前几天,在ucloud上搭建的k8s集群(搭建教程后续会发出)。今天发现域名解析不了。</p>
<p><strong>组件版本:k8s 1.15.0,coredns:1.3.1</strong></p>
<h3 id="过程是这样的">过程是这样的:</h3>
<p>首先用以下yaml文件创建了一个nginx服务</p>
<pre><code class="language-yaml">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
</code></pre>
<p>创建好之后:<br>
<img src="https://img2018.cnblogs.com/blog/1677443/201910/1677443-20191016100137917-625155618.jpg" alt="image.png" loading="lazy"><br>
因只部署了一个master节点。在master宿主机上直接执行以下命令:</p>
<pre><code class="language-yaml">nslookup nginx-svc-old.default.svc
</code></pre>
<p><img src="https://img2018.cnblogs.com/blog/1677443/201910/1677443-20191016100138648-1883964867.jpg" alt="image.png" loading="lazy"><br>
发现不能解析域名。事先也在宿主机上/etc/resolv.conf里配置了nameserver {coredns的podIP}<br>
<img src="https://img2018.cnblogs.com/blog/1677443/201910/1677443-20191016100146640-1863268935.jpg" alt="image.png" loading="lazy"><br>
这样一来,就以为可能是coredns有问题。。</p>
<p>然后用以下yaml创建了一个busybox作为调试工具:</p>
<pre><code class="language-yaml">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
</code></pre>
<p>这里用的是截止2019/07/20,busybox的最新镜像。创建好之后,exec进入容器,执行测试命令<br>
<img src="https://img2018.cnblogs.com/blog/1677443/201910/1677443-20191016100148135-2085114966.jpg" alt="image.png" loading="lazy"><br>
发现解析不了:</p>
<pre><code class="language-yaml">/ # 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
</code></pre>
<p>根据coredns解析集群内域名原理可知:</p>
<p>服务 a 访问服务 b,对于同一个 Namespace下,可以直接在 pod 中,通过 curl b 来访问。对于跨 Namespace 的情况,服务名后边对应 Namespace即可,比如 curl b.default。DNS 如何解析,依赖容器内 resolv 文件的配置。</p>
<p>查看busybox容器内的resolve.conf文件:</p>
<pre><code class="language-yaml">
# 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
/ #
</code></pre>
<p>这个文件中,配置的 DNS Server,一般就是 K8S 中,kubedns 的 Service 的 ClusterIP,这个IP是虚拟IP,无法ping,但可以访问。<br>
<img src="https://img2018.cnblogs.com/blog/1677443/201910/1677443-20191016100150838-1685026405.jpg" alt="image.png" loading="lazy"><br>
在容器内发请求时,会根据 /etc/resolv.conf 进行解析流程。选择 nameserver 10.96.0.10 进行解析,然后用nginx-svc-old ,依次带入 /etc/resolve.conf 中的 search 域,进行DNS查找,分别是:</p>
<p>search 内容类似如下(不同的pod,第一个域会有所不同)</p>
<pre><code class="language-yaml">search default.svc.cluster.local svc.cluster.local cluster.local
</code></pre>
<pre><code class="language-yaml">nginx-svc-old.default.svc.cluster.local -> nginx-svc-old.svc.cluster.local -> nginx-svc-old.cluster.local
</code></pre>
<p>直到找到为止。所以,我们执行 ping nginx-svc-old,或者执行 ping nginx-svc-old.default,都可以完成DNS请求,这2个不同的操作,会分别进行不同的DNS查找步骤。</p>
<p>根据以上原理,查看到busybox内的域名/etc/resolv.conf没有问题,nameserver指向正确的kube-dns的service clusterIP。</p>
<p>这下更加怀疑core-dns有问题了。</p>
<p>但查看coredns日志,可以看到并没有报错:<br>
<img src="https://img2018.cnblogs.com/blog/1677443/201910/1677443-20191016100151866-417911945.jpg" alt="image.png" loading="lazy"><br>
那就说明不是coredns问题了。。</p>
<p>把busybox里报的错误,进行搜索google</p>
<pre><code class="language-yaml">*** Can't find nginx-svc-old.default.svc: No answer
</code></pre>
<p><img src="https://img2018.cnblogs.com/blog/1677443/201910/1677443-20191016100153101-536477428.jpg" alt="image.png" loading="lazy"></p>
<p>查到了以下两个issue:</p>
<h4 id="issues1">issues1:</h4>
<p>https://github.com/kubernetes/kubernetes/issues/66924<br>
<img src="https://img2018.cnblogs.com/blog/1677443/201910/1677443-20191016100155717-189341869.jpg" alt="image.png" loading="lazy"></p>
<h4 id="issues2">issues2:</h4>
<p>https://github.com/easzlab/kubeasz/issues/260<br>
<img src="https://img2018.cnblogs.com/blog/1677443/201910/1677443-20191016100157912-1811742250.jpg" alt="image.png" loading="lazy"><br>
发现都说是busybox镜像的问题,从1.28.4以后的镜像都存在这问题。把镜像换成1.28.4试试?修改yaml版本号:</p>
<pre><code class="language-yaml">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
</code></pre>
<p>重新apply后,进入容器:<br>
<img src="https://img2018.cnblogs.com/blog/1677443/201910/1677443-20191016100201801-164252238.jpg" alt="image.png" loading="lazy"></p>
<p>确实可以成功解析域名了。</p>
<p>那为什么宿主机上直接执行测试命令,域名不能解析呢?<br>
<img src="https://img2018.cnblogs.com/blog/1677443/201910/1677443-20191016100203844-293885891.jpg" alt="image.png" loading="lazy"></p>
<p>继续google,知道resolver域名解析器:</p>
<p>nameserver关键字,如果没指定nameserver就找不到DNS服务器,其它关键字是可选的。nameserver表示解析域名时使用该地址指定的主机为域名服务器。其中域名服务器是按照文件中出现的顺序来查询的,且只有当第一个nameserver没有反应时才查询下面的nameserver,一般不要指定超过3个服务器。<br>
而我在宿主上/etc/resolv.conf中nameserver如下:<br>
<img src="https://img2018.cnblogs.com/blog/1677443/201910/1677443-20191016100207918-548775601.jpg" alt="image.png" loading="lazy"><br>
且前三个域名解析服务器后可以通。</p>
<p>现在试着把coredns的其中一个podIP:192.168.155.73放到第一个nameserver:<br>
<img src="https://img2018.cnblogs.com/blog/1677443/201910/1677443-20191016100209630-1331499340.jpg" alt="image.png" loading="lazy"><br>
可以看到现在可以解析了。</p>
<p>其实最好把kube-dns service的clusterIP放到/etc/resolv.conf中,这样pod重启后也可以解析。<br>
<img src="https://img2018.cnblogs.com/blog/1677443/201910/1677443-20191016100212110-1216791033.jpg" alt="image.png" loading="lazy"></p>
<h2 id="参考">参考</h2>
<p>Linux中/etc/resolv.conf文件简析<br>
https://blog.csdn.net/lcr_happy/article/details/54867510</p>
<p>CoreDNS系列1:Kubernetes内部域名解析原理、弊端及优化方式</p>
<p>https://hansedong.github.io/2018/11/20/9/</p>
<h2 id="历史文章">历史文章</h2>
<p>k8s中负载均衡器【ingress-nginx】部署</p>
<p>k8s使用Job执行任务失败怎么办</p>
<p>从外部访问Kubernetes中的Pod</p>
<p>k8s负载均衡器配置请求重定向</p>
<p>教你轻松获取k8s镜像和安装包</p>
<p>k8s必学必会知识梳理</p>
<p>docker基础知识整理</p>
<hr>
<hr>
<p><strong>本公众号</strong>免费<strong>提供csdn下载服务,海量IT学习资源,</strong>如果你准备入IT坑,励志成为优秀的程序猿,那么这些资源很适合你,包括但不限于java、go、python、springcloud、elk、嵌入式 、大数据、面试资料、前端 等资源。同时我们组建了一个技术交流群,里面有很多大佬,会不定时分享技术文章,如果你想来一起学习提高,可以公众号后台回复【<strong>2</strong>】,免费邀请加技术交流群互相学习提高,会不定期分享编程IT相关资源。</p>
<hr>
<p>扫码关注,精彩内容第一时间推给你</p>
<p><img src="https://img2018.cnblogs.com/blog/1677443/201910/1677443-20191016100212327-1942676483.jpg" alt="image" loading="lazy"></p><br><br>
来源:https://www.cnblogs.com/liabio/p/11683714.html
頁:
[1]