curl 和 wget 無法解析 aks 叢集內的內部 dns 名稱,但 nslookup 、 host 、 dig 運作正常

curl 和 wget 無法解析 aks 叢集內的內部 dns 名稱,但 nslookup 、 host 、 dig 運作正常

我在 azure 上有一個託管 kubernetes 實例。我非常確定核心 dns 正在工作並且 dns pod 運行狀況良好。

我有幾項服務

  1. 帶有一個 pod 的 frontend-service - 具有靜態前端檔案的鏡像 [nginx-alpine]。

  2. backend-service ,帶有一個 pod - 包含 Nodejs 程式碼的映像 [ubuntu:20.04]。

我無法從後端的 pod 解析 frontend-service 或 frontend-service.default.svc.cluster.local 等內部 dns 服務名稱,但內部 dns 名稱的 nslookup 、 host 、 dig 解析為正確的位址。後端 Pod 也能夠解析外部 DNS 名稱,例如 google.com。

curl http://frontend-service
curl: (6) Could not resolve host: frontend-service

curl http://frontend-service.default.svc.cluster.local
curl: (6) Could not resolve host: frontend-service.default.svc.cluster.local
wget frontend-service
--2020-08-31 23:36:43--  http://frontend-service
Resolving frontend-service (frontend-service)... failed: Name or service not known.
wget: unable to resolve host address 'frontend-service'
/etc/nsswitch.conf shows the below :

passwd:         files
group:          files
shadow:         files
gshadow:        files

hosts:          files dns
networks:       files

protocols:      db files
services:       db files
ethers:         db files
rpc:            db files

嘗試從前端服務的 pod 解析後端服務內部 dns 名稱時,一切正常。

經過一些偵錯並查看 coredns 和 strace 的日誌後,我發現在執行 curl 時沒有對 coredns pod 進行任何調用,但我可以在執行 nslook up 時看到該條目。

我也。驗證 /etc/resolv.conf 的配置是否正確。

nameserver 10.3.0.10
search default.svc.cluster.local svc.cluster.local cluster.local tdghymxumodutbxfnz5m2elcog.bx.internal.cloudapp.net
options ndots:5

strace 不會顯示任何搜尋 /etc/resolv.conf 的項目,因此curl 不會檢查 /etc/resolv.conf 。

編輯1

From the backend service pod :
dig frontend-service [It is able to resolve to the correct name server.]


; <<>> DiG 9.16.1-Ubuntu <<>> frontend-service
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 13441
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; OPT=65436: 87 a1 ee 81 04 d8 5a 49 be 0e c4 ed 1d d8 27 41 ("......ZI......'A")
;; QUESTION SECTION:
;frontend-service.            IN      A

;; AUTHORITY SECTION:
.                       30      IN      SOA     a.root-servers.net. nstld.verisign-grs.com. 2020083101 1800 900 604800 86400

;; Query time: 20 msec
;; SERVER: 10.3.0.10#53(10.3.0.10)
;; WHEN: Tue Sep 01 10:48:00 IST 2020
;; MSG SIZE  rcvd: 142

nslookup frontend-service

Server:         10.3.0.10
Address:        10.3.0.10#53

Name:   frontend-service.default.svc.cluster.local
Address: 10.3.0.30
host frontend-service     
frontend-service.default.svc.cluster.local has address 10.3.0.30

編輯2

我想使用相同的 ubuntu:20.04 映像逐步測試部署,因此我執行了以下操作。

方法一

我在叢集中建立了一個臨時 Pod,如下所示。

kubectl run -it --rm test-ubuntu --image=ubuntu:20.04 --restart=Never

Installed curl (7.68) and ran the curl http://frontend-service – This is successful.

這讓我很困惑,所以我從 Dockerfile 中刪除了所有建置步驟,只使用了以下命令。

方法2

Dockerfile

FROM ubuntu:20.04
 
EXPOSE 3688
CMD [ "sleep", "infinity" ]

將映像推送到 acr 並再次部署後端 Pod。

kubectl exec -it <pod-name> /bin/bash

I installed curl (7.68) and ran the curl http://frontend-service – Same error – unable to resolve host.

這是令人驚訝的,具有相同內容的相同映像 - 透過 kubectl run 運行並透過 Dockerfile 部署,在運行相同版本(7.68)的curl時具有不同的行為。

我想看看這兩種方法中 strace 的流程。請找到 RUN 和 EXEC 的 strace 鏈接

strace 來自臨時 pod 運行的curl。 https://pastebin.com/NthHQacW

strace 從透過 Dockerfile 部署的 pod 運行curl https://pastebin.com/6LCE5NXu

透過運行分析探測路徑後

cat strace-log | grep open

我發現方法 2 的 strace 日誌缺少以下幾行。


2844  openat(AT_FDCWD, "/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 7
2844  openat(AT_FDCWD, "/etc/host.conf", O_RDONLY|O_CLOEXEC <unfinished...>
2844  <... openat resumed>)             = 7
2844  openat(AT_FDCWD, "/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 7
2844  openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 7
2844  openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 7
2844  openat(AT_FDCWD, "/etc/hosts", O_RDONLY|O_CLOEXEC) = 7
2844  openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC <unfinished ...>
2844  <... openat resumed>)             = 7
2844  openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libnss_dns.so.2", O_RDONLY|O_CLOEXEC) = 7

因此,pod 中的curl 指令不會查看/etc/resolv.conf 或/etc/nsswitch.conf。

我很困惑為什麼在同一集群中具有相同圖像和相同捲曲版本的兩個 Pod 中的捲曲行為不同。

答案1

在嘗試了很多選項之後,我嘗試偵錯我用來將 pod 部署到 AKS 叢集的部署設定檔。我有一個基於主機掛載的捲,它指向路徑“/var/run”。

一旦我刪除了主機掛載,curl 和 wget 就會按預期工作。

在與MS 支援人員討論此行為後,他們確認如果您的主機掛載指向路徑“/var/run”,則curl 和wget 不會回退到/etc/resolv.conf 檔案進行DNS 解析,這可能是由於以下方式造成的DNS 探測是在curl 和wget 中實現的。

相關內容