解密K8S DNS:揭開內部服務查詢的生命循環

更新於 2024/02/21閱讀時間約 18 分鐘

先前我們說明了在K8S內部基本網路溝通的基本原則,本篇我們再針對應用服務的查詢與發現,這個部分將會依賴K8S內部的DNS元件來實現。

raw-image

同時也將說明內部服務查詢的整個生命循環,我們可以透過了解DNS的工作原理,可以在應用服務的問題處理可以更有效率。

本篇將不會說明安裝的做法,只針對DNS服務查詢的流程進行討論。我們接著將說明以下內容:

  1. Pod在K8S內部的溝通
  2. Kubernetes DNS是什麼
  3. DNS record長什麼樣子
  4. 要如何利用DNS來找到服務
  5. 基本測試
  6. 結論

1. Pod在K8S內部的溝通

一般來說,K8S內部使用Pod IP進行溝通會有以下問題:

  1. 動態IP指派:Pod在建立、重啟、擴展都會被指派新的IP位址,以IP來追蹤的話會常常出現問題。
  2. 外部存取限制:Pod IP無法從外部存取,因為K8S是沒有路由能力的。所以外部要存取到Pod,需要透過Service type。

所謂的Service type就是透過建立一個持久性的名稱來讓後端的Pod群組可以被外界存取到,並且提供以下優點:

  • Stable Communication:當Pod要連線到其他的Pod時,直接參照Service name,並且service可以很有效的將流量路由到其他的Pod
  • Load Balancing : 透過負載平衡的特性,將流量分散到所有的Pod可以強化應用服務的效能
  • High Availability : Service設定可以確保流量的重導到特定的Pod,就算失敗也不會干擾應用服務的可用性。
  • DNS Resolution : Service可以向Kubernetes DNS進行註冊,讓Pod-to-Pod的溝通可以很容易建立,而且不需要知道個別的IP位址。

2. Kubernetes DNS是什麼

用一句話來說明:將服務發現的工作簡單化

當我們建立Service建立之後,K8S DNS就會自動產生一個對應的A record 將service dns name與IP位址配對。之後,Pod就可以透過DNS名稱來進行連線。而DNS負責動態更新所有的A record來反應Service IP的改變。

K8S核心元件預設將與內部的DNS進行溝通來確保每個Pod與Service建立、移動、移除時相關記錄的正確。

目前K8S預設的DNS已從kube-dns移動到CoreDNS。二者所實作的功能相同的部分如下:

  • kube-dns service將建立一個以上的pod
  • kube-dns service針對service與endpoint相關事件並且修改成合適的DNS記錄
  • kubelet會對kube-dns的service指派對應的cluster ip,並且在每個pod內部的/etc/resolv.conf加入nameserver的字串如下:
nameserver 10.10.23.1
search namespace.svc.cluster.local svc.cluster.local cluster.local
  • 應用程式可以將 test-service.namespace 等主機名稱解析為適當的叢集 IP 位址
raw-image

3. DNS record長什麼樣子

一個完整的k8s service的A record如下:

service.namespace.svc.cluster.local

對應於上述的記錄,對於實際上的real IP後呈現如下:

10-32-0-125.namespace.pod.cluster.local

同時,針對k8s service 特定port的SRV記錄將用以下格式建立:

_port-name._protocol.service.namespace.svc.cluster.local

最後,應用程式可透過簡單且一致的主機名稱來存取叢集上的其他服務或 Pod。

通常不會使用完整的hostname來取用其他的服務,因為會在resolv.conf會設定好domain suffixes,如果要與同一個namespace內的服務溝通的話,只要用以下方式即可:

other-service

如果要到其他的namespace的話,加上:

other-service.other-namespace

如果要直接對應到Pod的話,則是:

pod-ip.other-namespace.pod

一個標準的service的定義如下:

apiVersion: v1
kind: Service
metadata:
name: foo
namespace: bar
spec:
ports:
- port: 80
name: http

建立之後,A record, SRV record就會用以下方式產生:

foo.bar.svc.cluster.local                     30 A X.X.X.X
_http._tcp.nginx.default.svc.cluster.local 3600 SRV 0 100 80 X-X-X-X.foo.bar.svc.cluster.local.

※ Cluster domain: cluster.local

當記錄建立完成後,在cluster內就可以使用DNS name去解析Service IP。


4. 要如何利用DNS來找到服務

情況1:不同節點

raw-image

流程:

Step1. Pod發動一個DNS查詢,會先查自已內部的resolv.conf

Step2. 內部的resolv.conf會設定一個預設的dns,這個dns帶有快取的含義

Step3. 如果這個local dns沒有相關的記錄,就會透過resolv.conf的內容,指向CoreDNS

Step4. CoreDNS透過向Kubernetes API(service registry)進行查詢,這個registry就會包含service name與ip的對應

Step5. 當查詢到了之後就會將正確的值回傳給Pod

Step6. 如果在Service registry也沒有的記錄就會再往更上游的DNS進行查詢。

以下簡單說明:

※ Pod發起查詢

Pod發送一個API需求來查詢service時,先詢問自已/etc/resolv.conf的內容。這個檔案是由kubelet所自動為每個pod所產生的。預設內容如下:

# cat /etc/resolv.conf

search namespace.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.101.101.11
options ndots:5

※ ndots 選項決定何時直接進行絕對網域查詢,而不是先附加搜尋網域。

※ Local dns

DNS查詢在網路溝通的過程是很普遍發生的,因為頻率很高,所以必須要很快速地處理來避免造成效能問題並且不容易除錯。

如果在k8s cluster內要強化DNS查詢效率,可以在每個節點再加入一個nodelocaldns元件來做決DNS快取。

如果在快取層沒有找到記錄,就會將查詢向上到CoreDNS,這種方式可以大大減少不斷的往CoreDNS查詢的頻率。

※ K8S 記錄的TTL

預設CoreDNS的DNS記錄的TTL是30秒。並且可以在CoreDNS的設定檔內變更這個值。

TTL會決定在必須進行新查詢之前多久的回應將被視為有效。如果把這個TTL變的更短,反而有可能增加DNS server的負載。但是更長也可能導致DNS回應的過期或回應的值不正確的問題。

※ SRV

K8S也會使用SRV來解析服務Port號。這也允許客戶端可以透過查詢DNS來發現服務的Port號。例如:

apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: test
spec:
ports:
- port: 80
name: http

[note]
(1) nginx容器會以http的名稱,暴露80port給外界,而k8s將會自動產生一個SRV的記錄如下:
_http._tcp.nginx.tet.svc.cluster.local

(2)用指令直接查詢:
[root]# dig SRV _http._tcp.nginx.tet.svc.cluster.local +short
=> 會回傳對應的SRV記錄

5. 基本測試

#--------------------------------------------------
# S5-1. create dnsutils pod
#--------------------------------------------------
[root]# vim dnsutils.yaml
apiVersion: v1
kind: Pod
metadata:
name: dnsutils
namespace: default
spec:
containers:
- name: dnsutils
image: registry.k8s.io/e2e-test-images/jessie-dnsutils:1.3
command:
- sleep
- "infinity"
imagePullPolicy: IfNotPresent
restartPolicy: Always

[root]# kubectl apply -f dnsutils.yaml
[root]# kubectl get pod
#--------------------------------------------------
# S5-2. confirm pod dns
#--------------------------------------------------
[root]# kubectl exec -i -t dnsutils -- nslookup kubernetes.default
Server: 10.96.0.10
Address: 10.96.0.10#53

