Kubernetes如何實現DNS解析
導讀 | 最近在處理 Kuberntes 中的 DNS 解析問題, 正好借這個機會學習下 Kubernetes 中的 DNS 伺服器工作原理。 |
我對解析過程的瞭解也比較粗淺, 僅介紹下配置中的內容.
眾所周知, DNS 伺服器用於將域名轉換為 IP (具體為啥要轉換建議複習下 7 層網路模型). 伺服器中 DNS 解析配置位於/etc/resolv.conf, 在 Pod 中也不例外, 下面是某個 Pod 中的配置:
nameserver 10.96.0.10 search kube-system.svc.cluster.local svc.cluster.local cluster.local options ndots:5
假如我們平時想要修改自己本機上的 DNS 伺服器, 比如想要修改為8.8.8.8, 就會這麼去修改:
nameserver 8.8.8.8 nameserver 8.8.4.4
如果想要除錯 DNS 伺服器, 測試返回結果, 可以使用 dig 工具:
> dig baidu.com @8.8.8.8 ; <<>> DiG 9.16.10 <<>> baidu.com @8.8.8.8 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5114 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 512 ;; QUESTION SECTION: ;baidu.com. IN A ;; ANSWER SECTION: baidu.com. 159 IN A 39.156.69.79 baidu.com. 159 IN A 220.181.38.148 ;; Query time: 10 msec ;; SERVER: 8.8.8.8#53(8.8.8.8) ;; WHEN: Tue Jan 12 09:26:13 HKT 2021 ;; MSG SIZE rcvd: 70
DNS 伺服器 – nameserver
我們先從nameserver 10.96.0.10來看, 為什麼請求這個地址可以進行 DNS 解析. 這個答案就是 iptables, 我僅擷取 UDP 的 53 埠, 以下內容可以透過iptables-save獲得.
A KUBE-SERVICES -d 10.96.0.10/32 -p udp -m comment --comment "kube-system/kube-dns:dns cluster IP" -m udp --dport 53 -j KUBE-SVC-TCOU7JCQXEZGVUNU # 簡單解釋下, 這條規則表示, 如果目標地址是 10.96.0.10的udp53埠, 那麼就會跳轉到這條鏈上`KUBE-SVC-TCOU7JCQXEZGVUNU`
我們再看下這條鏈KUBE-SVC-TCOU7JCQXEZGVUNU:
-A KUBE-SVC-TCOU7JCQXEZGVUNU -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-Q3HNNZPXUAYYDXW2 -A KUBE-SVC-TCOU7JCQXEZGVUNU -j KUBE-SEP-BBR3Z5NWFGXGVHEZ -A KUBE-SEP-Q3HNNZPXUAYYDXW2 -p udp -m udp -j DNAT --to-destination 172.32.3.219:53 -A KUBE-SEP-BBR3Z5NWFGXGVHEZ -p udp -m udp -j DNAT --to-destination 172.32.6.239:53 # 聯絡之前的規則, 這幾條規則完整的意思是: # 本機中, 發給10.96.0.10:53的流量, 一半轉發到172.32.3.219:53, 另一半轉發到172.32.6.239:53
再看下我們的 Kubernetes 中 Pod 的 IP 地址, 也就是說, DNS 請求實際上會到我們的 Coredns 容器中被處理.
> kubectl -n kube-system get pods -o wide | grep dns coredns-646bc69b8d-jd22w 1/1 Running 0 57d 172.32.6.239 m1coredns-646bc69b8d-p8pqq 1/1 Running 8 315d 172.32.3.219 m2
再檢視下對應的 Service, 可以看到, 上述機器中的 Iptables 其實就是 Service 的具體實現方式.
> kubectl -n kube-system get svc | grep dns kube-dns ClusterIP 10.96.0.1053/UDP,53/TCP,9153/TCP 398d
可能有人會有疑問, 現在是 2 個 Pod 可以均分流量, 如果是 3 個, 4 個 Pod, Iptables 是如何做轉發的呢, 正好我有這個疑問, 因此我就再加了 2 個 Pod, 看看iptables是怎麼實現對於 4 個 Pod 均分流量的.
這是最後的實現方式:
-A KUBE-SVC-TCOU7JCQXEZGVUNU -m statistic --mode random --probability 0.25000000000 -j KUBE-SEP-HTZHQHQPOHVVNWZS -A KUBE-SVC-TCOU7JCQXEZGVUNU -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-3VNFB2SPYQJRRPK6 -A KUBE-SVC-TCOU7JCQXEZGVUNU -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-Q3HNNZPXUAYYDXW2 -A KUBE-SVC-TCOU7JCQXEZGVUNU -j KUBE-SEP-BBR3Z5NWFGXGVHEZ
透過這樣的方式對流量進行了均分, 還是挺巧妙的, 這樣, 5個,10個也是可以依次去分的.
search kube-system.svc.cluster.local svc.cluster.local cluster.local options ndots:5
詳細的介紹可以看這裡: resolv.conf 手冊, 我簡單的說下我的理解.
假如沒有這個search引數, 我們查詢時:
> ping kube-dns ping: kube-dns: Name or service not known
如果增加了search引數後, 再去查詢:
> ping kube-dns PING kube-dns.kube-system.svc.psigor-dev.nease.net (10.96.0.10) 56(84) bytes of data.
可以看到, 解析域名時, 如果給定的域名無法查詢, 會新增search後面的字尾進行查詢(假如以.結尾, 類似kube-dns., 這樣的域名不會再去嘗試, FQDN域名).
search的工作就是幫我們去嘗試, 用在 Kubenetes 中, 配置kube-system.svc.cluster.local svc.cluster.local cluster.local 就會幫我們嘗試, 我們ping abc, 就會這樣進行查詢
[INFO] 10.202.37.232:50940 - 51439 "A IN abc.kube-system.svc.cluster.local. udp 51 false 512" NXDOMAIN qr,aa,rd 144 0.000114128s [INFO] 10.202.37.232:51823 - 54524 "A IN abc.svc.cluster.local. udp 39 false 512" NXDOMAIN qr,aa,rd 132 0.000124048s [INFO] 10.202.37.232:41894 - 15434 "A IN abc.cluster.local. udp 35 false 512" NXDOMAIN qr,aa,rd 128 0.000092304s [INFO] 10.202.37.232:40357 - 43160 "A IN abc. udp 21 false 512" NOERROR qr,aa,rd,ra 94 0.000163406s
search配置需要與ndots一起使用, 預設的ndots是 1, 它的作用是: 如果檢查到被查詢的域名中dot的數量小於該值時, 就會優先嚐試新增search域中的字尾.
Resolver queries having fewer than ndots dots (default is 1) in them will be attempted using each component of the search path in turn until a match is found.
假如我們的 DNS 配置如下:
search kube-system.svc.cluster.local svc.cluster.local cluster.local options ndots:2
當我們ping abc.123(此域名只有一個 dot ), DNS 伺服器的日誌如下, 可以注意到日誌中最先嚐試的是abc.123.kube-system.svc.cluster.local., 最後才會嘗試我們的域名.
[INFO] 10.202.37.232:33386 - 36445 "A IN abc.123.kube-system.svc.cluster.local. udp 55 false 512" NXDOMAIN qr,aa,rd 148 0.001700129s [INFO] 10.202.37.232:51389 - 58489 "A IN abc.123.svc.cluster.local. udp 43 false 512" NXDOMAIN qr,aa,rd 136 0.001117693s [INFO] 10.202.37.232:32785 - 4976 "A IN abc.123.cluster.local. udp 39 false 512" NXDOMAIN qr,aa,rd 132 0.001047215s [INFO] 10.202.37.232:57827 - 56555 "A IN abc.123. udp 25 false 512" NXDOMAIN qr,rd,ra 100 0.001763186s
那我們ping abc.123.def(此域名有兩個 dot), DNS 伺服器的日誌像下面這樣, 注意到日誌中最優先嚐試的是abc.123.def.
[INFO] 10.202.37.232:39314 - 794 "A IN abc.123.def. udp 29 false 512" NXDOMAIN qr,rd,ra 104 0.025049846s [INFO] 10.202.37.232:51736 - 61456 "A IN abc.123.def.kube-system.svc.cluster.local. udp 59 false 512" NXDOMAIN qr,aa,rd 152 0.001213934s [INFO] 10.202.37.232:53145 - 26709 "A IN abc.123.def.svc.cluster.local. udp 47 false 512" NXDOMAIN qr,aa,rd 140 0.001418143s [INFO] 10.202.37.232:54444 - 1145 "A IN abc.123.def.cluster.local. udp 43 false 512" NXDOMAIN qr,aa,rd 136 0.001009799s
希望借這個例子讓大家明白兩點:
無論 ndots 是多少, search 引數中的字尾都會被以此查詢(我們測試時使用了一個不存在的域名, 解析工具嘗試了全部的可能)
ndots 的不妥當設定, 可能會給 DNS 伺服器造成壓力(假如域名是存在的, dns查詢會盡快返回, 不會繼續查詢了, 會減少伺服器壓力)
假如現在 ndots 是 2, 我們想要查詢baidu.com, 由於 dot 數目為 1 小於配置中的 2, 會首先新增字尾進行查詢:
[INFO] 10.202.37.232:42911 - 55931 "A IN baidu.com.kube-system.svc.cluster.local. udp 57 false 512" NXDOMAIN qr,aa,rd 150 0.000116042s [INFO] 10.202.37.232:53722 - 33218 "A IN baidu.com.svc.cluster.local. udp 45 false 512" NXDOMAIN qr,aa,rd 138 0.000075077s [INFO] 10.202.37.232:46487 - 50053 "A IN baidu.com.cluster.local. udp 41 false 512" NXDOMAIN qr,aa,rd 134 0.000067313s [INFO] 10.202.37.232:48360 - 51853 "A IN baidu.com. udp 27 false 512" NOERROR qr,aa,rd,ra 77 0.000127309s
那麼, 我們會產生 3 個無用的 DNS 查詢記錄. 對於DNS伺服器來說, 僅僅是baidu.com這個域名, 流量就變成了4倍. 假如 n繼續增大呢, 就像是Kubernetes中預設給定的5, 那我們會產生更多的無效請求, 因為不只是baidu.com, 就連map.baidu.com, m.map.baidu.com, 這些域名也要從search域中開始嘗試, 會對 DNS 伺服器造成比較大的壓力.
我個人建議:
如果內部服務之間請求十分頻繁, 也就是我們需要經常訪問xxx.svc.cluster.local這樣的域名, 那麼可以保持 ndots 較大.
但是內部服務之間請求比較少時, 強烈建議調小 ndots, 以減少無用流量的產生, 減輕 dns 伺服器的壓力 我個人用的話, 改成 2 就好
很抱歉, 這篇文章的大部分篇幅都是在說 nameserver 是如何解析的, resolv.conf中的內容比較少, 主要原因是我前些天一直在看iptables, 這次正好有, 所以花時間看下, 可能有種想要炫技的心理吧.
解決問題的時候, 理解後面的引數是比較重要的, 我也貼了一些自己的實驗, 希望能對大家有所幫助吧, 至少了解了ndots之後再考慮調優.
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2761103/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 雲解析DNS如何實現智慧解析?DNS
- 什麼是智慧DNS雲解析?雲解析如何實現智慧解析效果?DNS
- 智慧雲解析DNS健康監測是如何實現的?DNS
- shell指令碼實現DNS正向解析指令碼DNS
- 什麼是DNS解析?如何提升DNS解析安全?DNS
- Kubernetes(k8s)如何使用kube-dns實現服務發現K8SDNS
- 如何判斷DNS解析故障?如何解決DNS解析錯誤?DNS
- 智慧雲解析DNS健康監測是如何實現的?-中科三方DNS
- 如何實現Spark on Kubernetes?Spark
- JAVA實現對阿里雲DNS的解析管理Java阿里DNS
- 【中科三方】什麼是雲解析DNS?雲解析DNS有必要購買嗎?如何購買雲解析DNS?DNS
- kubernetes實踐之九:kube-dnsDNS
- DNS解析流程DNS
- DNS解析原理DNS
- Linux---DNS域名解析如何配置LinuxDNS
- 揭秘:如何為 Kubernetes 實現原地升級
- DNS軟體bind-實現DNS伺服器DNS伺服器
- 詳解 DNS 解析DNS
- DNS域名解析DNS
- Dns解析(上) (轉)DNS
- Dns解析(下) (轉)DNS
- DNS解析為什麼不生效?DNS解析不生效原因分析DNS
- 多區域DNS服務,子域授權,快取DNS及Split分離解析的原理和實現DNS快取
- DNS.com和DNS盾免費DNS解析、DNSPOD阿里公共DNS等DNS阿里
- 什麼是容器編排,Kubernetes如何實現
- DNS分層結構及DNS解析流程DNS
- kali實現DNS內網劫持DNS內網
- DNS解析常見問題:如何新增A記錄?DNS
- nslookup命令怎麼用?如何查詢DNS解析故障?DNS
- 主流域名解析庫曝重大DNS投毒漏洞,如何有效應對DNS投毒?DNS
- 雲解析DNS有必要買嗎?雲解析DNS有什麼用?DNS
- c語言winsock 實現解簡域名解析(DNS. v 1.0)C語言DNS
- 搭建Kubernetes叢集時DNS無法解析問題的處理過程DNS
- DNS隧道技術解析DNS
- iOS 本地DNS解析方法iOSDNS
- DNS解析過程原理DNS
- linux實現DNS輪詢實現負載平衡LinuxDNS負載
- 解析最快的dns 最快最穩定的dnsDNS