本文主要用于介紹CoreDNS實(shí)現(xiàn)遞歸服務(wù)器的幾種方式以及在生產(chǎn)環(huán)境中遇到的一些問(wèn)題和解決方案。
在開(kāi)始之前我們需要知道一些關(guān)于CoreDNS的基本知識(shí):CoreDNS本身是沒(méi)有能力作為一個(gè)遞歸查詢(xún)的DNS服務(wù)器(Recursive DNS),但是它有著眾多的插件,可以通過(guò)插件來(lái)實(shí)現(xiàn)對(duì)域名的遞歸查詢(xún)和緩存等功能從而加速客戶(hù)端的DNS查詢(xún)性能。這里主要實(shí)現(xiàn)的插件有內(nèi)部插件(Plugins)forward或外部插件(External Plugins)unbound。
CoreDNS官方對(duì)External Plugins的描述為:
Out of tree plugins for CoreDNS. A plugin listed here is not automatically endorsed by the CoreDNS team. Issues should be reported to owner(s) of the plugin.
我們可以將CoreDNS的External Plugins簡(jiǎn)單理解為第三方插件,但是其中少部分會(huì)有官方的維護(hù)支持或者是直接默認(rèn)內(nèi)置在官方編譯好的版本中。
1、unbound
我們先來(lái)了解一下不依靠外部程序?qū)崿F(xiàn)遞歸查詢(xún)功能的unbound插件,unbound是一個(gè)非常優(yōu)秀的DNS軟件,專(zhuān)注于遞歸查詢(xún)和緩存,但對(duì)于權(quán)威DNS服務(wù)器這方面的功能稍顯不足,因此理論上將unbound和CoreDNS結(jié)合就可以很好的彌補(bǔ)兩者的不足。
1.1 編譯安裝
unbound插件的編譯安裝稍顯麻煩,此前的文章中有詳細(xì)介紹操作步驟和注意事項(xiàng),需要特別注意的是編譯安裝了unbound插件的CoreDNS會(huì)從原來(lái)的靜態(tài)二進(jìn)制文件,變成了需要?jiǎng)討B(tài)加載依賴(lài)庫(kù)。因此如果需要提前編譯然后大范圍使用,最好保證編譯環(huán)境的系統(tǒng)和最終的使用環(huán)境系統(tǒng)一致或全兼容。
1.2 一些問(wèn)題
unbound插件已經(jīng)很長(zhǎng)一段時(shí)間沒(méi)有更新維護(hù)了,盡管它有Maintained by CoreDNS的標(biāo)注,因此如果使用較新版本的go編譯之后,在啟動(dòng)的時(shí)候會(huì)有報(bào)警。
Jan 18 02:29:16 coredns1 coredns: [WARNING] An external plugin (/home/gopath/pkg/mod/github.com/coredns/unbound@v0.0.7/setup.go line 63) is using the deprecated function Normalize. This will be removed in a future versions of CoreDNS. The plugin should be updated to use OriginsFromArgsOrServerBlock or NormalizeExact instead.
另外就是在運(yùn)行的過(guò)程中會(huì)出現(xiàn)panic異常,一開(kāi)始懷疑是和負(fù)載有關(guān),后面測(cè)試發(fā)現(xiàn)當(dāng)請(qǐng)求量極低(個(gè)位數(shù)qps)的時(shí)候也會(huì)出現(xiàn)此類(lèi)異常。
[tinychen /home/coredns]# ./coredns -dns.port=53 -conf /home/coredns/corefile
.:53 on 0.0.0.0
CoreDNS-1.8.3
linux/amd64, go1.16.4, 7b43d042-dirty
[INFO] 127.0.0.1:46007 - 37929 "A IN baidu.com. udp 50 false 4096" NOERROR qr,rd,ra 484 0.614542s
[INFO] 127.0.0.1:32946 - 43201 "A IN baidu.com. udp 50 false 4096" NOERROR qr,aa,rd,ra 484 0.0000971s
[INFO] 127.0.0.1:38201 - 44652 "A IN baidu.com. udp 50 false 4096" NOERROR qr,aa,rd,ra 484 0.0001522s
[INFO] 127.0.0.1:50863 - 63692 "A IN tinychen.com. udp 53 false 4096" NOERROR qr,rd,ra 58 0.3613896s
[ERROR] Recovered from panic in server: "dns://0.0.0.0:53"
[ERROR] Recovered from panic in server: "dns://0.0.0.0:53"
[ERROR] Recovered from panic in server: "dns://0.0.0.0:53"
經(jīng)過(guò)多次測(cè)試之后,我們發(fā)現(xiàn)針對(duì)unbound插件出現(xiàn)panic的情況和請(qǐng)求的頻率無(wú)關(guān),而是和請(qǐng)求的內(nèi)容有關(guān)。簡(jiǎn)單來(lái)說(shuō)就是:當(dāng)請(qǐng)求的域名本身就不存在解析的時(shí)候,就會(huì)觸發(fā)panic異常;當(dāng)然還可以再進(jìn)一步:當(dāng)CoreDNS服務(wù)端本身無(wú)法和根域名服務(wù)器建立連接轉(zhuǎn)發(fā)查詢(xún)的時(shí)候,也會(huì)出現(xiàn)panic異常。
2、forward
2.1 配置使用
forward插件主要的作用就是把DNS請(qǐng)求轉(zhuǎn)發(fā)給上游的upstream服務(wù)器。forward插件本身并不支持任何的DNS解析功能,但是可以將相應(yīng)的請(qǐng)求轉(zhuǎn)發(fā)到遞歸服務(wù)器上,再結(jié)合cache插件做緩存,從而實(shí)現(xiàn)遞歸查詢(xún)解析緩存的功能。
.:53 {
forward . 114.114.114.114 114.114.115.115 {
health_check 5s
}
log
errors
ready
prometheus
cache {
success 10240 600 60
denial 5120 60 5
}
}
forward對(duì)應(yīng)的upstream機(jī)器可以根據(jù)自己的需求選擇現(xiàn)有的公共DNS,如國(guó)內(nèi)常見(jiàn)的114、谷歌的8888等免費(fèi)DNS,或者選擇自己使用unbound、bind9之類(lèi)的DNS服務(wù)器單獨(dú)搭建一個(gè)專(zhuān)門(mén)用來(lái)做遞歸查詢(xún)的DNS服務(wù)。
2.2 一些問(wèn)題
Jan 18 05:29:16 coredns1 coredns: [ERROR] plugin/errors: 2 nonexist.test.tinychen.com. A: read udp 127.0.0.1:7522->114.114.114.114:53: i/o timeout
當(dāng)查詢(xún)的域名解析記錄不存在或者是網(wǎng)絡(luò)問(wèn)題不可達(dá)的時(shí)候,可能會(huì)觸發(fā)upstream的超時(shí)時(shí)間限制,導(dǎo)致報(bào)錯(cuò)i/o timeout,可以考慮使用error插件的consolidate指令對(duì)這類(lèi)報(bào)警進(jìn)行統(tǒng)一處理并修改報(bào)警等級(jí)
errors {
consolidate 5m ".* i/o timeout$" warning
}