0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Kubernetes網(wǎng)絡(luò)模型介紹以及如何實(shí)現(xiàn)常見網(wǎng)絡(luò)任務(wù)

馬哥Linux運(yùn)維 ? 來源:sookocheff ? 作者:sookocheff ? 2022-05-05 20:22 ? 次閱讀

Kubernetes 是為運(yùn)行分布式集群而建立的,分布式系統(tǒng)的本質(zhì)使得網(wǎng)絡(luò)成為 Kubernetes 的核心和必要組成部分,了解 Kubernetes 網(wǎng)絡(luò)模型可以使你能夠正確運(yùn)行、監(jiān)控和排查應(yīng)用程序故障。

04860a1a-c958-11ec-bce3-dac502259ad0.png

網(wǎng)絡(luò)是非常復(fù)雜的,擁有許多概念,對(duì)于不熟悉這個(gè)領(lǐng)域的用戶來說,這可能會(huì)有一定的難度,這里面有很多概念需要理解,并且還需要把這些概念整合起來形成一個(gè)連貫的整體,比如網(wǎng)絡(luò)命名空間、虛擬接口、IP 轉(zhuǎn)發(fā)、NAT 等概念。

Kubernetes 中對(duì)任何網(wǎng)絡(luò)實(shí)現(xiàn)都規(guī)定了以下的一些要求:

  • 所有 Pod 都可以在不使用 NAT 的情況下與所有其他 Pod 進(jìn)行通信
  • 所有節(jié)點(diǎn)都可以在沒有 NAT 的情況下與所有 Pod 進(jìn)行通信
  • Pod 自己的 IP 與其他 Pod 看到的 IP 是相同的

鑒于這些限制,我們需要解決幾個(gè)不同的網(wǎng)絡(luò)問題:

  1. 容器到容器的網(wǎng)絡(luò)
  2. Pod 到 Pod 的網(wǎng)絡(luò)
  3. Pod 到 Service 的網(wǎng)絡(luò)
  4. 互聯(lián)網(wǎng)到 Service 的網(wǎng)絡(luò)

接下來我們將來討論這些問題及其解決方案。

容器到容器網(wǎng)絡(luò)

通常情況下我們將虛擬機(jī)中的網(wǎng)絡(luò)通信視為直接與以太網(wǎng)設(shè)備進(jìn)行交互,如圖1所示。

04ab1a4e-c958-11ec-bce3-dac502259ad0.jpg圖1.網(wǎng)絡(luò)設(shè)備的理想視圖

實(shí)際的情況肯定比這要復(fù)雜,在 Linux 中,每個(gè)正在運(yùn)行的進(jìn)程都在一個(gè)網(wǎng)絡(luò)命名空間內(nèi)進(jìn)行通信,該命名空間提供了一個(gè)具有自己的路由、防火墻規(guī)則和網(wǎng)絡(luò)設(shè)備的邏輯網(wǎng)絡(luò)棧,從本質(zhì)上講,網(wǎng)絡(luò)命名空間為命名空間內(nèi)的所有進(jìn)程提供了一個(gè)全新的網(wǎng)絡(luò)堆棧。

Linux 用戶可以使用 ip 命令創(chuàng)建網(wǎng)絡(luò)命名空間。例如,以下命令將創(chuàng)建一個(gè)名為 ns1 的網(wǎng)絡(luò)命名空間。

$ipnetnsaddns1

命名空間創(chuàng)建后,會(huì)在 /var/run/netns 下面為其創(chuàng)建一個(gè)掛載點(diǎn),即使沒有附加任何進(jìn)程,命名空間也是可以保留的。

你可以通過列出 /var/run/netns 下的所有掛載點(diǎn)或使用 ip 命令來列出可用的命名空間。

$ls/var/run/netns
ns1
$ipnetns
ns1

默認(rèn)情況下,Linux 將為每個(gè)進(jìn)程分配到 root network namespace,以提供訪問外部的能力,如圖2所示。

04ce82ae-c958-11ec-bce3-dac502259ad0.png圖2.root network namespace

對(duì)于 Docker 而言,一個(gè) Pod 會(huì)被構(gòu)建成一組共享網(wǎng)絡(luò)命名空間的 Docker 容器,Pod 中的容器都有相同的 IP 地址和端口空間,它們都是通過分配給 Pod 的網(wǎng)絡(luò)命名空間來分配的,并且可以通過 localhost 訪問彼此,因?yàn)樗鼈兾挥谕粋€(gè)命名空間中。這是使用 Docker 作為 Pod 容器來實(shí)現(xiàn)的,它持有網(wǎng)絡(luò)命名空間,而應(yīng)用容器則通過 Docker 的 -net=container:sandbox-container 功能加入到該命名空間中,圖3顯示了每個(gè) Pod 如何由共享網(wǎng)絡(luò)命名空間內(nèi)的多個(gè) Docker 容器(ctr*)組成的。

04dcb0b8-c958-11ec-bce3-dac502259ad0.png圖3.每個(gè) Pod 的網(wǎng)絡(luò)命名空間

此外 Pod 中的容器還可以訪問共享卷,這些卷被定義為 Pod 的一部分,并且可以掛載到每個(gè)容器的文件系統(tǒng)中。

Pod 到 Pod 網(wǎng)絡(luò)

在 Kubernetes 中,每個(gè) Pod 都有一個(gè)真實(shí)的 IP 地址,每個(gè) Pod 都使用該 IP 地址與其他 Pod 進(jìn)行通信。接下來我們將來了解 Kubernetes 如何使用真實(shí)的 IP 來實(shí)現(xiàn) Pod 與 Pod 之間的通信的。我們先來討論同一節(jié)點(diǎn)上的 Pod 通信的方式。