Name: kubernetes.default.svc.cluster.local
Address: 10.96.0.1
#--------------------------------------------------
# S5-3. confirm dns resolv.conf
#--------------------------------------------------
[root]# kubectl exec -ti dnsutils -- cat /etc/resolv.conf
search default.svc.cluster.local svc.cluster.local cluster.local test.example.poc
nameserver 10.96.0.10
options ndots:5
#--------------------------------------------------
# S5-4. confirm coredns running
#--------------------------------------------------
[root]# kubectl get pods --namespace=kube-system -l k8s-app=kube-dns
NAME READY STATUS RESTARTS AGE
coredns-5d78c9869d-n5jwk 1/1 Running 2 90d
coredns-5d78c9869d-s2kf8 1/1 Running 2 90d
#--------------------------------------------------
# S5-5. confirm pod's log
#--------------------------------------------------
[root]# kubectl logs --namespace=kube-system -l k8s-app=kube-dns
raw-image
#--------------------------------------------------
# S5-6. confirm dns service is running
# "kube-dns"名稱是coredns & kubedns都用同一個名字
#--------------------------------------------------
[root]# kubectl get svc --namespace=kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 90d
metrics-server ClusterIP 10.103.38.187 <none> 443/TCP
#--------------------------------------------------
# S5-7. DNS endpoint是否有暴露出來
#--------------------------------------------------
[root]# kubectl get endpoints kube-dns --namespace=kube-system
NAME ENDPOINTS AGE
kube-dns 192.168.101.133:53,192.168.101.134:53,192.168.101.133:53 + 3 more..
#--------------------------------------------------
# S5-8. 確認DNS查詢是否有接收並處理
# 透過在coredns設定檔內加入log
#--------------------------------------------------
[root]# kubectl edit configmap coredns -n kube-system
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
log <<<
errors
health
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
upstream
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}

[root]# kubectl logs -f coredns-5d78c9869d-n5jwk -n kube-system
raw-image

6.結論

所有Pod一建立起來就會被指派IP。Pod之間就可以使用這些IP相互溝通。

問題是如果Pod有任何重建或是刪除的異動的話,原本的IP也會被異動。如果要避免這種情況就必須要改用Service這種資源類型。

當建立service之後,apiserver就會儲存相關的資料到controller-manager並且會帶跟另外二個資源類型:EndpointsEndpointSlices

此時,CoreDNS就會利用這些資源去識別如何將service name轉換成service ip。同時,每個節點上的kube-proxy就會去更新節點內的iptables rules。這些規則就會讓需求可以正確定位到正確的Pod。

最後,當Pod產生查詢需求,就會執行一個DNS查詢給CoreDNS來取得service ip,取得service ip之後,就會套用節點上由kube-proxy所建立的規則來將流量導至實際的Pod IP。


本篇說明到這邊,感謝大家觀看,下期再見~~~


※ References:

avatar-img
15會員
40內容數
記錄IT社畜的自我學習筆記,如同專題名稱,主要是怕自已忘記自已做過什麼、學到什麼。索性就分享我自已在學習Kubernetes這條路上的各種測試、學習心得。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
超健忘閒人的沙龍 的其他內容
本篇將介紹Minio的功能和如何與Harbor進行整合,並說明這樣做的好處。包括Minio的優勢及Harbor x Minio的部署和測試。
本文闡述了Kubernetes內部網路通訊的基本概念,從容器到服務的溝通流程,並討論了Kubernetes使用的各種技術。重要的是,管理Kubernetes叢集時理解這些基本概念是極其重要的。
在Kubernetes cluster上建立Jenkins,並且使用動態方式建立Jenkins Agent。透過K8S解決傳統的Jenkins一對多架構的問題,最終建立基本Pipeline在Jenkins Web UI上,簡單驗證Jenkins engine正常運行。
本篇說明如何利用Kubernetes特色,將PostgreSQL DB以HA的架構來提供服務,並說明相關的實作流程與說明。
當您在K8S Cluster中使用Harbor作為容器鏡像的儲存庫時,隨著應用服務鏡像的增加,如何透過內建機制將一臺Harbor的內容同步到另一個Harbor就變得愈來愈重要。本文將介紹如何透過內建機制同步Harbor的內容以及支援Harbor同步到其他相容的Image Registry的方式。
本篇將分享關於nginx ingress controller的基本操作,包括預先準備、流程、實際操作、將domain name 映射到Ingress LB IP、部署Demo App 驗證以及結論。
本篇將介紹Minio的功能和如何與Harbor進行整合,並說明這樣做的好處。包括Minio的優勢及Harbor x Minio的部署和測試。
本文闡述了Kubernetes內部網路通訊的基本概念,從容器到服務的溝通流程,並討論了Kubernetes使用的各種技術。重要的是,管理Kubernetes叢集時理解這些基本概念是極其重要的。
在Kubernetes cluster上建立Jenkins,並且使用動態方式建立Jenkins Agent。透過K8S解決傳統的Jenkins一對多架構的問題,最終建立基本Pipeline在Jenkins Web UI上,簡單驗證Jenkins engine正常運行。
本篇說明如何利用Kubernetes特色,將PostgreSQL DB以HA的架構來提供服務,並說明相關的實作流程與說明。
當您在K8S Cluster中使用Harbor作為容器鏡像的儲存庫時,隨著應用服務鏡像的增加,如何透過內建機制將一臺Harbor的內容同步到另一個Harbor就變得愈來愈重要。本文將介紹如何透過內建機制同步Harbor的內容以及支援Harbor同步到其他相容的Image Registry的方式。
本篇將分享關於nginx ingress controller的基本操作,包括預先準備、流程、實際操作、將domain name 映射到Ingress LB IP、部署Demo App 驗證以及結論。
你可能也想看
Google News 追蹤
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
解密日本fukushima商用雪櫃常見錯誤:HP開機錯誤不製冷,如何解決? 大家好,我是駿弘電器維修陪件你。今天要和大家分享的是一個關於日本商用雪櫃的維修故障,具體問題是HP開機錯誤不製冷。如果你遇到這一問題,不要慌張,我將為你提供解決方案。 首先,讓我們先來瞭解一下fukushima
Thumbnail
解密煙罩維修:揭開神祕面紗,發現無法繞過的難點之「維修運水煙罩」 尊敬的讀者們,今天我將和大家分享一些關於維修運水煙罩時最容易出現問題的部分,並向大家介紹一傢俱備實力的維修公司——駿弘電器維修。這將是一場帶你撥開迷霧,解開謎題的精彩冒險之旅! 作為一個維修技師,我對煙罩的問題並不陌生
當我加入第一份外商公司時,最大的文化衝擊是不就是賣產品嗎?為什麼一個任務需要這麼多人參與,並且似乎存在許多重疊的部分 (難怪有這麼多冗員可以裁),大家的工作分配究竟是如何進行的? 事實上,當一個業務團隊的配置充足且完整時,每個團隊成員都能為業務目標共同努力。不論是在業務橫向的產品線或是縱向的產業分布
Thumbnail
美國的債務上限,在經濟、政治和金融世界中,都扮演著極其重要的角色,瞭解它的概念和運作方式,對投資者來說是必要的,那麼,美國債務上限究竟是什麼?它對全球市場,尤其對投資者有什麼影響?一起揭開債務上限背後的神秘面紗,並解析其對我們投資決策的影響。
本書共有二十四章,共分為三大部分,第一部分為亞琛戰役、許特根森林,第二部分則是突出部自十二月十六日自二十六日止的戰鬥過程;最後則是結語。
Thumbnail
解密陌生人6 〈完結篇〉:不在堪薩斯市的布蘭達 還記得布蘭達這個名字嗎? 一位叫做安辛尼亞的粗魯惡霸警察, 竟然害的一位黑人女性自殺, 他應該要懂的更多尊重和禮節, 我們要狠狠的判刑他! 但,問題真的是他嗎?
Thumbnail
解密陌生人3 : 緊張的莎莉 透明性偏誤 預設為真,是人們容易上當的原因, 我們會持續相信, 直到,懷疑的線索超過閾值。 那,如果我們好好搜集線索,是不是就比較不會上當呢? 不,因為我們對線索也有偏誤。 我們相信微表情,我們說眼睛不會騙人, 我們總認為對方是 透明的。
Thumbnail
新的單元 開始囉~ 我們要用三本書來討論一個問題。 人類到底容不容易受騙上當? 而我們的第一本書,是2020年6月新鮮出爐的 葛拉維爾 解密陌生人。 這本書將會用三個原因告訴你,為什麼,人類 容易受騙。
Thumbnail
撰寫:許陳品 1981年7月3日,遭台灣警備總司令部(警總)帶走約談的旅美學者陳文成(1950─1981年),離奇陳屍於台大研究生圖書館旁,該事件不僅震驚海內外,其真相迄今未明、疑點重重,也引發民眾的好奇心。行政院“促進轉型正義委員會”(促轉會)於5月4日上午10時舉行“陳文成案調查報告記者會”
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
解密日本fukushima商用雪櫃常見錯誤:HP開機錯誤不製冷,如何解決? 大家好,我是駿弘電器維修陪件你。今天要和大家分享的是一個關於日本商用雪櫃的維修故障,具體問題是HP開機錯誤不製冷。如果你遇到這一問題,不要慌張,我將為你提供解決方案。 首先,讓我們先來瞭解一下fukushima
Thumbnail
解密煙罩維修:揭開神祕面紗,發現無法繞過的難點之「維修運水煙罩」 尊敬的讀者們,今天我將和大家分享一些關於維修運水煙罩時最容易出現問題的部分,並向大家介紹一傢俱備實力的維修公司——駿弘電器維修。這將是一場帶你撥開迷霧,解開謎題的精彩冒險之旅! 作為一個維修技師,我對煙罩的問題並不陌生
當我加入第一份外商公司時,最大的文化衝擊是不就是賣產品嗎?為什麼一個任務需要這麼多人參與,並且似乎存在許多重疊的部分 (難怪有這麼多冗員可以裁),大家的工作分配究竟是如何進行的? 事實上,當一個業務團隊的配置充足且完整時,每個團隊成員都能為業務目標共同努力。不論是在業務橫向的產品線或是縱向的產業分布
Thumbnail
美國的債務上限,在經濟、政治和金融世界中,都扮演著極其重要的角色,瞭解它的概念和運作方式,對投資者來說是必要的,那麼,美國債務上限究竟是什麼?它對全球市場,尤其對投資者有什麼影響?一起揭開債務上限背後的神秘面紗,並解析其對我們投資決策的影響。
本書共有二十四章,共分為三大部分,第一部分為亞琛戰役、許特根森林,第二部分則是突出部自十二月十六日自二十六日止的戰鬥過程;最後則是結語。
Thumbnail
解密陌生人6 〈完結篇〉:不在堪薩斯市的布蘭達 還記得布蘭達這個名字嗎? 一位叫做安辛尼亞的粗魯惡霸警察, 竟然害的一位黑人女性自殺, 他應該要懂的更多尊重和禮節, 我們要狠狠的判刑他! 但,問題真的是他嗎?
Thumbnail
解密陌生人3 : 緊張的莎莉 透明性偏誤 預設為真,是人們容易上當的原因, 我們會持續相信, 直到,懷疑的線索超過閾值。 那,如果我們好好搜集線索,是不是就比較不會上當呢? 不,因為我們對線索也有偏誤。 我們相信微表情,我們說眼睛不會騙人, 我們總認為對方是 透明的。
Thumbnail
新的單元 開始囉~ 我們要用三本書來討論一個問題。 人類到底容不容易受騙上當? 而我們的第一本書,是2020年6月新鮮出爐的 葛拉維爾 解密陌生人。 這本書將會用三個原因告訴你,為什麼,人類 容易受騙。
Thumbnail
撰寫:許陳品 1981年7月3日,遭台灣警備總司令部(警總)帶走約談的旅美學者陳文成(1950─1981年),離奇陳屍於台大研究生圖書館旁,該事件不僅震驚海內外,其真相迄今未明、疑點重重,也引發民眾的好奇心。行政院“促進轉型正義委員會”(促轉會)於5月4日上午10時舉行“陳文成案調查報告記者會”