5種常見的 DNS 故障診斷及問題處理方法

千鋒IT教育發表於2022-11-22

本節模擬幾種導致 DNS 查詢變慢的場景,如果在實際環境中遇到類似現象,可以考慮往這些 方向排查。

1、機器未配置 DNS 導致域名查詢失敗

現象:網路是通的(例如 ping IP 通),但是 DNS 查詢總是失敗

可能的原因:機器沒有配置 DNS 伺服器

解決辦法:修改/etc/resolv.conf,給機器配置合適的 DNS 伺服器 有時新啟動的機器(不管是物理機、虛擬機器還是容器)沒有設定 DNS,導致訪問域名不通。我們來複現一下。

在正常的容器裡用 nslookup 工具檢視域名對應的 IP 地址:

/ # nslookup example.com
Name:      example.com
Address 1: 93.184.216.34
Address 2: 2606:2800:220:1:248:1893:25c8:1946

可以看到,我們獲取到了該域名一個 IPv4 地址和一個 IPv6 地址。

將/etc/resolv.conf 裡的 DNS 伺服器列表用#註釋掉,模擬沒有配置 DNS 伺服器的場景。

再次測試:

/ # nslookup example.com
nslookup: can't resolve 'example.com': Try again

所以遇到這種問題,可以先去排查/etc/resolv.conf 裡面是否配置了 DNS 伺服器。

2、DNS 服務太慢

現象:DNS 查詢太慢

可能的原因:配置的 DNS 伺服器不合理

解決辦法:修改/etc/resolv.conf,配置合適的 DNS 伺服器

每個公司一般都有自維護的 DNS 伺服器,不僅用來解析內網 DNS,而且可以加速解析公網域名 。

dig 是另外一個功能更強大的 DNS 查詢工具,安裝:

/ # apk update && apk add bind-tools

首先檢視使用內網 DNS,查詢域名的延遲:

/ # dig example.com
...
example.com.            15814   IN      A       93.184.216.34
;; Query time: 0 msec
;; SERVER: 192.168.1.11#53(192.168.1.11)

可以看到非常快,在 1ms 以內。

然後我們測試如果使用 Google 的公網 DNS 伺服器 8.8.8.8 [1],延遲會是多少。

修改/etc/resolv.conf,將其他 nameserver 註釋掉,新增一行 nameserver 8.8.8.8。

再次測試:

/ # dig example.com
...
example.com.            15814   IN      A       93.184.216.34
;; Query time: 150 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)

延遲變成了 150ms,比原來大了 150 多倍。

因此,對於 DNS 查詢特別慢的場景,首先要檢視配置的 DNS 伺服器是否合理。

3、hardcode /etc/hosts 導致跳過 DNS 查詢

現象:某域名訪問太慢、某域名總是指向相同 IP(多 IP 情況下)、特定機器不可訪問 某域名等等

可能的原因:/etc/hosts 有 hardcode 域名及 IP

解決辦法:修改/etc/hosts

前面提到,大部分公網域名都對應多個 IP 地址,因此每次 DNS 查詢拿到的 IP 地址都可能不一 樣,我們用 ping 來測試一下:

/ # ping baidu.com
PING baidu.com (220.181.57.216): 56 data bytes
64 bytes from 220.181.57.216: seq=0 ttl=45 time=26.895 ms
64 bytes from 220.181.57.216: seq=1 ttl=45 time=26.701 ms
^C
/ # ping baidu.com
PING baidu.com (123.125.115.110): 56 data bytes
64 bytes from 123.125.115.110: seq=0 ttl=43 time=27.587 ms
64 bytes from 123.125.115.110: seq=1 ttl=43 time=27.757 ms
^C

可以看到,兩次 ping 測試(內部首先查詢  baidu.com  對應的 IP 地址)拿到的 IP 地址是不一樣 的。用 nslookup 可以看到它們都是  baidu.com  對應的 IP 地址:

/ # nslookup baidu.com
Name: baidu.com
Address: 220.181.57.216
Name: baidu.com
Address: 123.125.115.110

/etc/hosts 裡面可以直接 harcode 一個域名對應的 IP 地址,這會導致機器跳過 DNS 查詢,直接拿這個 IP 作 為該域名的 IP。我們來驗證一下。