從 Pod 的角度來看,它存在于自己的網(wǎng)絡(luò)命名空間中,需要與同一節(jié)點(diǎn)上的其他網(wǎng)絡(luò)命名空間進(jìn)行通信。值得慶幸的時(shí)候,命名空間可以使用 Linux 虛擬以太網(wǎng)設(shè)備或由兩個(gè)虛擬接口組成的 veth 對(duì)進(jìn)行連接,這些虛擬接口可以分布在多個(gè)命名空間上。要連接 Pod 命名空間,我們可以將 veth 對(duì)的的一側(cè)分配給 root network namespace,將另一側(cè)分配給 Pod 的網(wǎng)絡(luò)命名空間。每個(gè) veth 對(duì)就像一根網(wǎng)線,連接兩側(cè)并允許流量在它們之間流動(dòng)。這種設(shè)置可以復(fù)制到節(jié)點(diǎn)上的任意數(shù)量的 Pod。圖4顯示了連接虛擬機(jī)上每個(gè) Pod 的 root network namespace 的 veth 對(duì)。

04ee5bba-c958-11ec-bce3-dac502259ad0.png圖4.Pod 的 veth 對(duì)

現(xiàn)在 Pod 都有自己的網(wǎng)絡(luò)命名空間,這樣它們就有自己的網(wǎng)絡(luò)設(shè)備和 IP 地址,并且它們連接到節(jié)點(diǎn)的 root 命名空間,現(xiàn)在我們希望 Pod 能夠通過 root 命名空間進(jìn)行通信,那么我們將要使用一個(gè)網(wǎng)絡(luò) bridge(網(wǎng)橋)來實(shí)現(xiàn)。

Linux bridge 是用純軟件實(shí)現(xiàn)的虛擬交換機(jī),有著和物理交換機(jī)相同的功能,例如二層交換,MAC 地址學(xué)習(xí)等。因此我們可以把 veth pair 等設(shè)備綁定到網(wǎng)橋上,就像是把設(shè)備連接到物理交換機(jī)上一樣。bridge 的工作方式是通過檢查通過它的數(shù)據(jù)包目的地,并決定是否將數(shù)據(jù)包傳遞給連接到網(wǎng)橋的其他網(wǎng)段,從而在源和目的地之間維護(hù)一個(gè)轉(zhuǎn)發(fā)表。bridge 通過查看網(wǎng)絡(luò)中每個(gè)以太網(wǎng)設(shè)備的唯一 MAC 地址來決定是橋接數(shù)據(jù)還是丟棄數(shù)據(jù)。

Bridges 實(shí)現(xiàn)了 ARP 協(xié)議來發(fā)現(xiàn)與指定 IP 地址關(guān)聯(lián)的鏈路層 MAC 地址。當(dāng) bridge 接收到數(shù)據(jù)幀的時(shí)候,bridge 將該幀廣播給所有連接的設(shè)備(原始發(fā)送者除外),響應(yīng)該幀的設(shè)備被存儲(chǔ)在一個(gè)查找表中,未來具有相同 IP 地址的通信使用查找表來發(fā)現(xiàn)正確的 MAC 地址來轉(zhuǎn)發(fā)數(shù)據(jù)包。

05068866-c958-11ec-bce3-dac502259ad0.png圖5.使用橋接連接命名空間

同節(jié)點(diǎn) Pod 通信

網(wǎng)絡(luò)命名空間將每個(gè) Pod 隔離到自己的網(wǎng)絡(luò)堆棧中,虛擬以太網(wǎng)設(shè)備將每個(gè)命名空間連接到根命名空間,以及一個(gè)將命名空間連接在一起的網(wǎng)橋,這樣我們就準(zhǔn)備好在同一節(jié)點(diǎn)上的 Pod 之間發(fā)送流量了,如下圖6所示。

0511a354-c958-11ec-bce3-dac502259ad0.gif同節(jié)點(diǎn)上的Pod間的數(shù)據(jù)包移動(dòng)

這上圖中,pod1 向自己的網(wǎng)絡(luò)設(shè)備 eth0 發(fā)送了一個(gè)數(shù)據(jù)包,對(duì)于 pod1 來說,eth0 通過虛擬網(wǎng)絡(luò)設(shè)備連接到 root netns 的 veth0(1),網(wǎng)橋 cbr0 被配置為與 veth0 一端相連,一旦數(shù)據(jù)包到達(dá)網(wǎng)橋,網(wǎng)橋就會(huì)使用 ARP 協(xié)議將數(shù)據(jù)包發(fā)送到 veth1(3)。當(dāng)數(shù)據(jù)包到達(dá)虛擬設(shè)備 veth1 時(shí),它被直接轉(zhuǎn)發(fā)到 pod2 的命名空間內(nèi)的 eth0(4) 設(shè)備。這整個(gè)過程中,每個(gè) Pod 僅與 localhost 上的 eth0 進(jìn)行通信,流量就會(huì)被路由到正確的 Pod。

Kubernetes 的網(wǎng)絡(luò)模型決定了 Pod 必須可以通過其 IP 地址跨節(jié)點(diǎn)訪問,也就是說,一個(gè) Pod 的 IP 地址始終對(duì)網(wǎng)絡(luò)中的其他 Pod 是可見的,每個(gè) Pod 看待自己的 IP 地址的方式與其他 Pod 看待它的方式是相同的。接下來我們來看看不同節(jié)點(diǎn)上的 Pod 之間的流量路由問題。

跨節(jié)點(diǎn) Pod 通信

在研究了如何在同一節(jié)點(diǎn)上的 Pod 之間路由數(shù)據(jù)包之后,接下來我們來看下不同節(jié)點(diǎn)上的 Pod 之間的通信。Kubernetes 網(wǎng)絡(luò)模型要求 Pod 的 IP 是可以通過網(wǎng)絡(luò)訪問的,但它并沒有規(guī)定必須如何來實(shí)現(xiàn)。

