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

更新於 發佈於 閱讀時間約 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
留言分享你的想法!
avatar-img
超健忘閒人的沙龍
15會員
40內容數
記錄IT社畜的自我學習筆記,如同專題名稱,主要是怕自已忘記自已做過什麼、學到什麼。索性就分享我自已在學習Kubernetes這條路上的各種測試、學習心得。
2024/05/08
本文將介紹如何在Gitlab上部署和註冊runner,以進行CI/CD測試。透過Docker-compose方式進行部署,同時注意安裝時的一些注意事項。建議學習者至少掌握一種以上的Pipeline工具,以滿足實務上的需求。
Thumbnail
2024/05/08
本文將介紹如何在Gitlab上部署和註冊runner,以進行CI/CD測試。透過Docker-compose方式進行部署,同時注意安裝時的一些注意事項。建議學習者至少掌握一種以上的Pipeline工具,以滿足實務上的需求。
Thumbnail
2024/04/19
上一篇說明了如何在Kubernetes上建立基本的MySQL standalone,並加入phpmyadmin(PMA)來進行圖形化的管理,本篇就再進階一步,實作MySQL replication架構(master-salve),並進行驗證是否成功。
Thumbnail
2024/04/19
上一篇說明了如何在Kubernetes上建立基本的MySQL standalone,並加入phpmyadmin(PMA)來進行圖形化的管理,本篇就再進階一步,實作MySQL replication架構(master-salve),並進行驗證是否成功。
Thumbnail
2024/04/09
本文記錄如何在Kubernetes環境下,部署Standalone架構的MySQL Database,並透過phpmyadmin進行管理。這篇文章將分成MySQL部署在K8S內的優勢、部署MySQL DB standalone、部署PhpMyAdmin (PMA)、結論四個部分進行說明與實作的流程。
Thumbnail
2024/04/09
本文記錄如何在Kubernetes環境下,部署Standalone架構的MySQL Database,並透過phpmyadmin進行管理。這篇文章將分成MySQL部署在K8S內的優勢、部署MySQL DB standalone、部署PhpMyAdmin (PMA)、結論四個部分進行說明與實作的流程。
Thumbnail
看更多
你可能也想看
Thumbnail
TOMICA第一波推出吉伊卡哇聯名小車車的時候馬上就被搶購一空,一直很扼腕當時沒有趕緊入手。前陣子閒來無事逛蝦皮,突然發現幾家商場都又開始重新上架,價格也都回到正常水準,估計是官方又再補了一批貨,想都沒想就立刻下單! 同文也跟大家分享近期蝦皮購物紀錄、好用推薦、蝦皮分潤計畫的聯盟行銷!
Thumbnail
TOMICA第一波推出吉伊卡哇聯名小車車的時候馬上就被搶購一空,一直很扼腕當時沒有趕緊入手。前陣子閒來無事逛蝦皮,突然發現幾家商場都又開始重新上架,價格也都回到正常水準,估計是官方又再補了一批貨,想都沒想就立刻下單! 同文也跟大家分享近期蝦皮購物紀錄、好用推薦、蝦皮分潤計畫的聯盟行銷!
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
安裝環境需求 64位元Linux,核心版本為3.1以上,且能滿足Ducker安裝環境。 機器之間要能夠互通。 外部存取權限。 硬體資源:兩核心CPU、8G記憶體、硬碟30GB以上。 安裝Kubeadm與Ducker Kubeadm是Kubernetes的一鍵部署工具。 增加Kube
Thumbnail
安裝環境需求 64位元Linux,核心版本為3.1以上,且能滿足Ducker安裝環境。 機器之間要能夠互通。 外部存取權限。 硬體資源:兩核心CPU、8G記憶體、硬碟30GB以上。 安裝Kubeadm與Ducker Kubeadm是Kubernetes的一鍵部署工具。 增加Kube
Thumbnail
在實際生產中,容器化技術開始走向「容器編排技術」,如:Kubernetes。因為Docker無法獨立支撐大規模容器化部署。 Kubernetes起源於Borg系統,所以在大規模的叢集管理,優於其他容器編排技術。它提供拉取映像檔、拉取執行容器、路由閘道、水平擴充、監控和備份等,除外還可以自動化處理容
Thumbnail
在實際生產中,容器化技術開始走向「容器編排技術」,如:Kubernetes。因為Docker無法獨立支撐大規模容器化部署。 Kubernetes起源於Borg系統,所以在大規模的叢集管理,優於其他容器編排技術。它提供拉取映像檔、拉取執行容器、路由閘道、水平擴充、監控和備份等,除外還可以自動化處理容
Thumbnail
本文介紹如何在GCP上使用Terraform建立CloudFlare DNS解析和模組化。通過閱讀本文,可以瞭解如何設置Terraform建立CloudFlare DNS解析以及取得GCS上的Terraform state file並透過Terraform建立CloudFlare DNS解析的步驟。
Thumbnail
本文介紹如何在GCP上使用Terraform建立CloudFlare DNS解析和模組化。通過閱讀本文,可以瞭解如何設置Terraform建立CloudFlare DNS解析以及取得GCS上的Terraform state file並透過Terraform建立CloudFlare DNS解析的步驟。
Thumbnail
本文將探討Kubernetes內部DNS解析的相關流程,並介紹如何利用DNS來找到服務。透過瞭解DNS的工作原理,可以讓應用服務的問題處理更有效率,並提供基本測試與結論。
Thumbnail
本文將探討Kubernetes內部DNS解析的相關流程,並介紹如何利用DNS來找到服務。透過瞭解DNS的工作原理,可以讓應用服務的問題處理更有效率,並提供基本測試與結論。
Thumbnail
本篇說明如何利用Kubernetes特色,將PostgreSQL DB以HA的架構來提供服務,並說明相關的實作流程與說明。
Thumbnail
本篇說明如何利用Kubernetes特色,將PostgreSQL DB以HA的架構來提供服務,並說明相關的實作流程與說明。
Thumbnail
引言 在當今的技術世界中,Kubernetes 已成為容器化應用的領導平台。作為一個高效的容器編排系統,它不僅管理著容器的部署和擴展,還提供了必要的自動化支持,以保證應用的高可用性和性能。在這個框架中,自動擴展功能起著至關重要的作用,特別是在面對不斷變化的負載和需求時。
Thumbnail
引言 在當今的技術世界中,Kubernetes 已成為容器化應用的領導平台。作為一個高效的容器編排系統,它不僅管理著容器的部署和擴展,還提供了必要的自動化支持,以保證應用的高可用性和性能。在這個框架中,自動擴展功能起著至關重要的作用,特別是在面對不斷變化的負載和需求時。
Thumbnail
本文將演示在安裝完 Kubernetes Cluster 後的基本元件安裝,包括 Calico/Calicoctl、Metric Server 和 Dashboard UI 的安裝方法以及相關問題與解決方式。
Thumbnail
本文將演示在安裝完 Kubernetes Cluster 後的基本元件安裝,包括 Calico/Calicoctl、Metric Server 和 Dashboard UI 的安裝方法以及相關問題與解決方式。
Thumbnail
這篇文章教你如何搭建Kubernetes Cluster,包括節點安裝前設定、軟體套件安裝、Control-Plane部署和加入運算節點等步驟。在建置之後,作者會分享一些基礎服務的安裝。希望這篇文章對你有所幫助。
Thumbnail
這篇文章教你如何搭建Kubernetes Cluster,包括節點安裝前設定、軟體套件安裝、Control-Plane部署和加入運算節點等步驟。在建置之後,作者會分享一些基礎服務的安裝。希望這篇文章對你有所幫助。
Thumbnail
本文章將說明如果您想要從頭建置一組具有Loadbalancer HA架構的Kubernetes Cluster時,你可能會需要做的事前準備工作。
Thumbnail
本文章將說明如果您想要從頭建置一組具有Loadbalancer HA架構的Kubernetes Cluster時,你可能會需要做的事前準備工作。
Thumbnail
最近在部署一些解決方案時,碰到了關於名稱解析上的一些問題,雖然有時候不難解決,但我發現如果清楚K8S有關於名稱解析的概念,會對除錯的時間與過程有很大的幫助。 透過本篇文章,除了幫自已留下問題查找的過程,同時也希望利用文章來整理自已對CoreDNS元件的一些觀念,同時也可以分享給大家參考。
Thumbnail
最近在部署一些解決方案時,碰到了關於名稱解析上的一些問題,雖然有時候不難解決,但我發現如果清楚K8S有關於名稱解析的概念,會對除錯的時間與過程有很大的幫助。 透過本篇文章,除了幫自已留下問題查找的過程,同時也希望利用文章來整理自已對CoreDNS元件的一些觀念,同時也可以分享給大家參考。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News