k8s pod dns policy

https://juejin.cn/post/6844903665879220231
https://mp.weixin.qq.com/s/r1ZjtBVe4XPLmsMTj2oZNQ

Kubernetes DNS 高階指南

DNS 是 Kubernetes 的核心功能之一,Kubernetes 通過(guò) kube-dnsCoreDNS 作為集群的必備擴(kuò)展來(lái)提供命名服務(wù)豪嗽,通過(guò) DNS 擴(kuò)展慕的,每一個(gè) Service 都會(huì)產(chǎn)生一個(gè)獨(dú)一無(wú)二的 FQDN(Fully Qualified Domain Name)名稱(chēng)噪矛。

在大多數(shù)使用場(chǎng)景下华糖,我們并不會(huì)太關(guān)心 DNS 插件的內(nèi)部運(yùn)作細(xì)節(jié)作郭,直接使用 Kubernetes 預(yù)設(shè)的 DNS 配置和策略就可以滿足需求诗充。然而隨著使用場(chǎng)景越來(lái)越復(fù)雜黑毅,譬如跟 NFV(Network Function Virtualization)相關(guān)的場(chǎng)景祭衩,我們的應(yīng)用(Pod)可能就會(huì)需要更加個(gè)性化的 DNS 配置灶体。

接下來(lái)使用下面這張架構(gòu)圖來(lái)說(shuō)明可能的使用場(chǎng)景:

[圖片上傳失敗...(image-87df61-1615508286754)]

1. 為什么需要自定義 DNS

一般的使用場(chǎng)景下,我們的 Kubernetes 集群的使用方式就像圖中紫色/粉紅色(Pod3)區(qū)域一樣掐暮,所有的 Pod 如果有任何要存取 DNS 的需求蝎抽,都會(huì)透過(guò)集群內(nèi)的的 k8s DNS 來(lái)處理對(duì)應(yīng)的請(qǐng)求與回復(fù)。

然而在 NFV 的使用場(chǎng)景下路克,網(wǎng)絡(luò)變成一個(gè)很重要的區(qū)域樟结,整體的性能都取決于該應(yīng)用的設(shè)計(jì)與集群的網(wǎng)絡(luò)架構(gòu)設(shè)計(jì)。這部分應(yīng)用通常都會(huì)追求高輸出或是低延遲精算,為了得到更好的性能瓢宦,需要避免這些流量跟其他無(wú)關(guān)的流量使用相同的網(wǎng)絡(luò)線路進(jìn)行傳輸。

在這種情況下灰羽,通常就會(huì)把整個(gè)集群的網(wǎng)絡(luò)設(shè)計(jì)成兩種架構(gòu)驮履,分別是 Control NetworkData Network 這兩個(gè)不同用途的網(wǎng)絡(luò)架構(gòu)。在 Kubernetes 中廉嚼,Control Network 就類(lèi)似于圖中的 Cluster Network玫镐,負(fù)責(zé)整個(gè)集群之間的溝通。圖中綠色/橘色(Pod1怠噪,Pod2)這兩個(gè)區(qū)域就是所謂的 Data Network恐似,其網(wǎng)卡本身也被獨(dú)立出來(lái),不會(huì)與本來(lái)的 Kubernetes 集群發(fā)生沖突傍念,它們之間的流量通過(guò)獨(dú)立的網(wǎng)絡(luò)進(jìn)行傳輸矫夷。

存在于獨(dú)立出來(lái)的網(wǎng)絡(luò)架構(gòu)中的這些特殊的 Pod 基本上沒(méi)法跟 Kubernetes 集群內(nèi)的 DNS 互連,而且這些應(yīng)用還有可能在外部有自己的 DNS Server憋槐,所以在這種場(chǎng)景下双藕,我們希望這些應(yīng)用(Pod1/Pod2)能夠使用自定義的 DNS Server

2. 如何自定義 DNS

為了讓用戶更容易控制 Pod 中的 DNS 設(shè)置阳仔,Kubernetes v1.9 引入了一項(xiàng)新的 Alpha 特性(在 v1.10 中處于 Beta 階段)蔓彩。該特性在 v1.10 中被默認(rèn)啟用,在 v1.9 中如果想要啟用此功能,集群管理員需要在 apiserver 和 kubelet 上啟用 CustomPodDNS 特性赤嚼,例如: “--feature-gates=CustomPodDNS=true,...”旷赖。啟用了該特性之后,用戶可以將 Pod 的 dnsPolicy 字段設(shè)置為 "None"更卒,并且可以在 Pod.Spec 中添加新的字段 dnsConfig等孵。

其中 dnsConfig 用來(lái)自定義 DNS 參數(shù),而 dnsPolicy 用來(lái)給 Pod 選取預(yù)設(shè)的 DNS蹂空。接下來(lái)就看看可以通過(guò)哪些手段自定義 DNS俯萌。

dnsConfig

dnsConfig 可以讓操作者延伸到 Pod 內(nèi)部關(guān)于 DNS 的配置,這邊需要特別注意的是上枕,我使用的字眼是 延伸 而不是 配置咐熙,這是因?yàn)橥ㄟ^(guò)下一節(jié)的 dnsPolicy,每個(gè) Pod 都會(huì)有一組預(yù)設(shè)的 DNS 配置辨萍。通過(guò) dnsConfig 我們可以繼續(xù)往上迭加相關(guān)的 DNS 參數(shù)到 Pod 之中棋恼。

目前總共支持三個(gè)參數(shù),分別是:

  • nameservers

  • searches

  • options

這三個(gè)參數(shù)對(duì)應(yīng)的就是大家熟悉的 /etc/resolv.conf 里面的三個(gè)參數(shù)锈玉,這里就不針對(duì) DNS 進(jìn)行詳細(xì)解釋了爪飘,不熟悉的朋友可以自行去 Google 學(xué)一下這些參數(shù)的意思。

在 Kubernetes 里面拉背,這三個(gè)參數(shù)都包含在 dnsConfig 配置項(xiàng)中师崎,而 dnsConfig 包含在 PodSpec 配置項(xiàng)中,因?yàn)?Pod 內(nèi)所有的容器都共享相同的 Network Namespace椅棺,所以網(wǎng)絡(luò)方面的配置都會(huì)共享犁罩。

這邊提供一個(gè)簡(jiǎn)單的 yaml 示例:

[圖片上傳失敗...(image-4b8e1f-1615508286753)]

通過(guò)上述 yaml 創(chuàng)建 Pod 之后,通過(guò)下面的命令可以觀察到容器中 DNS 配置文件中會(huì)出現(xiàn)額外的配置两疚。

$ kubectl exec ubuntu-setting cat /etc/resolv.confnameserver 10.254.0.2nameserver 1.2.3.4search default.svc.cluster.local svc.cluster.local cluster.local ns1.svc.cluster.local my.dns.search.suffixoptions ndots:2 edns0
復(fù)制代碼

可以看到 nameserver 多了一個(gè) 1.2.3.4床估,而 search 則多了 ns1.svc.cluster.local my.dns.search.suffix 這兩個(gè)自定義的值,最后 options 則增加了我們示例中指定的 ndots:2 edns0鬼雀。

dnsConfig 非常簡(jiǎn)單直觀顷窒,如果你需要自定義 DNS 參數(shù)蛙吏,就可以通過(guò)這個(gè)字段來(lái)指定源哩。

dnsPolicy

前面提過(guò),dnsConfig 提供的是延伸 Pod 內(nèi)預(yù)設(shè)的 DNS 配置鸦做,而 dnsPolicy 就是決定 Pod 內(nèi)預(yù)設(shè)的 DNS 配置有哪些励烦。

目前總共有四個(gè)類(lèi)型可以選擇:

  • None

  • Default

  • ClusterFirst

  • ClusterFirstHostNet

