理解OpenShift(1):網絡之 Router 和 Routehtml
理解OpenShift(2):網絡之 DNS(域名服務)node
理解OpenShift(4):用戶及權限管理github
理解OpenShift(5):從 Docker Volume 到 OpenShift Persistent Volumedocker
** 本文基於 OpenShift 3.11,Kubernetes 1.11 進行測試 ***後端
OpenShift 集羣中,至少有三個地方須要用到 DNS:api
本文就從這三點出發,解釋 OpenShift 是如何實現這三種DNS功能的。緩存
在Linux 系統上,當一個應用經過域名鏈接遠端主機時,DNS 解析會經過系統調用來進行,好比 getaddrinfo()。
和任何Linux 操做系統同樣,Pod 的 DNS 定義在 resolv.conf 文件中,其示例以下:服務器
sh-4.2$ cat /etc/resolv.conf nameserver 172.22.122.9 search dev.svc.cluster.local svc.cluster.local cluster.local exampleos.com options ndots:5
其中,微信
默認地,許多DNS 解析器若是發現被解析的域名中有任何的點(.)就把它當作一個 FQDN 來解析;若是域名中沒有任何點,就把它當作 PQDN 來處理,而且會加上系統的默認domain name 和最後的點,來組成 FQDN。若是沒有指定默認的 domain name (經過 domain 字段)或查詢失敗,則會將 search 字段的第一個值當作默認domain name,若是解析不成功,則依次往下試,直到有一個成功或者所有失敗爲止。
這個行爲是經過 options ndots 來指定的,其默認值爲1,這意味着只要被解析域名中有任何一個點(.),那麼它就會被當作 FQDN,而不會附加任何 search domain,直接用來查詢。OpenShift 環境中,這個值被設置爲 5。這意味着,只要被解析域名中包含不超過五個點,該域名就會被當作PQDN,而後挨個使用 search domain,來組裝成 FQDN 來作DNS查詢。若是所有不成功過,則會嘗試將它直接做爲 FQDN 來解析。
[root@node2 cloud-user]# cat /etc/resolv.conf # nameserver updated by /etc/NetworkManager/dispatcher.d/99-origin-dns.sh # Generated by NetworkManager search cluster.local exampleos.com nameserver 172.22.122.9
在部署環境時,會在每一個節點上部署 /etc/NetworkManager/dispatcher.d/99-origin-dns.sh 文件。每當節點上的 NetworkManager 服務啓動時,該文件會被運行。它的任務包括:
也就是說,宿主機上的 DNS 請求也會轉到本機上的 53 端口。
宿主機上的 53 端口上,dnsmasq 服務在route 默認路由的全部IP的53端口上偵聽。其中一個負責接受並處理宿主機上全部pod 中以及宿主機上的全部DNS查詢服務。
tcp 0 0 10.128.2.1:53 0.0.0.0:* LISTEN 906/dnsmasq
tcp 0 0 172.17.0.1:53 0.0.0.0:* LISTEN 906/dnsmasq
tcp 0 0 172.22.122.9:53 0.0.0.0:* LISTEN 906/dnsmasq
這些 IP 地址和默認路由IP 地址是符合的:
10.128.0.0 0.0.0.0 255.252.0.0 U 0 0 0 tun0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0 172.22.122.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0 172.30.0.0 0.0.0.0 255.255.0.0 U 0 0 0 tun0
dnsmasq 服務的配置目錄爲 /etc/dnsmasq.d。其中有兩個配置文件(具體含義請查閱有關文檔):
[root@node2 dnsmasq.d]# cat origin-dns.conf no-resolv domain-needed no-negcache max-cache-ttl=1 enable-dbus dns-forward-max=10000 cache-size=10000 bind-dynamic min-port=1024 except-interface=lo # End of config
文件 origin-upstream-dns.conf 中定義了上游(upstream) DNS 名字服務器:
[root@node2 dnsmasq.d]# cat origin-upstream-dns.conf server=172.22.122.3 server=172.22.122.2 server=172.22.122.4
這些上游服務器的地址是從 DHCP 服務器中獲取到的(個人OpenShift 環境搭建在OpenStack虛擬機中。前兩個地址是OpenStack neutron 網絡的 DNSmasq 地址,最後一個是單獨搭建的 bind9 DNS 服務器地址)。
在早期版本中(個人OpenShift版本是 3.11),還有一個配置文件 node-dnsmasq.conf :
server=/in-addr.arpa/127.0.0.1 server=/cluster.local/127.0.0.1
這意味着全部以 cluster.local 和 in-addr.arpa 結尾的域名,都會被轉到 127.0.0.1:53 上被解析。而其它的解析請求,會被轉到在 origin-upstream-dns.conf 中定義的上游 DNS 服務器。
個人3.11版本環境中並無生成該文件。從代碼 https://github.com/openshift/origin/blob/master/pkg/dns/dnsmasq.go 看,OpenShift 中的 dnsmasq 在啓動時會自動添加這兩條記錄:
而 dnsIP 和 dnsDomain 應該是在 /etc/origin/node/node-config.yaml 中的以下配置:
dnsBindAddress: 127.0.0.1:53 dnsDomain: cluster.local
Dec 3 14:10:57 dnsmasq[29595]: using nameserver 127.0.0.1#53 for domain in-addr.arpa Dec 3 14:10:57 dnsmasq[29595]: using nameserver 127.0.0.1#53 for domain cluster.local
從上面的分析可見,在 node 節點上的 dnsmasq,其實只是一個DNS 查詢轉發器(轉到上游DNS 服務器或者本機上的 SkyDns)和結果緩存器,它自己並不保存域名的原始記錄。
關於 SkyDNS:它是一個開源的構建在 etcd 之上的分佈式服務宣告(announcement)和發現(discovery)服務。利用它,能夠經過 DNS 查詢來發現可用的服務。其開源社區的地址是 https://github.com/skynetservices/skydns。社區版本的 SkyDns 將記錄保存在 etcd 中,在作查詢時從etcd 獲取數據並封裝成 DNS 結果格式給客戶端。
SkyDNS 的 server 部分支持被做爲庫文件使用,此時能夠爲其實現其它後端。在OpenShift 中並無採用默認的 etcd 後端,而是基於 OpenShift API 服務實現了新的後端,其代碼在https://github.com/openshift/origin/blob/master/pkg/dns/ 。SkyDns 調用 OpenShift API 服務來獲取主機名、IP地址等信息,而後封裝成標準 DNS 記錄並返回給查詢客戶端。
tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 17182/openshift
Node 節點上的 SkyDN 要麼從cache 中直接回答 DNS 查詢,要麼調用 OpenShift API 服務來獲取數據再返回。
resolv.conf 文件同Node 節點上的:
[root@master1 cloud-user]# cat /etc/resolv.conf # nameserver updated by /etc/NetworkManager/dispatcher.d/99-origin-dns.sh # Generated by NetworkManager search cluster.local haihangyun.cn exampleos.com nameserver 172.22.122.5
dnsmasq 在多個IP 地址的 53 端口上偵聽,爲本機上的以及本機上Pod 中的DNS查詢服務:
udp 0 0 10.128.0.1:53 0.0.0.0:* 866/dnsmasq udp 0 0 172.17.0.1:53 0.0.0.0:* 866/dnsmasq udp 0 0 172.22.122.5:53 0.0.0.0:* 866/dnsmasq
和 Node 節點不一樣,Master 節點上有兩個SkyDns 進程。一個在 127.0.0.1:53 偵聽,負責本機上的集羣內服務的DNS查詢,由於 Master 節點同時承擔 node 節點的角色:
udp 0 0 127.0.0.1:53 0.0.0.0:* 11700/openshift
Dec 3 14:50:41 dnsmasq[10607]: using nameserver 127.0.0.1#53 for domain cluster.local Dec 3 14:50:41 dnsmasq[10607]: using nameserver 127.0.0.1#53 for domain in-addr.arpa
另外一個是在全部網卡的 8053 端口上偵聽,這是由於Master 還具備 master api 角色:
udp 0 0 0.0.0.0:8053 0.0.0.0:* 15096/openshift
對於這個 SkyDns 進程的做用尚不清楚,還需進一步研究。從已有資料上看看,全部節點上都須要安裝 SkyDns,並組成一個分佈式集羣。由於 Master 節點上的 53 端口被另外一個 SkyDns 進程佔用,所以換到了端口8053。
流程示意圖如最上面圖中的 1 和 2.1 部分所示。
dnsmasq 日誌:
Nov 21 11:03:44 dnsmasq[17788]: using nameserver 172.22.122.3#53 Nov 21 11:03:44 dnsmasq[17788]: using nameserver 172.22.122.2#53 Nov 21 11:03:44 dnsmasq[17788]: using nameserver 172.22.122.4#53 Nov 21 11:03:49 dnsmasq[17788]: query[A] www.sina.com from 172.22.122.13 Nov 21 11:03:49 dnsmasq[17788]: forwarded www.sina.com to 172.22.122.4 Nov 21 11:03:49 dnsmasq[17788]: forwarded www.sina.com to 172.22.122.2 Nov 21 11:03:49 dnsmasq[17788]: forwarded www.sina.com to 172.22.122.3 Nov 21 11:03:49 dnsmasq[17788]: reply spool.grid.sinaedge.com is 124.228.42.248
能看到 node 上的 dnsmasq 直接將查詢請求轉發給上游 DNS 名字服務器。由於存在多個名字服務器,因此是依次查詢,直到成功爲止。從日誌看,其查詢順序和配置文件中的順序是相反的。
流程示意圖如上圖中的 1 + 2.2 + 3 部分所示。
日誌實例:
(1)從一個 pod 中 ping registry-console服務的域名 registry-console.default.svc.cluster.local。
(2)Node宿主機(IP 地址爲 172.22.122.13)上的 dnsmasq 收到該查詢。
(3)dnsmasq 將查詢轉到 127.0.0.1:53 上的 SkyDns 服務。
(4)SkyDNS 作查詢。SkyDNS 能接收的域名格式:<prefix>.<service_name>.<namespace>.(svc|endpoints|pod).<base>,這意味着它支持查詢服務(svc)、端點(endpoints)和 pod 的 DNS信息。
查詢結果:
[root@node2 cloud-user]# nsenter -t 4216 -n dig mybank.dev.svc.cluster.local ;; QUESTION SECTION: ;mybank.dev.svc.cluster.local. IN A ;; ANSWER SECTION: mybank.dev.svc.cluster.local. 30 IN A 172.30.162.172 ;; Query time: 1 msec ;; SERVER: 172.22.122.9#53(172.22.122.9) ;; WHEN: Mon Dec 03 11:43:01 CST 2018 ;; MSG SIZE rcvd: 62
dnsmasq 日誌:
Dec 3 14:19:44 dnsmasq[29595]: query[A] mybank.dev.svc.cluster.local from 10.128.2.128 Dec 3 14:19:44 dnsmasq[29595]: forwarded mybank.dev.svc.cluster.local to 127.0.0.1 Dec 3 14:19:44 dnsmasq[29595]: reply mybank.dev.svc.cluster.local is 172.30.162.172
(5)其它實驗:查詢服務的全部端點
查詢結果:
[root@node2 cloud-user]# nsenter -t 4216 -n dig jenkins.dev.endpoints.cluster.local ;; QUESTION SECTION: ;jenkins.dev.endpoints.cluster.local. IN A ;; ANSWER SECTION: jenkins.dev.endpoints.cluster.local. 30 IN A 10.128.2.81 jenkins.dev.endpoints.cluster.local. 30 IN A 10.131.1.70
dnsmasq 日誌:
Dec 3 14:20:48 dnsmasq[29595]: query[A] jenkins.dev.endpoints.cluster.local from 10.128.2.128 Dec 3 14:20:48 dnsmasq[29595]: forwarded jenkins.dev.endpoints.cluster.local to 127.0.0.1 Dec 3 14:20:48 dnsmasq[29595]: reply jenkins.dev.endpoints.cluster.local is 10.128.2.81 Dec 3 14:20:48 dnsmasq[29595]: reply jenkins.dev.endpoints.cluster.local is 10.131.1.70
(6)查詢 pod
待查詢的pod域名的格式爲 <IP_with_dashes>.<namespace>.pod.<base>,SkyDns 會返回其IP 地址,但我沒明白這麼作的場景和價值,也許是確認pod是否存在?
查詢結果:
[root@node2 cloud-user]# nsenter -t 4216 -n dig 172-30-162-172.dev.pod.cluster.local ;; QUESTION SECTION: ;172-30-162-172.dev.pod.cluster.local. IN A ;; ANSWER SECTION: 172-30-162-172.dev.pod.cluster.local. 30 IN A 172.30.162.172 ;; Query time: 1 msec ;; SERVER: 172.22.122.9#53(172.22.122.9) ;; WHEN: Mon Dec 03 13:32:05 CST 2018 ;; MSG SIZE rcvd: 70
dnsmasq 日誌:
Dec 3 14:22:24 dnsmasq[29595]: query[A] 172-30-162-172.dev.pod.cluster.local from 10.128.2.128 Dec 3 14:22:24 dnsmasq[29595]: forwarded 172-30-162-172.dev.pod.cluster.local to 127.0.0.1 Dec 3 14:22:24 dnsmasq[29595]: reply 172-30-162-172.dev.pod.cluster.local is 172.30.162.172
(7)對比 FQDN 和 PQDN
這個 PQDN 被加上了搜索域名再進行查詢,能返回正確的IP地址:
[root@node2 cloud-user]# nsenter -t 4216 -n ping mybank.dev.svc PING mybank.dev.svc.cluster.local (172.30.162.172) 56(84) bytes of data.
而這個 FQDN 被直接作DNS查詢,結果查詢失敗,未能獲取IP地址:
[root@node2 cloud-user]# nsenter -t 4216 -n ping mybank.dev.svc. ping: mybank.dev.svc.: Name or service not known
能夠看出,該過程當中只涉及到外部DNS將服務的公共域名解析爲 OpenShift Router 所在節點的公網地址,後面 HAProxy 做爲代理,直接經過 IP 訪問pod,並將結果返回客戶端。
參考文檔:
感謝您的閱讀,歡迎關注個人微信公衆號: