作用
coreDNS的作用是在集群內(nèi)提供Service和Pod的域名解析服務(wù)敏沉。coreDNS會(huì)監(jiān)聽集群中Service和Pod的創(chuàng)建銷毀事件讯泣,當(dāng)Service或Pod被創(chuàng)建時(shí)系任,記錄對(duì)應(yīng)的解析記錄。當(dāng)其他Pod需要通過(guò)域名訪問(wèn)集群中的Service或Pod時(shí)择示,會(huì)向coreDNS服務(wù)查詢解析記錄播揪,然后訪問(wèn)解析到的IP地址。整個(gè)流程如下
K8S服務(wù)在部署好coreDNS服務(wù)后顾瞪,會(huì)對(duì)外暴露一個(gè)Service舔庶,集群內(nèi)就可以通過(guò)訪問(wèn)該Service的ClusterIP+53端口獲取域名解析服務(wù)。ClusterIP一般是固定的陈醒,在安裝kubelet時(shí)惕橙,會(huì)傳遞--cluster-dns=<cluster-ip> --cluster-domain=<default-local-domain>(默認(rèn)為cluster.local)
參數(shù)給kubelet,kubelet在創(chuàng)建Pod時(shí)孵延,就會(huì)把這兩個(gè)配置寫入到Pod的/etc/resolv.conf
文件中吕漂。
cat /etc/kubernetes/kubelet
可以看到kubelet的配置亲配。
目前k8s支持正向查找(A記錄)尘应,端口查找(SRV記錄)惶凝,反向IP地址查找(PTR記錄)。
K8S中一般只有service和headless service后端的statefulset創(chuàng)建的Pod域名是固定的犬钢,其他Pod域名中都帶有Pod IP苍鲜,Pod重啟后IP改變域名也會(huì)改變,不推薦通過(guò)域名訪問(wèn)玷犹。
coreDNS配置說(shuō)明
Corefile配置
Corefile 是 CoreDNS 的配置文件混滔,它定義了:
- server 以什么協(xié)議監(jiān)聽在哪個(gè)端口(可以同時(shí)定義多個(gè) server 監(jiān)聽不同端口)
- server 負(fù)責(zé)哪個(gè) zone 的權(quán)威(authoritative)DNS 解析
- server 將加載哪些插件
Corefile的配置格式如下
zone:port {
plugin1
plugin2
}
其中zone表示監(jiān)聽的域名,可以是根域名.
歹颓,頂級(jí)域名com
等(一般省略前面的.
)坯屿;port表示server提供服務(wù)的端口,未配置使用默認(rèn)的53端口巍扛。
server和端口是1對(duì)1的關(guān)系领跛,server和zone是1對(duì)多的關(guān)系,即一個(gè)server只監(jiān)聽一個(gè)端口撤奸,一個(gè)server可以負(fù)責(zé)多個(gè)zone的DNS解析吠昭。
正向解析
.: {
log
errors
}
com: {
log
}
.:54 {
log
}
上面的coreDNS配置表示,起兩個(gè)server胧瓜,一個(gè)監(jiān)聽53端口矢棚,提供根域和com域的解析,另一個(gè)監(jiān)聽54端口府喳,負(fù)責(zé)根域的解析蒲肋。
域名解析使用貪心算法。當(dāng)我們?cè)L問(wèn)53端口劫拢,請(qǐng)求www.baidu.com
的解析時(shí)肉津,會(huì)匹配到第二個(gè),即com
域的解析舱沧。匹配成功后妹沙,開始執(zhí)行里面配置的插件,此處記錄一個(gè)log就結(jié)束了熟吏。
反向解析
in-addr.arpa (反向域名解析距糖,從IP地址到域名的映射)
in-addr是inverse address, arpa 的標(biāo)準(zhǔn)名稱對(duì)應(yīng)為Address and Routing Parameter Area, 即“地址路由參數(shù)域”。
由于在域名系統(tǒng)中牵寺,一個(gè)IP地址可以對(duì)應(yīng)多個(gè)域名悍引,因此從IP出發(fā)去找域名,理論上應(yīng)該遍歷整個(gè)域名樹帽氓,但這在 Internet上是不現(xiàn)實(shí)的趣斤。為了完成逆向域名解析,系統(tǒng)提供一個(gè)特別域黎休,該特別域稱為逆向解析域in-addr.arpa浓领。這樣欲解析的IP地址就會(huì)被表達(dá)成一種像域名一樣的可顯示串形式玉凯,后綴以逆向解析域域名“in-addr.arpa”結(jié)尾。例如一個(gè)IP地址:218.30.103.170联贩,其逆向域名表達(dá)方式為:170.103.30.218.in-addr.arpa漫仆。兩種表達(dá)方式中IP地址部分順序恰好相反,因?yàn)橛蛎Y(jié)構(gòu)是自底向上(從子域到域)泪幌,而IP地址結(jié)構(gòu)是自頂向下(從網(wǎng)絡(luò)到主機(jī))的盲厌。實(shí)質(zhì)上逆向域名解析是將IP地址表達(dá)成一個(gè)域名,以地址做為索引的域名空間祸泪,這樣逆向解析的很大部分可以納入正向解析中吗浩。
coreDNS在K8S中的配置
apiVersion: v1
data:
Corefile: |
.:53 {
errors
log
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
hosts {
10.20.31.104 www.google.com
fallthrough
}
prometheus :9153
forward . /etc/resolv.conf {
prefer_udp
}
cache 30
loop
reload
loadbalance
}
kind: ConfigMap
......
插件調(diào)用說(shuō)明
匹配域名后,會(huì)按照域內(nèi)的插件順序没隘,依次調(diào)用插件拓萌。插件處理邏輯有以下四種:
- 插件處理完成后,直接返回結(jié)果升略。如kubernetes微王,hosts,如果沒有加fallthrough品嚣,則調(diào)用結(jié)束本插件后炕倘,就返回了。
- 不被該插件處理翰撑,流轉(zhuǎn)到下一個(gè)插件罩旋,如果所有插件不處理,則返回錯(cuò)誤眶诈。
- 插件內(nèi)有fallthrough關(guān)鍵字涨醋,fallthrough到下一個(gè)插件。fallthrough關(guān)鍵字的含義是逝撬,繼續(xù)調(diào)用下一個(gè)插件處理浴骂。
- 插件處理后,打上hint宪潮,流轉(zhuǎn)到下一個(gè)插件溯警。
參數(shù) | 說(shuō)明 |
---|---|
errors | 打印/存儲(chǔ)錯(cuò)誤日志 |
log | 將CoreDNS每次域名解析的日志打印出來(lái) |
health | CoreDNS自身健康狀態(tài)報(bào)告,默認(rèn)監(jiān)聽端口8080狡相,一般用來(lái)做健康檢查梯轻。您可以通過(guò)http://localhost:8080/health獲取健康狀態(tài)(coredns Pod配置的存活探針使用此接口獲取CoreDNS自身健康)。 |
ready | CoreDNS插件狀態(tài)報(bào)告尽棕,默認(rèn)監(jiān)聽端口8181喳挑,一般用來(lái)做可讀性檢查。可以通過(guò)http://localhost:8181/ready獲取可讀狀態(tài)伊诵。當(dāng)所有插件都運(yùn)行后媚朦,ready狀態(tài)為200(coredns Pod配置的就緒探針使用此接口獲取CoreDNS插件的就緒狀況)。 |
kubernetes | kubernetes: CoreDNS Kubernetes插件日戈,提供集群內(nèi)服務(wù)解析能力。該插件實(shí)現(xiàn)了基于Kubernetes DNS的服務(wù)發(fā)現(xiàn)孙乖。 其中cluster.local in-addr.arpa ip6.arpa表示kubernetes插件會(huì)處理域名后綴為cluster.local的所有域名以及處理所有的in-addr.arpa中的反向dns查找和ip6.arpa形式域名浙炼,其中kubernetes集群域名后綴是在kubelet參數(shù)中配置的,默認(rèn)值為cluster.local唯袄。 pods參數(shù)用于設(shè)置基于pods ip的A記錄弯屈,例如default namespace下存在一個(gè)pod,ip為10.233.64.2,此Pod的A記錄為10-233-64-2.default.pod.cluster.local ->10.233.64.2,pods參數(shù)有三個(gè)值恋拷,其中disabled表示關(guān)閉pod ip的A記錄资厉;insecure總是從請(qǐng)求中返回一個(gè)帶有IP的A記錄(不檢查k8s)(例如:1-2-3-4.ns.pod.cluster.local. in A 1.2.3.4);verified表示如果在同一命名空間中蔬顾,則存在匹配IP的pod宴偿。 fallthrough:指定特定區(qū)域查詢失敗,如果in-addr.arpa和ip6.arpa形式的域名在kubernetes插件沒有匹配成功的話則進(jìn)入下一個(gè) plugin 繼續(xù)诀豁。 ttl參數(shù)為響應(yīng)客戶端請(qǐng)求設(shè)置的自定義 TTL窄刘。更多參數(shù)配置見:https://coredns.io/plugins/kubernetes/ |
hosts | 相當(dāng)于主機(jī)/etc/hosts 文件里面的解析信息。如果一個(gè)域名在 hosts中存在舷胜,則優(yōu)先使用這個(gè)信息返回娩践,在本例中一定要注意hosts插件的位置,如果放在了forward插件之后烹骨,那么hosts插件即沒有匹配的機(jī)會(huì)翻伺; |
prometeus | CoreDNS自身metrics數(shù)據(jù)接口【诨溃可以通過(guò)http://localhost:9153/metrics獲取prometheus格式的監(jiān)控?cái)?shù)據(jù)吨岭。 |
forward | 將域名查詢請(qǐng)求轉(zhuǎn)到預(yù)定義的DNS服務(wù)器。默認(rèn)配置中峦树,當(dāng)域名不在Kubernetes域時(shí)未妹,將請(qǐng)求轉(zhuǎn)發(fā)到預(yù)定義的解析器(/etc/resolv.conf)中。默認(rèn)使用宿主機(jī)的/etc/resolv.conf配置空入。 forward . /etc/resolv.conf中的"."表示匹配所有域名络它。 |
cache | 溯源得到的結(jié)果,緩存指定時(shí)間歪赢。類似 TTL 的概念化戳;TTL以秒為單位。如果未指定,將使用最大 TTL点楼,對(duì)于 NOERROR 響應(yīng)為 3600扫尖,對(duì)于拒絕存在響應(yīng)為 1800。將 TTL 設(shè)置為 30表示緩存記錄長(zhǎng)達(dá) 30 秒掠廓。 |
loop | 環(huán)路檢測(cè)换怖,如果檢測(cè)到環(huán)路,則停止CoreDNS蟀瞧。例如沉颂,forward . /etc/resolv.conf中配置的dns server地址和coredns地址一致,客戶端請(qǐng)求解析in-addr.arpa類型域名悦污,在kubernetes插件中解析in-addr.arpa類型域名失敗铸屉,由于配置了fallthrough in-addr.arpa ip6.arpa,那么就會(huì)進(jìn)入到forward插件繼續(xù)解析切端,由于forward . /etc/resolv.conf中配置的dns server地址和coredns地址一致彻坛,那么又會(huì)傳到dns server進(jìn)行解析,這么就陷入了一個(gè)死循環(huán)踏枣,通過(guò)loop插件可以避免環(huán)路問(wèn)題昌屉。 |
reload | 允許自動(dòng)重新加載已更改的Corefile。編輯ConfigMap配置后茵瀑,請(qǐng)等待兩分鐘以使更改生效,無(wú)需重啟coredns對(duì)應(yīng)的Pod怠益。 |
loadbalance | 循環(huán)DNS負(fù)載均衡器,可以在答案中隨機(jī)A瘾婿、AAAA蜻牢、MX記錄的順序。 |
其他典型場(chǎng)景
- 特定域名使用自定義DNS服務(wù)器
example.com:53 {
errors
cache 30
forward . 10.10.0.10
}
- 外部域名完全使用自建DNS服務(wù)器
Corefile: |
.:53 {
...
forward . 10.10.0.10 10.10.0.20{
prefer_udp
}
...
}
- 禁止CoreDNS對(duì)IPv6類型的AAAA記錄查詢返回
Corefile: |
.:53 {
errors
health {
lameduck 15s
}
#新增以下一行Template插件偏陪,其它數(shù)據(jù)請(qǐng)保持不變抢呆。
template IN AAAA .
}
- 統(tǒng)一域名訪問(wèn)服務(wù)或是在集群內(nèi)對(duì)域名的做CNAME解析
Corefile: |
.:53 {
errors
health {
lameduck 15s
}
ready
rewrite stop {
name regex foo.example.com foo.default.svc.cluster.local
answer name foo.default.svc.cluster.local foo.example.com
}
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf {
prefer_udp
}
cache 30
loop
reload
loadbalance
}
此處的含義是請(qǐng)求域名符合正則表達(dá)式foo.example.com
時(shí),重定向到foo.default.svc.cluster.local
處理笛谦;處理完返回時(shí)抱虐,把response的foo.default.svc.cluster.local
改寫為foo.example.com
,否則client端可能會(huì)認(rèn)為返回結(jié)果無(wú)效饥脑,因?yàn)閏lient請(qǐng)求的地址和接收到的answer的地址不是同一個(gè)恳邀,會(huì)認(rèn)為存在中間人攻擊。
rewrite的好處是灶轰,在公網(wǎng)(默認(rèn)使用域名foo.example.com
)谣沸、內(nèi)網(wǎng)(默認(rèn)使用域名foo.example.com
)、集群內(nèi)部(默認(rèn)使用域名foo.default.svc.cluster.local
)笋颤,都可以使用同一個(gè)域名foo.example.com
訪問(wèn)服務(wù)乳附。(前提:該服務(wù)在公網(wǎng)和內(nèi)網(wǎng)都通過(guò)LB暴露并綁定了域名。)
rewrite用法參考。
參考
https://www.cnblogs.com/zhangmingcheng/p/15680815.html
https://help.aliyun.com/document_detail/380963.html