在使用k8s的DNS来进行Service间的调用,通过Service名称发现无法解析域名。困惑了我好久,我可完全是按照文档 来的呀。终于在最后发现了原因,通过基本的分析思路,还是得从DNS的基础原理出发。

根据文档-使用 Service 连接到应用 ,一个集群内部的服务间访问,可以通过3种方式:

  1. 直接IP
  2. 通过环境变量
  3. 通过DNS,使用Service Name访问

前面2种就不说了,第3种需要安装DNS插件,可以通过下面的命令查看有没有DNS服务:

$ kubectl get services kube-dns --namespace=kube-system
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   4d2h

可以看到我的DNS已经运行了4天多了。

而排查DNS问题的步骤,第一步就是确定DNS是否正常运行。

域名访问测试

第二步,就是起一个带nslookup命令的pod来测试下域名访问。

Pod没起的情况

$ kubectl run curl1 --image=radial/busyboxplus:curl -i --tty
If you don't see a command prompt, try pressing enter.

如果找得到域名,就是下面这样:

# 找到
[ root@curl1:/ ]$ nslookup sentry-web
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      sentry-web
Address 1: 10.96.231.203 sentry-web.default.svc.cluster.local

如果找不到:

# 找不到
[ root@curl1:/ ]$ nslookup sentry-web
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

nslookup: can't resolve 'sentry-web'

这里找不到的原因是Pod停了,但DNS服务的地址都是一样的,有这些 10.96.231.203 sentry-web.default.svc.cluster.local.

DNS服务不存在

第二种情况就是DNS地址缺失,查找域名时肯定找不到。

进入找不到域名的Pod容器,查看他的配置文件 /etc/resolv.conf为:

 cat /etc/resolv.conf 
nameserver 172.18.0.1
options ndots:0

可以看到,只有 172.18.0.1.

而正常k8s内网pod里的是:

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

可以看到,为什么没有 default.svc.cluster.local svc.cluster.local cluster.local 这些DNS服务地址呢?

特别注意

我对比了Pod的配置文件,发现这个Pod启用了 hostNetwork,和主机共用网络。

kind: Pod
apiVersion: v1
metadata:
  name: sentry-relay
  labels:
    app: sentry
spec:
  hostNetwork: true
  containers:
    - name: sentry-relay
      image: getsentry/relay:22.6.0
      ports:
        - containerPort: 3000

如果使用了 hostNetwork, 那么是无法接入k8s的DNS的.

这里需要特别注意。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