原文連接:https://fuckcloudnative.io/posts/install-coredns-on-macos/html
CoreDNS 是 Golang 編寫的一個插件式 DNS 服務器,是 Kubernetes 1.13 後所內置的默認 DNS 服務器。CoreDNS 的目標是成爲 cloud-native 環境下的 DNS 服務器和服務發現解決方案,即:linux
Our goal is to make CoreDNS the cloud-native DNS server and service discovery solution.nginx
它有如下幾個特性:git
插件化(Plugins)github
基於 Caddy 服務器框架,CoreDNS 實現了一個插件鏈的架構,將大量應用端的邏輯抽象成 plugin 的形式(如 Kubernetes 的 DNS 服務發現,Prometheus 監控等)暴露給使用者。CoreDNS 以預配置的方式將不一樣的 plugin 串成一條鏈,按序執行 plugin 的邏輯。從編譯層面,用戶選擇所需的 plugin 編譯到最終的可執行文件中,使得運行效率更高。CoreDNS 採用 Go 編寫,因此從具體代碼層面來看,每一個 plugin 其實都是實現了其定義的 interface 的組件而已。第三方只要按照 CoreDNS Plugin API 去編寫自定義插件,就能夠很方便地集成於 CoreDNS。macos
配置簡單化json
引入表達力更強的 DSL,即 Corefile
形式的配置文件(也是基於 Caddy 框架開發)。windows
一體化的解決方案後端
區別於 kube-dns
,CoreDNS 編譯出來就是一個單獨的二進制可執行文件,內置了 cache,backend storage,health check 等功能,無需第三方組件來輔助實現其餘功能,從而使得部署更方便,內存管理更爲安全。緩存
其實從功能角度來看,CoreDNS 更像是一個通用 DNS 方案(相似於 BIND
),而後經過插件模式來極大地擴展自身功能,從而能夠適用於不一樣的場景(好比 Kubernetes)。正如官方博客所說:
CoreDNS is powered by plugins.
Corefile
是 CoreDNS 的配置文件(源於 Caddy 框架的配置文件 Caddyfile),它定義了:
server
以什麼協議監聽在哪一個端口(能夠同時定義多個 server 監聽不一樣端口)zone
的權威(authoritative)DNS 解析常見地,一個典型的 Corefile 格式以下所示:
ZONE:[PORT] { [PLUGIN] ... }
PORT
是可選項,默認爲 53;好比:
. { chaos CoreDNS-001 }
上述配置文件表達的是:server 負責根域 .
的解析,其中 plugin 是 chaos
且沒有參數。
一個最簡單的配置文件能夠爲:
.{}
即 server 監聽 53 端口並不使用插件。若是此時在定義其餘 server,要保證監聽端口不衝突;若是是在原來 server 增長 zone,則要保證 zone 之間不衝突,如:
. {} .:54 {}
另外一個 server 運行於 54 端口並負責根域 .
的解析。
又如:
example.org { whoami } org { whoami }
同一個 server 可是負責不一樣 zone 的解析,有不一樣插件鏈。
跟其餘 DNS 服務器相似,Corefile 也能夠定義 Reverse Zone
(反向解析 IP 地址對應的域名):
0.0.10.in-addr.arpa { whoami }
或者簡化版本:
10.0.0.0/24 { whoami }
能夠經過 dig
進行反向查詢:
$ dig -x 10.0.0.1
CoreDNS 除了支持 DNS 協議,也支持 TLS
和 gRPC
,即 DNS-over-TLS 和 DNS-over-gRPC 模式:
tls://example.org:1443 { #... }
當 CoreDNS 啓動後,它將根據配置文件啓動不一樣 server ,每臺 server 都擁有本身的插件鏈。當有 DNS 請求時,它將依次經歷以下 3 步邏輯:
請求被當前插件處理
插件將生成對應的響應並回給客戶端,此時請求結束,下一個插件將不會被調用,如 whoami 插件;
請求被當前插件以 Fallthrough 形式處理
若是請求在該插件處理過程當中有可能將跳轉至下一個插件,該過程稱爲 fallthrough,並以關鍵字 fallthrough
來決定是否容許此項操做,例如 host 插件,當查詢域名未位於 /etc/hosts,則調用下一個插件;
請求在處理過程被攜帶 Hint
請求被插件處理,並在其響應中添加了某些信息(hint)後繼續交由下一個插件處理。這些額外的信息將組成對客戶端的最終響應,如 metric
插件;
若是 Corefile 爲:
coredns.io:5300 { file db.coredns.io } example.io:53 { log errors file db.example.io } example.net:53 { file db.example.net } .:53 { kubernetes proxy . 8.8.8.8 log health errors cache }
從配置文件來看,咱們定義了兩個 server(儘管有 4 個區塊),分別監聽在 5300
和 53
端口。其邏輯圖可以下所示:
每一個進入到某個 server 的請求將按照 plugin.cfg
定義順序執行其已經加載的插件。
從上圖,咱們須要注意如下幾點:
.:53
配置了 health
插件,可是它併爲在上面的邏輯圖中出現,緣由是:該插件並未參與請求相關的邏輯(即並無在插件鏈上),只是修改了 server 配置。更通常地,咱們能夠將插件分爲兩種:
health
,tls
等插件;既然 CoreDNS 如此優秀,我用它來抵禦偉大的防火長城豈不美哉?研究了一圈,發現技術上仍是可行的,惟一的一個缺點是不支持使用代理,不過你能夠經過 proxychians-ng 或 proxifier 來強制使用代理。下面開始折騰。
具體的思路其實很是簡單,就是將國內的域名查詢請求轉發到 114 等國內的公共 DNS 服務器,將國外的域名查詢請求轉發到 8.8.8.8 等國外的公共 DNS 服務器。然而 CoreDNS 的插件鏈有點反直覺,同一個插件鏈上的每個插件只能出現一次,若是隻使用 forward
插件是知足不了需求的。
CoreDNS 原來還有個插件叫 proxy
,功能和 forward
相似,目測好像同時利用 proxy
和 forward
插件就能夠實現咱的需求了。但理想與現實的差距老是很大,不知道從何時開始,CoreDNS 官方編譯的二進制文件已經沒有 proxy
插件了,真是氣人。
偶然間發現了一個第三方插件 dnsredir,目測能夠解決個人全部問題。該插件綜合了 proxy
和 forward
插件的全部優勢,支持 UDP、TCP、DNS-over-TLS 和 DNS-over-HTTPS,也支持多個後端,還具有健康檢查和故障轉移的功能,真是太香了!
它的語法是這樣的:
dnsredir FROM... { to TO... }
FROM...
是一個文件列表,包含了匹配的域名和解析該域名的服務器,說白了就是 dnsmasq 所使用的格式,直接看例子:
server=/0-100.com/114.114.114.114 server=/0-100.com/114.114.114.114
爲何要用這種格式呢?固然是爲了方便啦。
爲何這樣會方便呢?固然是爲了能夠直接用上 FelixOnMars的大陸區域名列表了。。。FelixOnMars 同時還提供了 Google
和 Apple
的域名列表,這在某些地區某些ISP能夠獲得國內鏡像的 IP,從而加速訪問,想一想就刺激。
固然,除了使用文件列表外,還可使用 .
,相似於上面所說的根域。這個插件最大的亮點是能夠在插件鏈中重複使用 dnsredir 插件,只要 FROM...
不重複就行。
to TO...
用來將 DNS 解析請求發給上游 DNS 服務器。支持幾乎全部 DNS 協議,例如:
dns://1.1.1.1 8.8.8.8 tcp://9.9.9.9 udp://2606:4700:4700::1111 tls://1.1.1.1@one.one.one.one tls://8.8.8.8 tls://dns.quad9.net doh://cloudflare-dns.com/dns-query json-doh://1.1.1.1/dns-query json-doh://dns.google/resolve ietf-doh://dns.quad9.net/dns-query
dnsredir 雖香,但你們別忘了,它是第三方插件,官方默認的二進制文件是不包含該插件的。你能夠選擇本身編譯,但若是常常須要升級怎麼辦?總不能每次都手動編譯吧,也太累了。
好在有位大佬已經經過 CI/CD
流程將所需的第三方插件都集成編譯進去了,並按期更新,簡直就是我等的福音。大佬的項目地址爲:
如今只須要下載對應操做系統的二進制文件,處處拷貝,就能夠運行了。
下面通通以 MacOS 爲例做講解。Openwrt
的玩法也同樣,參考本文的方法論便可,具體本文就不展開了。
直接下載二進制文件:
$ wget 'https://appveyorcidatav2.blob.core.windows.net/missdeer-15199/coredns-custom-build/1-7-1-514/idbodwxwywg1xgdg/distrib/coredns-linux-amd64.zip?sv=2015-12-11&sr=c&sig=BhMWcOVtDuaETyz2DcjpOr9GdvkpNVOqoIa7iWFpFNQ%3D&st=2020-12-23T15%3A26%3A19Z&se=2020-12-23T15%3A32%3A19Z&sp=r' $ $ tar zxf coredns-linux-amd64.zip $ mv coredns-linux-amd64/coredns /usr/local/bin/
要深刻了解 CoreDNS,請查看其文檔,及 plugins 的介紹。下面是個人配置文件:
cat > /usr/local/etc/Corefile <<EOF # https://coredns.io/plugins/cache/ (global_cache) { cache { # [5, 60] success 65536 3600 300 # [1, 10] denial 8192 600 60 prefetch 1 60m 10% } } .:7913 { ads { default-lists blacklist https://raw.githubusercontent.com/privacy-protection-tools/anti-AD/master/anti-ad-domains.txt whitelist https://files.krnl.eu/whitelist.txt log auto-update-interval 24h list-store ads-cache } errors hosts { fallthrough } health prometheus :9153 import global_cache template ANY AAAA { rcode NXDOMAIN } dnsredir accelerated-domains.china.conf google.china.conf apple.china.conf mydns.conf { expire 15s max_fails 3 health_check 3s policy round_robin path_reload 2s to 114.114.114.114 223.5.5.5 119.29.29.29 } dnsredir . { expire 60s max_fails 5 health_check 5s policy random spray to tls://8.8.8.8@dns.google tls://8.8.4.4@dns.google to tls://1.1.1.1@1dot1dot1dot1.cloudflare-dns.com tls://1.0.0.1@1dot1dot1dot1.cloudflare-dns.com # Global TLS server name # tls_servername cloudflare-dns.com } log loop reload 6s } EOF
hosts
是 CoreDNS 的一個 plugin,這一節的意思是加載 /etc/hosts
文件裏面的解析信息。hosts 在最前面,則若是一個域名在 hosts 文件中存在,則優先使用這個信息返回;hosts
中找不到,則進入下一個 plugin 繼續。缺乏這一個指令,後面的 plugins 配置就無心義了;mydns.conf
。第二段 dnsredir 配置表示默認的解析配置,能夠理解爲故障轉移,若是某個域名沒有匹配到任何一個文件列表,就使用第二段 dnsredir 的上游 DNS 服務器進行解析。經過這樣的配置方式,就實現了將國內的域名查詢請求轉發到 114 等國內的公共 DNS 服務器,將國外的域名查詢請求轉發到 8.8.8.8 等國外的公共 DNS 服務器。講一下我本身的理解:
fallthrough
關鍵字流向下一個 plugin;注意:該方案的前提是可以強制讓 CoreDNS 使用代理,或者更精確一點,讓 8.8.8.8 和 8.8.4.4 使用代理。這裏的方法比較複雜一點,本文就不介紹了。若是你實在不知道怎麼辦,能夠將 8.8.8.8 這一行刪除,直接使用 Cloudflare 提供的 DNS 服務,雖然響應有點慢,但好在能夠訪問。
若是你沒法忍受 Cloudflare 的響應速度,能夠考慮使用國內的無污染 DNS:紅魚 DNS。而後直接一勞永逸:
cat > /usr/local/etc/Corefile <<EOF # https://coredns.io/plugins/cache/ (global_cache) { cache { # [5, 60] success 65536 3600 300 # [1, 10] denial 8192 600 60 prefetch 1 60m 10% } } .:7913 { ads { default-lists blacklist https://raw.githubusercontent.com/privacy-protection-tools/anti-AD/master/anti-ad-domains.txt whitelist https://files.krnl.eu/whitelist.txt log auto-update-interval 24h list-store ads-cache } errors hosts { fallthrough } health prometheus :9153 import global_cache template ANY AAAA { rcode NXDOMAIN } dnsredir accelerated-domains.china.conf google.china.conf apple.china.conf mydns.conf { expire 15s max_fails 3 health_check 3s policy round_robin path_reload 2s to 114.114.114.114 223.5.5.5 119.29.29.29 } dnsredir . { expire 60s max_fails 5 health_check 5s policy random spray to doh://13800000000.rubyfish.cn } log loop reload 6s } EOF
這樣 CoreDNS 就不用擔憂走代理的問題了。
大陸域名列表天天都會更新,因此還須要寫個腳原本更新文件列表。不用檢查文件是否存在了,直接簡單粗暴無腦更新:
$ cat > /usr/local/bin/update_coredns.sh <<EOF #!/bin/bash rm accelerated-domains.china.conf wget https://cdn.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/accelerated-domains.china.conf -O /usr/local/etc/accelerated-domains.china.conf rm apple.china.conf wget https://cdn.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/apple.china.conf -O /usr/local/etc/apple.china.conf rm google.china.conf wget https://cdn.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/google.china.conf -O /usr/local/etc/google.china.conf EOF $ sudo chmod +x /usr/local/bin/update_coredns.sh
先執行一遍該腳本,更新 Corefile 的配置:
$ /usr/local/bin/update_coredns.sh
而後經過 Crontab
製做定時任務,每隔兩天下午兩點更新域名列表:
$ crontab -l 0 14 */2 * * /usr/local/bin/update_coredns.sh
MacOS 可使用 launchctl 來管理服務,它能夠控制啓動計算機時須要開啓的服務,也能夠設置定時執行特定任務的腳本,就像 Linux crontab 同樣, 經過加裝 *.plist
文件執行相應命令。Launchd 腳本存儲在如下位置, 默認須要本身建立我的的 LaunchAgents
目錄:
~/Library/LaunchAgents
: 由用戶本身定義的任務項/Library/LaunchAgents
: 由管理員爲用戶定義的任務項/Library/LaunchDaemons
: 由管理員定義的守護進程任務項/System/Library/LaunchAgents
: 由 MacOS 爲用戶定義的任務項/System/Library/LaunchDaemons
: 由 MacOS 定義的守護進程任務項咱們選擇在 /Library/LaunchAgents/
目錄下建立 coredns.plist
文件,內容以下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>coredns</string> <key>ProgramArguments</key> <array> <string>/usr/local/bin/coredns</string> <string>-conf</string> <string>/usr/local/etc/Corefile</string> </array> <key>StandardOutPath</key> <string>/var/log/coredns.stdout.log</string> <key>StandardErrorPath</key> <string>/var/log/coredns.stderr.log</string> <key>KeepAlive</key> <true/> <key>RunAtLoad</key> <true/> </dict> </plist>
設置開機自動啓動 coredns:
$ sudo launchctl load -w /Library/LaunchAgents/coredns.plist
查看服務:
$ sudo launchctl list|grep coredns 61676 0 coredns
$ sudo launchctl list coredns { "StandardOutPath" = "/var/log/coredns.stdout.log"; "LimitLoadToSessionType" = "System"; "StandardErrorPath" = "/var/log/coredns.stderr.log"; "Label" = "coredns"; "TimeOut" = 30; "OnDemand" = false; "LastExitStatus" = 0; "PID" = 61676; "Program" = "/usr/local/bin/coredns"; "ProgramArguments" = ( "/usr/local/bin/coredns"; "-conf"; "/usr/local/etc/Corefile"; ); };
查看端口號:
$ sudo ps -ef|egrep -v grep|grep coredns 0 81819 1 0 2:54下午 ?? 0:04.70 /usr/local/bin/coredns -conf /usr/local/etc/Corefile $ sudo lsof -P -p 81819|egrep "TCP|UDP" coredns 81819 root 5u IPv6 0x1509853aadbdf853 0t0 TCP *:5302 (LISTEN) coredns 81819 root 6u IPv6 0x1509853acd2f39ab 0t0 UDP *:5302 coredns 81819 root 7u IPv6 0x1509853aadbdc493 0t0 TCP *:53 (LISTEN) coredns 81819 root 8u IPv6 0x1509853acd2f5a4b 0t0 UDP *:53 coredns 81819 root 9u IPv6 0x1509853ac63bfed3 0t0 TCP *:5301 (LISTEN) coredns 81819 root 10u IPv6 0x1509853acd2f5d03 0t0 UDP *:5301
大功告成,如今你只須要將系統的 DNS IP 設置爲 127.0.0.1
就能夠了。
$ doggo www.youtube.com @udp://127.0.0.1 NAME TYPE CLASS TTL ADDRESS NAMESERVER www.youtube.com. CNAME IN 293s youtube-ui.l.google.com. 127.0.0.1:53 youtube-ui.l.google.com. A IN 293s 172.217.14.110 127.0.0.1:53 youtube-ui.l.google.com. A IN 293s 172.217.11.174 127.0.0.1:53 youtube-ui.l.google.com. A IN 293s 172.217.5.206 127.0.0.1:53 youtube-ui.l.google.com. A IN 293s 172.217.5.78 127.0.0.1:53 youtube-ui.l.google.com. A IN 293s 172.217.14.78 127.0.0.1:53 youtube-ui.l.google.com. A IN 293s 142.250.72.238 127.0.0.1:53 youtube-ui.l.google.com. A IN 293s 216.58.193.206 127.0.0.1:53 youtube-ui.l.google.com. A IN 293s 142.250.68.110 127.0.0.1:53 youtube-ui.l.google.com. A IN 293s 142.250.68.78 127.0.0.1:53 youtube-ui.l.google.com. A IN 293s 172.217.4.142 127.0.0.1:53 youtube-ui.l.google.com. A IN 293s 142.250.68.14 127.0.0.1:53
搞定。
什麼?你問我 doggo
是個啥?掃描下方二維碼關注公衆號:
公衆號後臺回覆 doggo 便可獲取你想要的東西😬
Kubernetes 1.18.2 1.17.5 1.16.9 1.15.12離線安裝包發佈地址http://store.lameleg.com ,歡迎體驗。 使用了最新的sealos v3.3.6版本。 做了主機名解析配置優化,lvscare 掛載/lib/module解決開機啓動ipvs加載問題, 修復lvscare社區netlink與3.10內核不兼容問題,sealos生成百年證書等特性。更多特性 https://github.com/fanux/sealos 。歡迎掃描下方的二維碼加入釘釘羣 ,釘釘羣已經集成sealos的機器人實時能夠看到sealos的動態。