接下來(lái)針對(duì)這四個(gè)類(lèi)型分別介紹。

None

None 表示會(huì)清除 Pod 預(yù)設(shè)的 DNS 配置泼诱,當(dāng) dnsPolicy 設(shè)置成這個(gè)值之后坛掠,Kubernetes 不會(huì)為 Pod 預(yù)先載入任何自身邏輯判斷得到的 DNS 配置。因此若要將 dnsPolicy 的值設(shè)為 None,為了避免 Pod 里面沒(méi)有配置任何 DNS屉栓,最好再添加 dnsConfig 來(lái)描述自定義的 DNS 參數(shù)舷蒲。

使用下面的示例來(lái)進(jìn)行測(cè)試:

[圖片上傳失敗...(image-170b2b-1615508286753)]

通過(guò)上述 yaml 創(chuàng)建 Pod 之后,通過(guò)下面的命令可以觀察容器中的 DNS 配置文件友多,可以觀察到跟之前的 dnsConfig 的結(jié)果有一點(diǎn)差異牲平,這里只有我們?cè)?yaml 里配置的那些參數(shù),而沒(méi)有加入集群預(yù)設(shè)的 DNS 配置域滥。

$ kubectl exec ubuntu-none cat /etc/resolv.confnameserver 1.2.3.4search ns1.svc.cluster.local my.dns.search.suffixoptions ndots:2 edns0
復(fù)制代碼

Default

Default 表示 Pod 里面的 DNS 配置繼承了宿主機(jī)上的 DNS 配置纵柿。簡(jiǎn)單來(lái)說(shuō),就是該 Pod 的 DNS 配置會(huì)跟宿主機(jī)完全一致启绰。

使用下面的示例來(lái)進(jìn)行測(cè)試:

[圖片上傳失敗...(image-aad2ab-1615508286753)]

首先昂儒,我們先觀察 Node 上面的 DNS 配置:

$ cat /etc/resolv.conf# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTENnameserver 10.0.2.3
復(fù)制代碼

可以觀察到,Node 上面的 DNS 配置得很簡(jiǎn)單委可,只有單純的 10.0.2.3渊跋。 接下來(lái)我們觀察該 Pod 內(nèi)的 DNS 配置:

$ kubectl exec ubuntu-default cat /etc/resolv.confnameserver 10.0.2.3
復(fù)制代碼

可以看到這兩個(gè)的 DNS 配置完全一致,該 Pod 內(nèi)的 DNS 配置已經(jīng)直接繼承 Node 上面的配置了撤缴。

ClusterFirst

相對(duì)于上述的 Default刹枉,ClusterFirst 是完全相反的操作,它會(huì)預(yù)先把 kube-dns(或 CoreDNS)的信息當(dāng)作預(yù)設(shè)參數(shù)寫(xiě)入到該 Pod 內(nèi)的 DNS 配置屈呕。

ClusterFirst 是預(yù)設(shè)的行為微宝,若沒(méi)有在 Pod 內(nèi)特別描述 PodPolicy, 則會(huì)將 dnsPolicy 預(yù)設(shè)為 ClusterFirst。

使用下面的示例來(lái)進(jìn)行測(cè)試:

[圖片上傳失敗...(image-33a41d-1615508286753)]

通過(guò)上述 yaml 創(chuàng)建 Pod 之后虎眨,通過(guò)下面的命令觀察容器中的 DNS 配置文件:

$ kubectl exec ubuntu-clusterfirst cat /etc/resolv.confnameserver 10.254.0.2search default.svc.cluster.local svc.cluster.local cluster.localoptions ndots:5
復(fù)制代碼

可以看到這里使用的是 k8s DNS 的設(shè)置蟋软。

此外,ClusterFirst 還有一個(gè)沖突嗽桩,如果你的 Pod 設(shè)置了 HostNetwork=true岳守,則 ClusterFirst 就會(huì)被強(qiáng)制轉(zhuǎn)換成 Default

HostNetwork