修改/etc/hosts,新增一行 123.125.115.110  baidu.com ,再次 ping 測試

/ # ping baidu.com
PING baidu.com (123.125.115.110): 56 data bytes
64 bytes from 123.125.115.110: seq=0 ttl=43 time=27.861 ms
^C
--- baidu.com ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 27.861/27.861/27.861 ms
/ # ping baidu.com
PING baidu.com (123.125.115.110): 56 data bytes
64 bytes from 123.125.115.110: seq=0 ttl=43 time=27.614 ms
^C

這是不管執行多少次, baidu.com  對應的 IP 地址都不會變了。而實際上,這個 IP 地址並不一定是最優的 IP 地址,甚至有可能這 個 IP 不可用,導致訪問  baidu.com  失敗。因此,實際中要極力避免在/etc/hosts 中 hardcode。

4、DNS 查詢不穩定

現象:DNS 查詢不穩定,時快時慢

可能的原因:機器上有 tc 或 iptables 規則,導致到 DNS 伺服器的 packet 變慢或丟失

解決辦法:修改或刪除 tc/iptables 規則

我們用 tc 來模擬網路延遲:

/ # apk add iproute2

首先檢視有沒有 tc 規則:

/ # tc -p qdisc ls dev eth0

預設沒有任何規則。

然後我們加一條:每個 packet 延遲 600ms:

/ # tc qdisc add dev eth0 root netem delay 600ms
/ # tc -p qdisc ls dev eth0
/ # qdisc netem 8001: root refcnt 2 limit 1000 delay 600.0ms

測試:

/ # dig example.com
...
example.com.            15814   IN      A       93.184.216.34
;; Query time: 600 msec
;; SERVER: 192.168.1.11#53(192.168.1.11)

可以看到,DNS 查詢變成了 600ms。

這裡我們測試的是固定延遲,這種問題很容易發現。我們還可以測試隨機延遲,或者按 比例延遲等 [2]:

/ # tc qdisc change dev eth0 root netem delay 600ms 10ms 25%
/ # tc qdisc change dev eth0 root netem delay 600ms 20ms distribution normal

此類規則會導致 DNS 查詢速度更有隨機性。

最後刪除 tc 規則:

/ # tc qdisc del dev eth0 root

iptables 規則也會導致類似的問題。

很多軟體在執行之後,會在宿主機上新增 tc 或 iptables 規則,例如 OpenStack,K8S 等等 。因此遇到這種隨機延遲問題,首先可以檢視機器上是否有 tc 或 iptables 規則。

5、DNS 反向查詢不穩定

線上遇到過這樣一個問題:從一臺機器 ping 一個內網域名,每個 ping 包看起來都會卡 5 ~ 30s 不等,但是 CTL-C 關閉 ping 之後,列印出來的統計資訊裡,既沒有丟包,ping 的延遲也很低 (毫秒級),這就很奇怪。接下來:

  • dig,很快,毫秒級,說明 DNS 查詢沒有問題
  • dig 能看到域名對應的 IP,直接 ping 這個 IP,發現是沒有卡頓的
  • 仍然 ping 域名,用 tcpdump 抓包,tcpdump -i eth0 hostand icmp,發現 ping 包都是立即響應的,印證了統計資訊裡,ping 延遲很低的事實

根據以上資訊,說明 ping 卡頓的問題出在這臺機器,而且應該就是 ping 程式本身在做什麼耗 時的操作。繼續:

  • 仍然 ping 域名,同時,用 ltrace -p跟蹤 ping 程式,發現卡在一個叫 gethostbyaddr()的函式
  • 查閱文件,發現這個函式是根據 IP 反向查詢 hostname,需要和 DNS 互動

到這裡,基本確定了是 DNS 伺服器反向查詢的問題,我們用另外幾個命令列工具驗證一下, 以下三個命令都是根據 IP 反查 hostname:

  • nslookup
  • host
  • dig -x

果然,以上三個命令都會卡住。修改/etc/resolv.conf,換一個 DNS 伺服器之後,問題 消失了。接下來,就去查 DNS 伺服器的問題吧。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70023145/viewspace-2924605/,如需轉載,請註明出處,否則將追究法律責任。

相關文章