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