通常集群中的每個(gè)節(jié)點(diǎn)都分配有一個(gè) CIDR,用來指定該節(jié)點(diǎn)上運(yùn)行的 Pod 可用的 IP 地址。一旦以 CIDR 為目的地的流量到達(dá)節(jié)點(diǎn),節(jié)點(diǎn)就會(huì)將流量轉(zhuǎn)發(fā)到正確的 Pod。圖7展示了兩個(gè)節(jié)點(diǎn)之間的網(wǎng)絡(luò)通信,假設(shè)網(wǎng)絡(luò)可以將 CIDR 中的流量轉(zhuǎn)發(fā)到正確的節(jié)點(diǎn)。

0533f710-c958-11ec-bce3-dac502259ad0.gif圖7.不同節(jié)點(diǎn)上的Pod間通信

上圖一樣和圖6相同的地方開始請(qǐng)求,但是這次目標(biāo) Pod(綠色標(biāo)注)與源 Pod(藍(lán)色標(biāo)注)位于不同的節(jié)點(diǎn)上。數(shù)據(jù)包首先通過 pod1 的網(wǎng)絡(luò)設(shè)備發(fā)送,該設(shè)備與 root netns(1)中的虛擬網(wǎng)絡(luò)設(shè)備配對(duì),最終數(shù)據(jù)包到達(dá) root netns 的網(wǎng)橋(2)上。這個(gè)時(shí)候網(wǎng)橋上的 ARP 會(huì)失敗,因?yàn)榕c網(wǎng)橋相連的沒有正確的數(shù)據(jù)包 MAC 地址。一旦失敗,網(wǎng)橋會(huì)將數(shù)據(jù)包發(fā)送到默認(rèn)路由上 - root netns 的 eth0 設(shè)備,此時(shí)就會(huì)路由離開節(jié)點(diǎn),進(jìn)入網(wǎng)絡(luò)(3)。我們現(xiàn)在假設(shè)網(wǎng)絡(luò)可以根據(jù)分配給節(jié)點(diǎn)的 CIDR 將數(shù)據(jù)包路由到正確的節(jié)點(diǎn)(4)。數(shù)據(jù)包進(jìn)入目標(biāo)節(jié)點(diǎn)的 root netns(VM2 上的 eth0),這那里它通過網(wǎng)橋路由到正確的虛擬設(shè)備(5)。最后,路由通過位于 pod4 的命名空間(6)中的虛擬設(shè)備 eth0 來完成。一般來說,每個(gè)節(jié)點(diǎn)都知道如何將數(shù)據(jù)包傳遞給其內(nèi)部運(yùn)行的 Pod,一旦數(shù)據(jù)包到達(dá)目標(biāo)節(jié)點(diǎn),數(shù)據(jù)包的流動(dòng)方式與同一節(jié)點(diǎn)上的 Pod 間通信方式一樣。

我們這里沒有介紹如何配置網(wǎng)絡(luò)來將 Pod IPs 的流量路由到負(fù)責(zé)這些 IP 的正確節(jié)點(diǎn),這和特定的網(wǎng)絡(luò)有關(guān)系,比如 AWS 就維護(hù)了一個(gè) Kubernetes 容器網(wǎng)絡(luò)插件,該插件允許在 AWS 的 VPC 環(huán)境中使用 [容器網(wǎng)絡(luò)接口(CNI)插件](https://github.com/aws/amazon-vpc-cni-k8s)來進(jìn)行節(jié)點(diǎn)到節(jié)點(diǎn)的網(wǎng)絡(luò)通信。

在 EC2 中,每個(gè)實(shí)例都綁定到一個(gè)彈性網(wǎng)絡(luò)接口 (ENI),并且所有 ENI 都連接在一個(gè) VPC 內(nèi) —— ENI 無需額外操作即可相互訪問。默認(rèn)情況下,每個(gè) EC2 實(shí)例部署一個(gè) ENI,但你可以創(chuàng)建多個(gè) ENI 并將它們部署到 EC2 實(shí)例上。Kubernetes 的 AWS CNI 插件會(huì)為節(jié)點(diǎn)上的每個(gè) Pod 創(chuàng)建一個(gè)新的 ENI,因?yàn)?VPC 中的 ENI 已經(jīng)連接到了現(xiàn)有 AWS 基礎(chǔ)設(shè)施中,這使得每個(gè) Pod 的 IP 地址可以在 VPC 內(nèi)自然尋址。當(dāng) CNI 插件被部署到集群時(shí),每個(gè)節(jié)點(diǎn)(EC2 實(shí)例)都會(huì)創(chuàng)建多個(gè)彈性網(wǎng)絡(luò)接口,并為這些實(shí)例分配 IP 地址,從而為每個(gè)節(jié)點(diǎn)形成了一個(gè) CIDR 塊。當(dāng)部署 Pod 時(shí),有一個(gè)小的二進(jìn)制文件會(huì)作為 DaemonSet 部署到 Kubernetes 集群中,從節(jié)點(diǎn)本地的 kubelet 進(jìn)程接收任何添加 Pod 到網(wǎng)絡(luò)的請(qǐng)求,這個(gè)二進(jìn)制文件會(huì)從節(jié)點(diǎn)的可用 ENI 池中挑選一個(gè)可用的 IP 地址,并通過在 Linux 內(nèi)核中連接虛擬網(wǎng)絡(luò)設(shè)備和網(wǎng)橋?qū)⑵浞峙浣o Pod,和在同一節(jié)點(diǎn)內(nèi)容的 Pod 通信一樣,有了這個(gè),Pod 的流量就可以跨集群內(nèi)的節(jié)點(diǎn)進(jìn)行通信了。

