深入了解支持服務(wù)間通信的 3 個(gè)原生 K8s 對(duì)象:ClusterIP Service、DNS 和 Kube-Proxy。
概述 傳統(tǒng)的服務(wù)到服務(wù)通信 在進(jìn)入 Kubernetes 生態(tài)系統(tǒng)之前,快速了解一下傳統(tǒng)的服務(wù)到服務(wù)通信:通信是通過(guò) IP 地址進(jìn)行的,因此為了讓服務(wù) A 調(diào)用服務(wù) B,一種方法是為服務(wù) B 分配一個(gè)靜態(tài) IP 地址。現(xiàn)在,服務(wù) A 已經(jīng)知道該 IP 地址(這在處理極少數(shù)服務(wù)時(shí)可能會(huì)起作用)或服務(wù) B 使用域名注冊(cè)自己,并且服務(wù) A 通過(guò) DNS 查找獲取服務(wù) B 的聯(lián)系地址。
傳統(tǒng)的服務(wù)到服務(wù)通信 Kubernetes 網(wǎng)絡(luò)模型
現(xiàn)在在 Kubernetes 集群中,我們擁有構(gòu)成集群管理組件和一組工作機(jī)器(稱為節(jié)點(diǎn))的控制平面。這些節(jié)點(diǎn)托管 Pod,這些 Pod 將后端微服務(wù)作為容器化服務(wù)運(yùn)行。
集群內(nèi)的 Pod 到 Pod 通信
根據(jù) Kubernetes 網(wǎng)絡(luò)模型:
集群中的每個(gè) pod 都有自己唯一的集群范圍 IP 地址
所有 pod 都可以與集群內(nèi)的每個(gè) pod 通信
通信在沒(méi)有 NAT 的情況下發(fā)生,這意味著目標(biāo) pod 可以看到源 pod 的真實(shí) IP 地址。Kubernetes 認(rèn)為容器網(wǎng)絡(luò)或在其上運(yùn)行的應(yīng)用程序是可信的,不需要在網(wǎng)絡(luò)級(jí)別進(jìn)行身份驗(yàn)證。 ?
ClusterIP 服務(wù) ~ 基于 Pod 的抽象
既然集群中的每個(gè) pod 都有自己的 IP 地址,那么一個(gè) pod 與另一個(gè) pod 通信應(yīng)該很容易吧?
不,因?yàn)?Pod 是易變的,每次創(chuàng)建 pod 時(shí)都會(huì)獲得一個(gè)新的 IP 地址。所以客戶端服務(wù)必須以某種方式切換到下一個(gè)可用的 pod。
Pod 直接相互交談的問(wèn)題是另一個(gè)目標(biāo) Pod 的短暫性(隨時(shí)可能銷毀),其次是發(fā)現(xiàn)新 Pod IP 地址。
因此 Kubernetes 可以在一組 Pod 之上創(chuàng)建一個(gè)層,該層可以為該組提供單個(gè) IP 地址并可以提供基本的負(fù)載平衡。
通過(guò)持久 IP 地址上的 ClusterIP 服務(wù)公開(kāi)的 Pod,客戶端與服務(wù)對(duì)話,而不是直接與 Pod 對(duì)話。
這種抽象是由 Kubernetes 中一個(gè)名為ClusterIP service的服務(wù)對(duì)象提供的。它在多個(gè)節(jié)點(diǎn)上產(chǎn)生,從而在集群中創(chuàng)建單個(gè)服務(wù)。它可以接收任何端口上的請(qǐng)求并將其轉(zhuǎn)發(fā)到 pod 上的任何端口。
因此,當(dāng)應(yīng)用服務(wù) A 需要與服務(wù) B 對(duì)話時(shí),它會(huì)調(diào)用服務(wù) B 對(duì)象的 ClusterIP 服務(wù),而不是運(yùn)行該服務(wù)的單個(gè) pod。
ClusterIP 使用 Kubernetes 中標(biāo)簽和選擇器的標(biāo)準(zhǔn)模式來(lái)不斷掃描匹配選擇標(biāo)準(zhǔn)的 pod。Pod 有標(biāo)簽,服務(wù)有選擇器來(lái)查找標(biāo)簽。使用它,可以進(jìn)行基本的流量拆分,其中新舊版本的微服務(wù)在同一個(gè) clusterIP 服務(wù)后共存。
CoreDNS ~ 集群內(nèi)的服務(wù)發(fā)現(xiàn)
現(xiàn)在服務(wù) B 已經(jīng)獲得了一個(gè)持久的 IP 地址,服務(wù) A 仍然需要知道這個(gè) IP 地址是什么,然后才能與服務(wù) B 通信。
Kubernetes 支持使用 CoreDNS 進(jìn)行名稱解析。服務(wù) A 應(yīng)該知道它需要與之通信的 ClusterIP 的名稱(和端口)。
CoreDNS 掃描集群,每當(dāng)創(chuàng)建 ClusterIP 服務(wù)時(shí),它的條目就會(huì)添加到 DNS 服務(wù)器(如果已配置,它還會(huì)為每個(gè) pod 添加一個(gè)條目,但它與服務(wù)到服務(wù)的通信無(wú)關(guān))。
接下來(lái),CoreDNS 將自己暴露為 cluster IP 服務(wù)(默認(rèn)稱為 kube-dns),并且該服務(wù)被配置為 pod 中的 nameserver。
發(fā)起請(qǐng)求的 Pod 從 DNS 獲取 ClusterIP 服務(wù)的 IP 地址,然后可以使用 IP 地址和端口發(fā)起請(qǐng)求。 ?
Kube-proxy 打通 Service 和后端 Pod 之間(DNAT)
到目前為止,從本文來(lái)看,似乎是 ClusterIP 服務(wù)將請(qǐng)求調(diào)用轉(zhuǎn)發(fā)到后端 Pod。但實(shí)際上,它是由 Kube-proxy 完成的。
Kube-proxy 在每個(gè)節(jié)點(diǎn)上運(yùn)行,并監(jiān)視 Service 及其選擇的 Pod(實(shí)際上是 Endpoint 對(duì)象)。
當(dāng)節(jié)點(diǎn)上運(yùn)行的 pod 向 ClusterIP 服務(wù)發(fā)出請(qǐng)求時(shí),kube-proxy 會(huì)攔截它。
通過(guò)查看目的 IP 地址和端口,可以識(shí)別目的 ClusterIP 服務(wù)。并將此請(qǐng)求的目的地替換為實(shí)際 Pod 所在的端點(diǎn)地址。
如何協(xié)同工作?
ClusterIP Service、CoreDNS、客戶端 Pod、Kube-Proxy、EndPoint的交互
目標(biāo)的 ClusterIP 服務(wù)在 CoreDNS 中注冊(cè)
DNS 解析:每個(gè) pod 都有一個(gè) resolve.conf 文件,其中包含 CoreDNS 服務(wù)的 IP 地址,pod 執(zhí)行 DNS 查找。
Pod 使用它從 DNS 收到的 IP 地址和它已經(jīng)知道的端口來(lái)調(diào)用 clusterIP 服務(wù)。
目標(biāo)地址轉(zhuǎn)換:Kube-proxy 將目標(biāo) IP 地址更新為服務(wù) B 的 Pod 可用的地址。
編輯:黃飛
?
評(píng)論