采坑指南——k8s域名解析coredns問題排查過程


正文

前幾天,在ucloud上搭建的k8s集群(搭建教程后續會發出)。今天發現域名解析不了。

組件版本:k8s 1.15.0,coredns:1.3.1

過程是這樣的:

首先用以下yaml文件創建了一個nginx服務

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

創建好之后:
image.png
因只部署了一個master節點。在master宿主機上直接執行以下命令:

nslookup nginx-svc-old.default.svc

image.png
發現不能解析域名。事先也在宿主機上/etc/resolv.conf里配置了nameserver {coredns的podIP}
image.png
這樣一來,就以為可能是coredns有問題。。

然后用以下yaml創建了一個busybox作為調試工具:

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進入容器,執行測試命令
image.png
發現解析不了:

/ # 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文件:


[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,但可以訪問。
image.png
在容器內發請求時,會根據 /etc/resolv.conf 進行解析流程。選擇 nameserver 10.96.0.10 進行解析,然后用nginx-svc-old ,依次帶入 /etc/resolve.conf 中的 search 域,進行DNS查找,分別是:

search 內容類似如下(不同的pod,第一個域會有所不同)

search default.svc.cluster.local svc.cluster.local cluster.local
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日志,可以看到並沒有報錯:
image.png
那就說明不是coredns問題了。。

把busybox里報的錯誤,進行搜索google

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

image.png

查到了以下兩個issue:

issues1:

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

issues2:

https://github.com/easzlab/kubeasz/issues/260
image.png
發現都說是busybox鏡像的問題,從1.28.4以后的鏡像都存在這問題。把鏡像換成1.28.4試試?修改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

重新apply后,進入容器:
image.png

確實可以成功解析域名了。

那為什么宿主機上直接執行測試命令,域名不能解析呢?
image.png

繼續google,知道resolver域名解析器:

nameserver關鍵字,如果沒指定nameserver就找不到DNS服務器,其它關鍵字是可選的。nameserver表示解析域名時使用該地址指定的主機為域名服務器。其中域名服務器是按照文件中出現的順序來查詢的,且只有當第一個nameserver沒有反應時才查詢下面的nameserver,一般不要指定超過3個服務器。
而我在宿主上/etc/resolv.conf中nameserver如下:
image.png
且前三個域名解析服務器后可以通。

現在試着把coredns的其中一個podIP:192.168.155.73放到第一個nameserver:
image.png
可以看到現在可以解析了。

其實最好把kube-dns service的clusterIP放到/etc/resolv.conf中,這樣pod重啟后也可以解析。
image.png

參考

Linux中/etc/resolv.conf文件簡析
https://blog.csdn.net/lcr_happy/article/details/54867510

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

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

歷史文章

k8s中負載均衡器【ingress-nginx】部署

k8s使用Job執行任務失敗怎么辦

從外部訪問Kubernetes中的Pod

k8s負載均衡器配置請求重定向

教你輕松獲取k8s鏡像和安裝包

k8s必學必會知識梳理

docker基礎知識整理



本公眾號免費提供csdn下載服務,海量IT學習資源,如果你准備入IT坑,勵志成為優秀的程序猿,那么這些資源很適合你,包括但不限於java、go、python、springcloud、elk、嵌入式 、大數據、面試資料、前端 等資源。同時我們組建了一個技術交流群,里面有很多大佬,會不定時分享技術文章,如果你想來一起學習提高,可以公眾號后台回復【2】,免費邀請加技術交流群互相學習提高,會不定期分享編程IT相關資源。


掃碼關注,精彩內容第一時間推給你

image


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM