本文轉(zhuǎn)載自:「云原生技術(shù)愛好者社區(qū)」
原文:https://tinyurl.com/6c3anmaj,版權(quán)歸原作者所有
1 DNS 基礎(chǔ)知識(shí)
互聯(lián)網(wǎng)基于 TCP/IP 協(xié)議。為了方便管理網(wǎng)絡(luò)內(nèi)的主機(jī),整個(gè)互聯(lián)網(wǎng)分為若干個(gè)域 (domain),每 個(gè)域又可以再分為若干個(gè)子域,例如,.com,.org,.edu 都是頂級(jí)域,而 google.com 是.com 下面的子域。
網(wǎng)絡(luò)中的任意一臺(tái)主機(jī)(host)都會(huì)屬于某個(gè)域,并且有自己的名字,稱為主機(jī)名( hostname)。例如 example.com 就是.com 域中一臺(tái)主機(jī)名為 example.com(或 example,hostname 和 domain name 的區(qū)別,見這里 )的主機(jī)。
域名/主機(jī)名是為了方便人記憶,而機(jī)器之間通信最終用的還是 IP 地址,因此需要一個(gè)將主 機(jī)名(域名)轉(zhuǎn)換成 IP 地址的服務(wù)。域名服務(wù)系統(tǒng)(DNS, domain name system)做的就是 這個(gè)事情,對(duì)應(yīng)的服務(wù)器稱為域名服務(wù)器(Domain Name Server)。
例如,當(dāng)通過瀏覽器訪問 example.com,瀏覽器會(huì)首先訪問 DNS 服務(wù)器,查找 example.com 對(duì)應(yīng)的 IP 地址,然后和這個(gè) IP 建立 TCP 連接,接下來才發(fā)起 HTTP 請(qǐng)求。
一個(gè)域名可以對(duì)應(yīng)一個(gè) IP 地址,也可以對(duì)應(yīng)多個(gè)。對(duì)于后者,DNS 服務(wù)算法會(huì)從中選擇一個(gè) 地址返回。大部分網(wǎng)絡(luò)服務(wù)為了實(shí)現(xiàn)高可用,都是對(duì)應(yīng)多個(gè)地址,我們后面會(huì)看到, baidu.com 就對(duì)應(yīng)多個(gè) IP。
有一些場(chǎng)景會(huì)導(dǎo)致訪問 DNS 服務(wù)不穩(wěn)定,例如 DNS 服務(wù)器的設(shè)置有問題、網(wǎng)絡(luò)有丟包、主機(jī) DNS 配置錯(cuò)誤等等。我們接下來查看幾種 case。
2 準(zhǔn)備測(cè)試環(huán)境
為方便大家跟著上手練習(xí),本文將搭建一個(gè)容器環(huán)境。
Pull Docker 鏡像:
$sudodockerpullalpine:3.8
運(yùn)行容器,注意這里一定要帶--privileged 參數(shù) [2],否則后面的部分 tc 命令無法執(zhí)行:
$sudodockerrun-d--privileged--namectn-1alpine:3.8sleep3600d $sudodockerps CONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES 233bc36bde4balpine:3.8"sleep3600d"1minutesagoUp14minutesctn-1
進(jìn)入容器:
$sudodockerexec-itctn-1sh
查看容器網(wǎng)絡(luò)信息:
/#ifconfig eth0Linkencap:EthernetHWaddr02AC00:09 inetaddr:172.17.0.9Bcast:0.0.0.0Mask:255.255.0.0
3 DNS 配置
3.1 查看 DNS 配置
Linux 上的 DNS 配置在/etc/resolv.conf 里面。我們先來查看容器的配置:
/#cat/etc/resolv.conf #Dynamicresolv.conf(5)fileforglibcresolver(3)generatedbyresolvconf(8) #DONOTEDITTHISFILEBYHAND--YOURCHANGESWILLBEOVERWRITTEN nameserver192.168.1.11 nameserver192.168.1.12
這其實(shí)是繼承了宿主機(jī)的 DNS 配置,在宿主機(jī)上執(zhí)行 cat /etc/resolv.conf 會(huì)看到一樣的 結(jié)果。
3.2 修改 DNS 配置
可以通過修改/etc/resolv.conf 里面的 nameserver 來配置自己想用的 DNS 服務(wù)器。例如內(nèi)網(wǎng)環(huán)境可能都會(huì)使用自己的 DNS 服務(wù)器,因?yàn)樗?提供內(nèi)網(wǎng)域名解析之外,公網(wǎng)域名解析也會(huì)比較快(相比于網(wǎng)絡(luò)供應(yīng)商的公網(wǎng) DNS 服務(wù)器) 。
4 DNS 問題排查
本節(jié)模擬幾種導(dǎo)致 DNS 查詢變慢的場(chǎng)景,如果在實(shí)際環(huán)境中遇到類似現(xiàn)象,可以考慮往這些 方向排查。
4.1 機(jī)器未配置 DNS 導(dǎo)致域名查找失敗
現(xiàn)象:網(wǎng)絡(luò)是通的(例如 ping IP 通),但是 DNS 查詢總是失敗
可能的原因:機(jī)器沒有配置 DNS 服務(wù)器
解決辦法:修改/etc/resolv.conf,給機(jī)器配置合適的 DNS 服務(wù)器 有時(shí)新啟動(dòng)的機(jī)器(不管是物理機(jī)、虛擬機(jī)還是容器)沒有設(shè)置 DNS,導(dǎo)致訪問域名不通。我們來復(fù)現(xiàn)一下。
在正常的容器里用 nslookup 工具查看域名對(duì)應(yīng)的 IP 地址:
/#nslookupexample.com Name:example.com Address1:93.184.216.34 Address2:260622024825c8:1946
可以看到,我們獲取到了該域名一個(gè) IPv4 地址和一個(gè) IPv6 地址。
將/etc/resolv.conf 里的 DNS 服務(wù)器列表用#注釋掉,模擬沒有配置 DNS 服務(wù)器的場(chǎng)景。
再次測(cè)試:
/#nslookupexample.com nslookup:can'tresolve'example.com':Tryagain
所以遇到這種問題,可以先去排查/etc/resolv.conf 里面是否配置了 DNS 服務(wù)器。
4.2 DNS 服務(wù)太慢
現(xiàn)象:DNS 查詢太慢
可能的原因:配置的 DNS 服務(wù)器不合理
解決辦法:修改/etc/resolv.conf,配置合適的 DNS 服務(wù)器
每個(gè)公司一般都有自維護(hù)的 DNS 服務(wù)器,不僅用來解析內(nèi)網(wǎng) DNS,而且可以加速解析公網(wǎng)域名 。
dig 是另外一個(gè)功能更強(qiáng)大的 DNS 查詢工具,安裝:
/#apkupdate&&apkaddbind-tools
首先查看使用內(nèi)網(wǎng) DNS,查詢域名的延遲:
/#digexample.com ... example.com.15814INA93.184.216.34 ;;Querytime:0msec ;;SERVER:192.168.1.11#53(192.168.1.11)
可以看到非常快,在 1ms 以內(nèi)。
然后我們測(cè)試如果使用 Google 的公網(wǎng) DNS 服務(wù)器 8.8.8.8 [1],延遲會(huì)是多少。
修改/etc/resolv.conf,將其他 nameserver 注釋掉,添加一行 nameserver 8.8.8.8。
再次測(cè)試:
/#digexample.com ... example.com.15814INA93.184.216.34 ;;Querytime:150msec ;;SERVER:8.8.8.8#53(8.8.8.8)
延遲變成了 150ms,比原來大了 150 多倍。
因此,對(duì)于 DNS 查詢特別慢的場(chǎng)景,首先要查看配置的 DNS 服務(wù)器是否合理。
4.3 hardcode /etc/hosts 導(dǎo)致跳過 DNS 查詢
現(xiàn)象:某域名訪問太慢、某域名總是指向相同 IP(多 IP 情況下)、特定機(jī)器不可訪問 某域名等等
可能的原因:/etc/hosts 有 hardcode 域名及 IP
解決辦法:修改/etc/hosts
前面提到,大部分公網(wǎng)域名都對(duì)應(yīng)多個(gè) IP 地址,因此每次 DNS 查詢拿到的 IP 地址都可能不一 樣,我們用 ping 來測(cè)試一下:
/#pingbaidu.com PINGbaidu.com(220.181.57.216):56databytes 64bytesfrom220.181.57.216:seq=0ttl=45time=26.895ms 64bytesfrom220.181.57.216:seq=1ttl=45time=26.701ms ^C
/#pingbaidu.com PINGbaidu.com(123.125.115.110):56databytes 64bytesfrom123.125.115.110:seq=0ttl=43time=27.587ms 64bytesfrom123.125.115.110:seq=1ttl=43time=27.757ms ^C
可以看到,兩次 ping 測(cè)試(內(nèi)部首先查詢 baidu.com 對(duì)應(yīng)的 IP 地址)拿到的 IP 地址是不一樣 的。用 nslookup 可以看到它們都是 baidu.com 對(duì)應(yīng)的 IP 地址:
/#nslookupbaidu.com Name:baidu.com Address:220.181.57.216 Name:baidu.com Address:123.125.115.110
/etc/hosts 里面可以直接 harcode 一個(gè)域名對(duì)應(yīng)的 IP 地址,這會(huì)導(dǎo)致機(jī)器跳過 DNS 查詢,直接拿這個(gè) IP 作 為該域名的 IP。我們來驗(yàn)證一下。
修改/etc/hosts,添加一行 123.125.115.110 baidu.com,再次 ping 測(cè)試
/#pingbaidu.com PINGbaidu.com(123.125.115.110):56databytes 64bytesfrom123.125.115.110:seq=0ttl=43time=27.861ms ^C ---baidu.compingstatistics--- 1packetstransmitted,1packetsreceived,0%packetloss round-tripmin/avg/max=27.861/27.861/27.861ms /#pingbaidu.com PINGbaidu.com(123.125.115.110):56databytes 64bytesfrom123.125.115.110:seq=0ttl=43time=27.614ms ^C
這是不管執(zhí)行多少次,baidu.com 對(duì)應(yīng)的 IP 地址都不會(huì)變了。而實(shí)際上,這個(gè) IP 地址并不一定是最優(yōu)的 IP 地址,甚至有可能這 個(gè) IP 不可用,導(dǎo)致訪問 baidu.com 失敗。因此,實(shí)際中要極力避免在/etc/hosts 中 hardcode。
4.4 DNS 查詢不穩(wěn)定
現(xiàn)象:DNS 查詢不穩(wěn)定,時(shí)快時(shí)慢
可能的原因:機(jī)器上有 tc 或 iptables 規(guī)則,導(dǎo)致到 DNS 服務(wù)器的 packet 變慢或丟失
解決辦法:修改或刪除 tc/iptables 規(guī)則
我們用 tc 來模擬網(wǎng)絡(luò)延遲:
/#apkaddiproute2
首先查看有沒有 tc 規(guī)則:
/#tc-pqdisclsdeveth0
默認(rèn)沒有任何規(guī)則。
然后我們加一條:每個(gè) packet 延遲 600ms:
/#tcqdiscadddeveth0rootnetemdelay600ms /#tc-pqdisclsdeveth0 /#qdiscnetem8001:rootrefcnt2limit1000delay600.0ms
測(cè)試:
/#digexample.com ... example.com.15814INA93.184.216.34 ;;Querytime:600msec ;;SERVER:192.168.1.11#53(192.168.1.11)
可以看到,DNS 查詢變成了 600ms。
這里我們測(cè)試的是固定延遲,這種問題很容易發(fā)現(xiàn)。我們還可以測(cè)試隨機(jī)延遲,或者按 比例延遲等 [2]:
/#tcqdiscchangedeveth0rootnetemdelay600ms10ms25% /#tcqdiscchangedeveth0rootnetemdelay600ms20msdistributionnormal
此類規(guī)則會(huì)導(dǎo)致 DNS 查詢速度更有隨機(jī)性。
最后刪除 tc 規(guī)則:
/#tcqdiscdeldeveth0root
iptables 規(guī)則也會(huì)導(dǎo)致類似的問題。
很多軟件在運(yùn)行之后,會(huì)在宿主機(jī)上添加 tc 或 iptables 規(guī)則,例如 OpenStack,K8S 等等 。因此遇到這種隨機(jī)延遲問題,首先可以查看機(jī)器上是否有 tc 或 iptables 規(guī)則。
4.5 DNS 反向查詢不穩(wěn)定
線上遇到過這樣一個(gè)問題:從一臺(tái)機(jī)器 ping 一個(gè)內(nèi)網(wǎng)域名,每個(gè) ping 包看起來都會(huì)卡 5 ~ 30s 不等,但是 CTL-C 關(guān)閉 ping 之后,打印出來的統(tǒng)計(jì)信息里,既沒有丟包,ping 的延遲也很低 (毫秒級(jí)),這就很奇怪。接下來:
dig,很快,毫秒級(jí),說明 DNS 查詢沒有問題
dig 能看到域名對(duì)應(yīng)的 IP,直接 ping 這個(gè) IP,發(fā)現(xiàn)是沒有卡頓的
仍然 ping 域名,用 tcpdump 抓包,tcpdump -i eth0 hostand icmp,發(fā)現(xiàn) ping 包都是立即響應(yīng)的,印證了統(tǒng)計(jì)信息里,ping 延遲很低的事實(shí)
根據(jù)以上信息,說明 ping 卡頓的問題出在這臺(tái)機(jī)器,而且應(yīng)該就是 ping 程序本身在做什么耗 時(shí)的操作。繼續(xù):
仍然 ping 域名,同時(shí),用 ltrace -p跟蹤 ping 進(jìn)程,發(fā)現(xiàn)卡在一個(gè)叫 gethostbyaddr()的函數(shù)
查閱文檔,發(fā)現(xiàn)這個(gè)函數(shù)是根據(jù) IP 反向查詢 hostname,需要和 DNS 交互
到這里,基本確定了是 DNS 服務(wù)器反向查詢的問題,我們用另外幾個(gè)命令行工具驗(yàn)證一下, 以下三個(gè)命令都是根據(jù) IP 反查 hostname:
nslookup
host
dig -x
果然,以上三個(gè)命令都會(huì)卡住。修改/etc/resolv.conf,換一個(gè) DNS 服務(wù)器之后,問題 消失了。接下來,就去查 DNS 服務(wù)器的問題吧。
審核編輯:劉清
-
Linux系統(tǒng)
+關(guān)注
關(guān)注
4文章
593瀏覽量
27392 -
DNS
+關(guān)注
關(guān)注
0文章
218瀏覽量
19828 -
TCPIP協(xié)議
+關(guān)注
關(guān)注
0文章
35瀏覽量
11930 -
虛擬機(jī)
+關(guān)注
關(guān)注
1文章
914瀏覽量
28160 -
CTl
+關(guān)注
關(guān)注
0文章
6瀏覽量
7434
原文標(biāo)題:5 種最常見的 DNS 故障診斷及問題處理方法
文章出處:【微信號(hào):良許Linux,微信公眾號(hào):良許Linux】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論