Pod 到 Service

上面我們已經(jīng)介紹了如何在 Pod 和它們相關(guān)的 IP 地址之間的通信。但是 Pod 的 IP 地址并不是固定不變的,會(huì)隨著應(yīng)用的擴(kuò)縮容、應(yīng)用崩潰或節(jié)點(diǎn)重啟而出現(xiàn)或消失,這些都可能導(dǎo)致 Pod IP 地址發(fā)生變化,Kubernetes 中可以通過 Service 對(duì)象來解決這個(gè)問題。

Kubernetes Service 管理一組 Pod,允許你跟蹤一組隨時(shí)間動(dòng)態(tài)變化的 Pod IP 地址,Service 作為對(duì) Pod 的抽象,為一組 Pod 分配一個(gè)虛擬的 VIP 地址,任何發(fā)往 Service VIP 的流量都會(huì)被路由到與其關(guān)聯(lián)的一組 Pod。這就允許與 Service 相關(guān)的 Pod 集可以隨時(shí)變更 - 客戶端只需要知道 Service VIP 即可。

創(chuàng)建 Service 時(shí)候,會(huì)創(chuàng)建一個(gè)新的虛擬 IP(也稱為 clusterIP),這集群中的任何地方,發(fā)往虛擬 IP 的流量都將負(fù)載均衡到與 Service 關(guān)聯(lián)的一組 Pod。實(shí)際上,Kubernetes 會(huì)自動(dòng)創(chuàng)建并維護(hù)一個(gè)分布式集群內(nèi)的負(fù)載均衡器,將流量分配到 Service 相關(guān)聯(lián)的健康 Pod 上。接下來讓我們仔細(xì)看看它是如何工作的。

netfilter 與 iptables

為了在集群中執(zhí)行負(fù)載均衡,Kubernetes 會(huì)依賴于 Linux 內(nèi)置的網(wǎng)絡(luò)框架 - netfilter。Netfilter 是 Linux 提供的一個(gè)框架,它允許以自定義處理程序的形式實(shí)現(xiàn)各種與網(wǎng)絡(luò)相關(guān)的操作,Netfilter 為數(shù)據(jù)包過濾、網(wǎng)絡(luò)地址轉(zhuǎn)換和端口轉(zhuǎn)換提供了各種功能和操作,它們提供了引導(dǎo)數(shù)據(jù)包通過網(wǎng)絡(luò)所需的功能,以及提供禁止數(shù)據(jù)包到達(dá)計(jì)算機(jī)網(wǎng)絡(luò)中敏感位置的能力。

iptables 是一個(gè)用戶空間程序,它提供了一個(gè)基于 table 的系統(tǒng),用于定義使用 netfilter 框架操作和轉(zhuǎn)換數(shù)據(jù)包的規(guī)則。在 Kubernetes 中,iptables 規(guī)則由 kube-proxy 控制器配置,該控制器會(huì) watch kube-apiserver 的變更,當(dāng)對(duì) Service 或 Pod 的變化更新了 Service 的虛擬 IP 地址或 Pod 的 IP 地址時(shí),iptables 規(guī)則會(huì)被自動(dòng)更新,以便正確地將指向 Service 的流量路由到支持 Pod。iptables 規(guī)則會(huì)監(jiān)聽發(fā)往 Service VIP 的流量,并且在匹配時(shí),從可用 Pod 集中選擇一個(gè)隨機(jī) Pod IP 地址,并且 iptables 規(guī)則將數(shù)據(jù)包的目標(biāo) IP 地址從 Service 的 VIP 更改為所選的 Pod IP。當(dāng) Pod 啟動(dòng)或關(guān)閉時(shí),iptables 規(guī)則集也會(huì)更新以反映集群的變化狀態(tài)。換句話說,iptables 已經(jīng)在節(jié)點(diǎn)上做了負(fù)載均衡,以將指向 Service VIP 的流量路由到實(shí)際的 Pod 的 IP 上。

在返回路徑上,IP 地址來自目標(biāo) Pod,在這種情況下,iptables 再次重寫 IP 頭以將 Pod IP 替換為 Service 的 IP,以便 Pod 認(rèn)為它一直只與 Service 的 IP 通信。

IPVS

Kubernetes 新版本已經(jīng)提供了另外一個(gè)用于集群負(fù)載均衡的選項(xiàng):IPVS, IPVS 也是構(gòu)建在 netfilter 之上的,并作為 Linux 內(nèi)核的一部分實(shí)現(xiàn)了傳輸層的負(fù)載均衡。IPVS 被合并到了 LVS(Linux 虛擬服務(wù)器)中,它在主機(jī)上運(yùn)行并充當(dāng)真實(shí)服務(wù)器集群前面的負(fù)載均衡器,IPVS 可以將基于 TCP 和 UDP 的服務(wù)請(qǐng)求定向到真實(shí)服務(wù)器,并使真實(shí)服務(wù)器的服務(wù)作為虛擬服務(wù)出現(xiàn)在一個(gè) IP 地址上。這使得 IPVS 非常適合 Kubernetes 服務(wù)。

這部署 kube-proxy 時(shí),可以指定使用 iptables 或 IPVS 來實(shí)現(xiàn)集群內(nèi)的負(fù)載均衡。IPVS 專為負(fù)載均衡而設(shè)計(jì),并使用更高效的數(shù)據(jù)結(jié)構(gòu)(哈希表),與 iptables 相比允許更大的規(guī)模。在使用 IPVS 模式的 Service 時(shí),會(huì)發(fā)生三件事:在 Node 節(jié)點(diǎn)上創(chuàng)建一個(gè)虛擬 IPVS 接口,將 Service 的 VIP 地址綁定到虛擬 IPVS 接口,并為每個(gè) Service VIP 地址創(chuàng)建 IPVS 服務(wù)器。

Pod 到 Service 通信

055f97e4-c958-11ec-bce3-dac502259ad0.gif圖8. Pod 與 Service 之間通信

當(dāng)這 Pod 和 Service 之間路由一個(gè)數(shù)據(jù)包時(shí),流量和以前開始的方式一樣,數(shù)據(jù)包首先通過連接到 Pod 的網(wǎng)絡(luò)命名空間(1)的 eth0 離開 Pod,。然后它通過虛擬網(wǎng)絡(luò)設(shè)備到達(dá)網(wǎng)橋(2)。網(wǎng)橋上運(yùn)行的 ARP 是不知道 Service 地址的,所以它通過默認(rèn)路由 eth0(3)將數(shù)據(jù)包傳輸出去。到這里會(huì)有一些不同的地方了,在 eth0 接收之前,該數(shù)據(jù)包會(huì)被 iptables 過濾,在收到數(shù)據(jù)包后,iptables 使用 kube-proxy 在節(jié)點(diǎn)上安裝的規(guī)則來響應(yīng) Service 或 Pod 事件,將數(shù)據(jù)包的目的地從 Service VIP 改寫為特定的 Pod IP(4)。該數(shù)據(jù)包現(xiàn)在就要到達(dá) pod4 了,而不是 Service 的 VIP,iptables 利用內(nèi)核的 conntrack 工具來記錄選擇的 Pod,以便將來的流量會(huì)被路由到相同的 Pod。從本質(zhì)上講,iptables 直接從節(jié)點(diǎn)上完成了集群內(nèi)的負(fù)載均衡,然后流量流向 Pod,剩下的就和前面的 Pod 到 Pod 通信一樣的了(5)。

Service 到 Pod 通信

05738254-c958-11ec-bce3-dac502259ad0.gif圖9.在 Service 和 Pod 之間通信

相應(yīng)的回包的時(shí)候,收到該數(shù)據(jù)包的 Pod 將響應(yīng),將源 IP 標(biāo)記為自己的 IP,將目標(biāo) IP 標(biāo)記為最初發(fā)送數(shù)據(jù)包的 Pod(1)。進(jìn)入節(jié)點(diǎn)后,數(shù)據(jù)包流經(jīng) iptables,它使用 conntrack 記住它之前所做的選擇,并將數(shù)據(jù)包的源重寫為 Service 的 VIP 而不是現(xiàn)在 Pod 的 IP(2)。從這里開始,數(shù)據(jù)包通過網(wǎng)橋流向與 Pod 的命名空間配對(duì)的虛擬網(wǎng)絡(luò)設(shè)備 (3),然后流向我們之前看到的 Pod 的虛擬網(wǎng)絡(luò)設(shè)備 (4)。

外網(wǎng)到 Service 通信

到這里我們已經(jīng)了解了 Kubernetes 集群內(nèi)的流量是如何路由的,但是更多的時(shí)候我們需要將服務(wù)暴露到外部去。這個(gè)時(shí)候會(huì)涉及到兩個(gè)主要的問題:

  • 將流量從 Kubernetes 服務(wù)路由到互聯(lián)網(wǎng)上去
  • 將流量從互聯(lián)網(wǎng)傳到你的 Kubernetes 服務(wù)

接下來我們就來討論這些問題。

出流量

從節(jié)點(diǎn)到公共 Internet 的路由流量也是和特定的網(wǎng)絡(luò)有關(guān)系的,這取決于你的網(wǎng)絡(luò)如何配置來發(fā)布流量的。這里我們以 AWS VPC 為例來進(jìn)行說明。

在 AWS 中,Kubernetes 集群在 VPC 中運(yùn)行,每個(gè)節(jié)點(diǎn)都分配有一個(gè)私有 IP 地址,該地址可從 Kubernetes 集群內(nèi)訪問。要從集群外部訪問服務(wù),你可以在 VPC 上附加一個(gè)外網(wǎng)網(wǎng)關(guān)。外網(wǎng)網(wǎng)關(guān)有兩個(gè)用途:在你的 VPC 路由表中為可路由到外網(wǎng)的流量提供目標(biāo),以及為已分配公共 IP 地址的實(shí)例執(zhí)行網(wǎng)絡(luò)地址轉(zhuǎn)換 (NAT)。NAT 轉(zhuǎn)換負(fù)責(zé)將集群節(jié)點(diǎn)的內(nèi)部 IP 地址更改為公網(wǎng)中可用的外部 IP 地址。

有了外網(wǎng)網(wǎng)關(guān),VM 就可以自由地將流量路由到外網(wǎng)。不過有一個(gè)小問題,Pod 有自己的 IP 地址,與運(yùn)行 Pod 的節(jié)點(diǎn) IP 地址不同,并且外網(wǎng)網(wǎng)關(guān)的 NAT 轉(zhuǎn)換僅適用于 VM IP 地址,因?yàn)樗恢滥男?Pod 在哪些 VM 上運(yùn)行 —— 網(wǎng)關(guān)不支持容器。讓我們看看 Kubernetes 是如何使用 iptables 來解決這個(gè)問題的。

在下圖中,數(shù)據(jù)包源自 Pod 的命名空間 (1),并經(jīng)過連接到根命名空間 (2) 的 veth 對(duì)。一旦進(jìn)入根命名空間,數(shù)據(jù)包就會(huì)從網(wǎng)橋移動(dòng)到默認(rèn)設(shè)備,因?yàn)閿?shù)據(jù)包上的 IP 與連接到網(wǎng)橋的任何網(wǎng)段都不匹配。在到達(dá)根命名空間的網(wǎng)絡(luò)設(shè)備 (3) 之前,iptables 會(huì)破壞數(shù)據(jù)包 (3)。在這種情況下,數(shù)據(jù)包的源 IP 地址是 Pod,如果我們將源保留為 Pod,外網(wǎng)網(wǎng)關(guān)將拒絕它,因?yàn)榫W(wǎng)關(guān) NAT 只了解連接到 VM 的 IP 地址。解決方案是讓 iptables 執(zhí)行源 NAT —— 更改數(shù)據(jù)包源,使數(shù)據(jù)包看起來來自 VM 而不是 Pod。有了正確的源 IP,數(shù)據(jù)包現(xiàn)在可以離開 VM (4) 并到達(dá)外網(wǎng)網(wǎng)關(guān) (5) 了。外網(wǎng)網(wǎng)關(guān)將執(zhí)行另一個(gè) NAT,將源 IP 從 VM 內(nèi)部 IP 重寫為公網(wǎng)IP。最后,數(shù)據(jù)包將到達(dá)互聯(lián)網(wǎng)上 (6)。在返回的路上,數(shù)據(jù)包遵循相同的路徑,并且任何源 IP 的修改都會(huì)被取消,這樣系統(tǒng)的每一層都會(huì)接收到它理解的 IP 地址:節(jié)點(diǎn)或 VM 級(jí)別的 VM 內(nèi)部,以及 Pod 內(nèi)的 Pod IP命名空間。

05853f62-c958-11ec-bce3-dac502259ad0.gif圖10.從Pod到互聯(lián)網(wǎng)通信

入流量

讓流量進(jìn)入你的集群是一個(gè)非常難以解決的問題。同樣這也和特定的網(wǎng)絡(luò)環(huán)境有關(guān)系,但是一般來說入流量可以分為兩種解決方案:

  • Service LoadBalancer
  • Ingress 控制器

LoadBalancer

當(dāng)你創(chuàng)建一個(gè) Kubernetes Service時(shí),你可以選擇指定一個(gè) LoadBalancer 來使用它。LoadBalancer 有為你提供服務(wù)的云供應(yīng)商負(fù)責(zé)創(chuàng)建負(fù)載均衡器,創(chuàng)建服務(wù)后,它將暴露負(fù)載均衡器的 IP 地址。終端用戶可以直接通過該 IP 地址與你的服務(wù)進(jìn)行通信。

LoadBalancer 到 Service

在部署了 Service 后,你使用的云提供商將會(huì)為你創(chuàng)建一個(gè)新的 LoadBalancer(1)。因?yàn)?LoadBalancer 不支持容器,所以一旦流量到達(dá) LoadBalancer,它就會(huì)分布在集群的各個(gè)節(jié)點(diǎn)上(2)。每個(gè)節(jié)點(diǎn)上的 iptables 規(guī)則會(huì)將來自 LoadBalancer 的傳入流量路由到正確的 Pod 上(3)。從 Pod 到客戶端的響應(yīng)將返回 Pod 的 IP,但客戶端需要有 LoadBalancer 的 IP 地址。正如我們之前看到的,iptables 和 conntrack 被用來在返回路徑上正確重寫 IP 地址。

下圖展示的就是托管 Pod 的三個(gè)節(jié)點(diǎn)前面的負(fù)載均衡器。傳入流量(1)指向 Service 的 LoadBalancer,一旦 LoadBalancer 接收到數(shù)據(jù)包(2),它就會(huì)隨機(jī)選擇一個(gè)節(jié)點(diǎn)。我們這里的示例中,我們選擇了沒有運(yùn)行 Pod 的節(jié)點(diǎn) VM2(3)。在這里,運(yùn)行在節(jié)點(diǎn)上的 iptables 規(guī)則將使用 kube-proxy 安裝到集群中的內(nèi)部負(fù)載均衡規(guī)則,將數(shù)據(jù)包轉(zhuǎn)發(fā)到正確的 Pod。iptables 執(zhí)行正確的 NAT 并將數(shù)據(jù)包轉(zhuǎn)發(fā)到正確的 Pod(4)。

05a34f48-c958-11ec-bce3-dac502259ad0.gif圖11.外網(wǎng)訪問 Service

Ingress 控制器

在七層網(wǎng)絡(luò)上 Ingress 在 HTTP/HTTPS 協(xié)議范圍內(nèi)運(yùn)行,并建立在 Service 之上。啟用 Ingress 的第一步是使用 Kubernetes 中的 NodePort 類型的 Service,如果你將 Service 設(shè)置成 NodePort 類型,Kubernetes master 將從你指定的范圍內(nèi)分配一個(gè)端口,并且每個(gè)節(jié)點(diǎn)都會(huì)將該端口代理到你的 Service,也就是說,任何指向節(jié)點(diǎn)端口的流量都將使用 iptables 規(guī)則轉(zhuǎn)發(fā)到 Service。

將節(jié)點(diǎn)的端口暴露在外網(wǎng),可以使用一個(gè) Ingress 對(duì)象,Ingress 是一個(gè)更高級(jí)別的 HTTP 負(fù)載均衡器,它將 HTTP 請(qǐng)求映射到 Kubernetes Service。根據(jù)控制器的實(shí)現(xiàn)方式,Ingress 的使用方式會(huì)有所不同。HTTP 負(fù)載均衡器,和四層網(wǎng)絡(luò)負(fù)載均衡器一樣,只了解節(jié)點(diǎn) IP(而不是 Pod IP),因此流量路由同樣利用由 kube-proxy 安裝在每個(gè)節(jié)點(diǎn)上的 iptables 規(guī)則提供的內(nèi)部負(fù)載均衡。

在 AWS 環(huán)境中,ALB Ingress 控制器使用 AWS 的七層應(yīng)用程序負(fù)載均衡器提供 Kubernetes 入口。下圖詳細(xì)介紹了此控制器創(chuàng)建的 AWS 組件,它還演示了 Ingress 流量從 ALB 到 Kubernetes 集群的路由。

05b21078-c958-11ec-bce3-dac502259ad0.png圖12.Ingress 控制器

創(chuàng)建后,(1) Ingress Controller 會(huì) watch 來自 Kubernetes APIServer 的 Ingress 事件。當(dāng)它找到滿足其要求的 Ingress 資源時(shí),它會(huì)開始創(chuàng)建 AWS 資源。AWS 將 Application Load Balancer (ALB) (2) 用于 Ingress 資源。負(fù)載均衡器與用于將請(qǐng)求路由到一個(gè)或多個(gè)注冊(cè)節(jié)點(diǎn)的 TargetGroup一起工作。(3) 在 AWS 中為 Ingress 資源描述的每個(gè)唯一 Kubernetes Service 創(chuàng)建 TargetGroup。(4) Listener 是一個(gè) ALB 進(jìn)程,它使用你配置的協(xié)議和端口檢查連接請(qǐng)求。Listener 由 Ingress 控制器為你的 Ingress 資源中描述的每個(gè)端口創(chuàng)建。最后,為 Ingress 資源中指定的每個(gè)路徑創(chuàng)建 TargetGroup 規(guī)則。這可以保證到特定路徑的流量被路由到正確的 Kubernetes 服務(wù)上 (5)。

Ingress 到 Service

流經(jīng) Ingress 的數(shù)據(jù)包的生命周期與 LoadBalancer 的生命周期非常相似。主要區(qū)別在于 Ingress 知道 URL 的路徑(可以根據(jù)路徑將流量路由到 Service)Ingress 和節(jié)點(diǎn)之間的初始連接是通過節(jié)點(diǎn)上為每個(gè)服務(wù)暴露的端口。

部署 Service 后,你使用的云提供商將為你創(chuàng)建一個(gè)新的 Ingress 負(fù)載均衡器 (1)。因?yàn)樨?fù)載均衡器不支持容器,一旦流量到達(dá)負(fù)載均衡器,它就會(huì)通過為你的服務(wù)端口分布在組成集群 (2) 的整個(gè)節(jié)點(diǎn)中。每個(gè)節(jié)點(diǎn)上的 iptables 規(guī)則會(huì)將來自負(fù)載均衡器的傳入流量路由到正確的 Pod (3)。Pod 到客戶端的響應(yīng)將返回 Pod 的 IP,但客戶端需要有負(fù)載均衡器的 IP 地址。正如我們之前看到的,iptables 和 conntrack 用于在返回路徑上正確重寫 IP。

05c2b338-c958-11ec-bce3-dac502259ad0.gif圖13.從 Ingress 到 Service

總結(jié)

本文介紹了 Kubernetes 網(wǎng)絡(luò)模型以及如何實(shí)現(xiàn)常見網(wǎng)絡(luò)任務(wù)。網(wǎng)絡(luò)知識(shí)點(diǎn)既廣泛又很深,所以我們這里不可能涵蓋所有的內(nèi)容,但是你可以以本文為起點(diǎn),然后去深入了解你感興趣的主題。

原文標(biāo)題:Kubernetes 網(wǎng)絡(luò)模型基礎(chǔ)指南

文章出處:【微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

審核編輯:湯梓紅
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 分布式
    +關(guān)注

    關(guān)注

    1

    文章

    824

    瀏覽量

    74394
  • 網(wǎng)絡(luò)模型
    +關(guān)注

    關(guān)注

    0

    文章

    43

    瀏覽量

    8387
  • kubernetes
    +關(guān)注

    關(guān)注

    0

    文章

    222

    瀏覽量

    8655

原文標(biāo)題:Kubernetes 網(wǎng)絡(luò)模型基礎(chǔ)指南