使用下面的示例來(lái)進(jìn)行測(cè)試:

[圖片上傳失敗...(image-44b2ab-1615508286753)]

通過(guò)上述 yaml 創(chuàng)建 Pod 之后碌冶,通過(guò)下面的命令觀察容器中的 DNS 配置文件:

$ kubectl exec ubuntu-hostnetwork-policy-default cat /etc/resolv.confnameserver 10.0.2.3
復(fù)制代碼

可以觀察到湿痢,Pod 里面的 DNS 配置直接繼承了宿主機(jī)上的 DNS 配置。

這邊稍微來(lái)解釋一下這個(gè)設(shè)計(jì)上的原理以及流程:

  1. 因?yàn)樵O(shè)置了 HostNetwork=true , 會(huì)讓該 Pod 與該節(jié)點(diǎn)共用相同的網(wǎng)路空間(網(wǎng)卡/路由等功能)扑庞。

  2. 預(yù)設(shè)的 k8s DNS 是使用 ClusterIP 的 kubernetes serivce. 這種情況下譬重,只有屬于 Cluster 內(nèi)的 Pod 可以獲取該 ClusterIP。

  3. 所以設(shè)置了 HostNetwork=true 的 Pod 就沒(méi)有辦法獲取該 ClusterIP罐氨。

  4. 于是預(yù)設(shè)就會(huì)將對(duì)應(yīng)的 DNS 配置改回 Default 的形式臀规,從節(jié)點(diǎn)繼承其 DNS 配置信息。

這種情況下栅隐,就會(huì)有人想要問(wèn)塔嬉,如果我刻意想要這樣設(shè)置不行嗎玩徊?

原先的設(shè)計(jì)中,是沒(méi)有辦法刻意處理的谨究,原因是當(dāng) Pod yaml 配置文件被發(fā)送出去后恩袱,在發(fā)現(xiàn)沒(méi)有設(shè)定 dnsPolicy 的情況下,會(huì)自動(dòng)幫你把該 dnsPolicy 補(bǔ)上 ClusterFirst 的數(shù)值胶哲。

然后最后面的程序處理邏輯中憎蛤,其實(shí)並沒(méi)有辦法分別下列兩種情況:

  1. HostNetwork:我希望走 Host DNS

  2. HostNetwork & dnsPolicy=ClusterFirst:我希望走 ClusterIP DNS

上述兩種情況對(duì)于后端的程序來(lái)看都長(zhǎng)得一樣,完全沒(méi)有辦法分辨纪吮,我們可以直接從 Kubernetes 源碼 來(lái)閱讀一下其運(yùn)作流程:

func getPodDNSType(pod *v1.Pod) (podDNSType, error) {    dnsPolicy := pod.Spec.DNSPolicy    switch dnsPolicy {    case v1.DNSNone:        if utilfeature.DefaultFeatureGate.Enabled(features.CustomPodDNS) {            return podDNSNone, nil        }        // This should not happen as kube-apiserver should have rejected        // setting dnsPolicy to DNSNone when feature gate is disabled.        return podDNSCluster, fmt.Errorf(fmt.Sprintf("invalid DNSPolicy=%v: custom pod DNS is disabled", dnsPolicy))    case v1.DNSClusterFirstWithHostNet:        return podDNSCluster, nil    case v1.DNSClusterFirst:        if !kubecontainer.IsHostNetworkPod(pod) {            return podDNSCluster, nil        }        // Fallback to DNSDefault for pod on hostnetowrk.        fallthrough    case v1.DNSDefault:        return podDNSHost, nil    }    // This should not happen as kube-apiserver should have rejected    // invalid dnsPolicy.    return podDNSCluster, fmt.Errorf(fmt.Sprintf("invalid DNSPolicy=%v", dnsPolicy))}
復(fù)制代碼

這邊可以看到一旦是 DNSClusterFirst 的情況下俩檬,若設(shè)置了 HostNetwork, 最后就會(huì)直節(jié)回傳 podDNSHost 節(jié)點(diǎn)的 DNS 設(shè)定回去。

為了解決上述的問(wèn)題碾盟,所以引進(jìn)了一個(gè)新的類(lèi)型 ClusterFirstHostNet棚辽。

ClusterFirstWithHostNet

ClusterFirstWithHostNet 用途非常簡(jiǎn)單,我希望滿足使用 HostNetwork 同時(shí)使用 k8s DNS 作為我 Pod 預(yù)設(shè) DNS 的配置冰肴。

根據(jù)上面的源碼也可以觀察到:

case v1.DNSClusterFirstWithHostNet:    return podDNSCluster, nil
復(fù)制代碼

只要將 dnsPolicy 設(shè)置為 ClusterFirstWithHostNet, 就會(huì)一律返回 k8s DNS 的 clusterIP 這種形式屈藐。

使用下面的示例來(lái)進(jìn)行測(cè)試:

[圖片上傳失敗...(image-cfe007-1615508286752)]

通過(guò)上述 yaml 創(chuàng)建 Pod 之后,通過(guò)下面的命令觀察該 Pod 的狀態(tài):

$ kubectl exec ubuntu-hostnetwork-policy cat /etc/resolv.confnameserver 10.254.0.2search default.svc.cluster.local svc.cluster.local cluster.localoptions ndots:5
復(fù)制代碼

可以發(fā)現(xiàn)這時(shí)候的 DNS 就會(huì)配置成 k8s DNS 的 ClusterIP 了熙尉。

作者:rowenan
鏈接:https://juejin.cn/post/6844903665879220231
來(lái)源:掘金
著作權(quán)歸作者所有联逻。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處检痰。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末包归,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子铅歼,更是在濱河造成了極大的恐慌公壤,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件椎椰,死亡現(xiàn)場(chǎng)離奇詭異厦幅,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)慨飘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)确憨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人瓤的,你說(shuō)我怎么就攤上這事休弃。” “怎么了堤瘤?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,704評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵玫芦,是天一觀的道長(zhǎng)浆熔。 經(jīng)常有香客問(wèn)我本辐,道長(zhǎng)桥帆,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,702評(píng)論 1 294
  • 正文 為了忘掉前任慎皱,我火速辦了婚禮老虫,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘茫多。我一直安慰自己祈匙,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布天揖。 她就那樣靜靜地躺著夺欲,像睡著了一般。 火紅的嫁衣襯著肌膚如雪今膊。 梳的紋絲不亂的頭發(fā)上些阅,一...
    開(kāi)封第一講書(shū)人閱讀 51,573評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音斑唬,去河邊找鬼市埋。 笑死,一個(gè)胖子當(dāng)著我的面吹牛恕刘,可吹牛的內(nèi)容都是我干的缤谎。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼褐着,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼坷澡!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起含蓉,我...
    開(kāi)封第一講書(shū)人閱讀 39,230評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤洋访,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后谴餐,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體姻政,經(jīng)...
    沈念sama閱讀 45,680評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評(píng)論 3 336
  • 正文 我和宋清朗相戀三年岂嗓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了汁展。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,991評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡厌殉,死狀恐怖食绿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情公罕,我是刑警寧澤器紧,帶...
    沈念sama閱讀 35,706評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站楼眷,受9級(jí)特大地震影響铲汪,放射性物質(zhì)發(fā)生泄漏熊尉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評(píng)論 3 330
  • 文/蒙蒙 一掌腰、第九天 我趴在偏房一處隱蔽的房頂上張望狰住。 院中可真熱鬧,春花似錦齿梁、人聲如沸催植。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,910評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)创南。三九已至,卻和暖如春省核,著一層夾襖步出監(jiān)牢的瞬間扰藕,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,038評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工芳撒, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留邓深,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,158評(píng)論 3 370
  • 正文 我出身青樓笔刹,卻偏偏與公主長(zhǎng)得像芥备,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子舌菜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容