文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Kubernetes 網(wǎng)絡(luò)模型如何實(shí)現(xiàn)常見網(wǎng)絡(luò)任務(wù)

    Kubernetes 是為運(yùn)行分布式集群而建立的,分布式系統(tǒng)的本質(zhì)使得網(wǎng)絡(luò)成為 Kubernetes 的核心和必要組成部分,了解 Kubernetes
    的頭像 發(fā)表于 10-08 11:32 ?985次閱讀

    助聽器降噪神經(jīng)網(wǎng)絡(luò)模型

    抑制任務(wù)是語音增強(qiáng)領(lǐng)域的一個(gè)重要學(xué)科, 隨著深度神經(jīng)網(wǎng)絡(luò)的興起,提出了幾種基于深度模型的音頻處理新方法[1,2,3,4]。然而,這些通常是為離線處理而開發(fā)的,不需要考慮實(shí)時(shí)性。當(dāng)使用神經(jīng)網(wǎng)絡(luò)
    發(fā)表于 05-11 17:15

    使用全卷積網(wǎng)絡(luò)模型實(shí)現(xiàn)圖像分割

    OpenCv-C++-深度神經(jīng)網(wǎng)絡(luò)(DNN)模塊-使用FCN模型實(shí)現(xiàn)圖像分割
    發(fā)表于 05-28 07:33

    卷積神經(jīng)網(wǎng)絡(luò)模型發(fā)展及應(yīng)用

    介紹了卷積 神經(jīng)網(wǎng)絡(luò)的發(fā)展歷史,然后分析了典型的卷積神經(jīng) 網(wǎng)絡(luò)模型通過堆疊結(jié)構(gòu)、網(wǎng)中網(wǎng)結(jié)構(gòu)、殘差結(jié)構(gòu)以及 注意力機(jī)制提升
    發(fā)表于 08-02 10:39

    Kubernetes網(wǎng)絡(luò)隔離NetworkPolicy實(shí)驗(yàn)

    隔離。幸好,Kubernetes提供了NetworkPolicy,支持按Namespace級(jí)別的網(wǎng)絡(luò)隔離。 使用NetworkPolicy需要kubernetes1.8以及calico
    發(fā)表于 11-28 10:00 ?2631次閱讀

    Kubernetes網(wǎng)絡(luò)模型的基礎(chǔ)知識(shí)

    Kubernetes 是為運(yùn)行分布式集群而建立的,分布式系統(tǒng)的本質(zhì)使得網(wǎng)絡(luò)成為 Kubernetes 的核心和必要組成部分,了解 Kubernetes
    的頭像 發(fā)表于 07-20 09:46 ?1101次閱讀

    Kubernetes集群發(fā)生網(wǎng)絡(luò)異常時(shí)如何排查

    本文將引入一個(gè)思路:“在 Kubernetes 集群發(fā)生網(wǎng)絡(luò)異常時(shí)如何排查”。文章將引入 Kubernetes 集群中網(wǎng)絡(luò)排查的思路,包含網(wǎng)絡(luò)
    的頭像 發(fā)表于 09-02 09:45 ?4566次閱讀

    Kubernetes中的網(wǎng)絡(luò)模型

    kubernetes 中,underlay network 中比較典型的例子是通過將宿主機(jī)作為路由器設(shè)備,Pod 的網(wǎng)絡(luò)則通過學(xué)習(xí)路由條目從而實(shí)現(xiàn)跨節(jié)點(diǎn)通訊。
    的頭像 發(fā)表于 12-14 10:07 ?762次閱讀

    Kubernetes Pod如何獨(dú)立工作

    在學(xué)習(xí) Kubernetes 網(wǎng)絡(luò)模型的過程中,了解各種網(wǎng)絡(luò)組件的作用以及如何交互非常重要。本文就介紹
    的頭像 發(fā)表于 05-16 14:29 ?542次閱讀
    <b class='flag-5'>Kubernetes</b> Pod如何獨(dú)立工作

    各種網(wǎng)絡(luò)組件在 Kubernetes 集群中是如何交互的

    Kubernetes 中有多種網(wǎng)絡(luò)設(shè)置方法,以及 container runtime 的各種選項(xiàng)。這篇文章將使用 Flannel 作為 network provider,并使用 Containered 作為 containe
    的頭像 發(fā)表于 05-23 09:49 ?696次閱讀
    各種<b class='flag-5'>網(wǎng)絡(luò)</b>組件在 <b class='flag-5'>Kubernetes</b> 集群中是如何交互的

    常見的卷積神經(jīng)網(wǎng)絡(luò)模型 典型的卷積神經(jīng)網(wǎng)絡(luò)模型

    各種任務(wù)表現(xiàn)出色。在本文中,我們將介紹常見的卷積神經(jīng)網(wǎng)絡(luò)模型,包括LeNet、AlexNet、VGG、GoogLeNet、ResNet、In
    的頭像 發(fā)表于 08-21 17:11 ?2654次閱讀

    探討Kubernetes中的網(wǎng)絡(luò)模型(各種網(wǎng)絡(luò)模型分析)

    kubernetes 中,underlay network 中比較典型的例子是通過將宿主機(jī)作為路由器設(shè)備,Pod 的網(wǎng)絡(luò)則通過學(xué)習(xí)路由條目從而實(shí)現(xiàn)跨節(jié)點(diǎn)通訊。
    發(fā)表于 08-24 12:44 ?286次閱讀
    探討<b class='flag-5'>Kubernetes</b>中的<b class='flag-5'>網(wǎng)絡(luò)</b><b class='flag-5'>模型</b>(各種<b class='flag-5'>網(wǎng)絡(luò)</b><b class='flag-5'>模型</b>分析)

    構(gòu)建神經(jīng)網(wǎng)絡(luò)模型的常用方法 神經(jīng)網(wǎng)絡(luò)模型的常用算法介紹

    神經(jīng)網(wǎng)絡(luò)模型是一種通過模擬生物神經(jīng)元間相互作用的方式實(shí)現(xiàn)信息處理和學(xué)習(xí)的計(jì)算機(jī)模型。它能夠?qū)斎霐?shù)據(jù)進(jìn)行分類、回歸、預(yù)測(cè)和聚類等任務(wù),已經(jīng)廣
    發(fā)表于 08-28 18:25 ?944次閱讀

    常見網(wǎng)絡(luò)接口介紹

    在現(xiàn)今的數(shù)字化時(shí)代,網(wǎng)絡(luò)接口作為連接各種設(shè)備和網(wǎng)絡(luò)的橋梁,其重要性不言而喻。網(wǎng)絡(luò)接口不僅關(guān)系到數(shù)據(jù)傳輸?shù)乃俾屎唾|(zhì)量,還影響著整個(gè)網(wǎng)絡(luò)的穩(wěn)定性和安全性。因此,了解和選擇合適的
    的頭像 發(fā)表于 05-29 16:07 ?945次閱讀

    經(jīng)典卷積網(wǎng)絡(luò)模型介紹

    經(jīng)典卷積網(wǎng)絡(luò)模型在深度學(xué)習(xí)領(lǐng)域,尤其是在計(jì)算機(jī)視覺任務(wù)中,扮演著舉足輕重的角色。這些模型通過不斷演進(jìn)和創(chuàng)新,推動(dòng)了圖像處理、目標(biāo)檢測(cè)、圖像生成、語義分割等多個(gè)領(lǐng)域的發(fā)展。以下將詳細(xì)探討
    的頭像 發(fā)表于 07-11 11:45 ?306次閱讀