色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

跟蹤Kubernetes的網絡流量路徑

馬哥Linux運維 ? 來源:馬哥Linux運維 ? 作者:馬哥Linux運維 ? 2022-10-24 10:22 ? 次閱讀

通過本文,你將了解在 Kubernetes 內外,數據包是如何轉發的,從原始的 Web 請求開始,到托管應用程序的容器。 在深入了解在 Kubernetes 集群中數據包如何流轉的細節之前,先明確一下 Kubernetes 對網絡的要求。

Kubernetes 網絡模型定義了一組基本規則:

在不使用網絡地址轉換 (NAT) 的情況下,集群中的 Pod 能夠與任意其他 Pod 進行通信

在不使用網絡地址轉換 (NAT) 的情況下,在集群節點上運行的程序能與同一節點上的任何 Pod 進行通信。

每個 Pod 都有自己的 IP 地址(IP-per-Pod),并且任意其他 Pod 都可以通過相同的這個地址訪問它。

這些要求,不會將具體實現限制在某種解決方案上。

相反,它們籠統地描述了集群網絡的特性。

為了滿足這些限制,你必須解決以下挑戰:

如何確保同一個 Pod 中的容器行為就像它們在同一個主機上一樣?

集群中的 Pod 能否訪問其他 Pod?

Pod 可以訪問服務嗎?服務是負載均衡的嗎?

Pod 可以接收集群外部的流量嗎?

在本文中,將重點關注前三點,從 Pod 內的網絡,容器到容器的通信說起。

Linux 網絡命名空間如何在 Pod 中工作

讓我們來看一個運行應用的主容器和伴隨一起的另一個容器。

在示例中,有一個帶有 nginx 和 busybox 容器的 Pod:

apiVersion:v1
kind:Pod
metadata:
name:multi-container-Pod
spec:
containers:
-name:container-1
image:busybox
command:['/bin/sh','-c','sleep1d']
-name:container-2
image:nginx

部署時,會發生以下事情:

Pod 在節點上擁有獨立的網絡命名空間。

分配一個 IP 地址給 Pod ,兩個容器之間共享端口

兩個容器共享相同的網絡命名空間,并在本地彼此可見。

網絡配置在后臺迅速完成。

但是,讓我們退后一步,嘗試理解為什么運行容器需要上述動作。

在 Linux 中,網絡命名空間是獨立的、隔離的邏輯空間。

你可以將網絡命名空間視為,將物理網絡接口分割小塊之后的獨立部分。

每個部分都可以單獨配置,并擁有自己的網絡規則和資源。

這些包括防火墻規則、接口(虛擬的或物理的)、路由以及與網絡相關的所有內容。

物理網絡接口持有根網絡命名空間。

d23603f6-5216-11ed-a3b6-dac502259ad0.svg ? ?2. 你可以使用 Linux 網絡命名空間來創建獨立的網絡。每個網絡都是獨立的,除非你進行配置,默認不會與其他網絡互通。 d253e65a-5216-11ed-a3b6-dac502259ad0.svg

但最終,還是需要物理接口處理所有真實的數據包,所有虛擬接口都是基于物理接口創建的。

網絡命名空間可以通過 ip-netns 進行管理,使用 ip netns list 可以列出主機上的命名空間。

需要注意的是,創建的網絡命名空間會出現在 /var/run/netns 下面,但 Docker 并沒有遵循這一規則。

例如,這是 Kubernetes 節點的一些命名空間:

$ipnetnslist

cni-0f226515-e28b-df13-9f16-dd79456825ac(id:3)
cni-4e4dfaac-89a6-2034-6098-dd8b2ee51dcd(id:4)
cni-7e94f0cc-9ee8-6a46-178a-55c73ce58f2e(id:2)
cni-7619c818-5b66-5d45-91c1-1c516f559291(id:1)
cni-3004ec2c-9ac2-2928-b556-82c7fb37a4d8(id:0)

注意 cni- 前綴;這意味著命名空間是由 CNI 插件創建的。

當你創建一個 Pod,Pod 被分配給一個節點后,CNI 將:

分配 IP 地址。

將容器連接到網絡。

如果 Pod 包含多個容器,那么這些容器都將被放在同一個命名空間中。

當創建 Pod 時,容器運行時會給容器創建一個網絡命名空間。

d26e3d3e-5216-11ed-a3b6-dac502259ad0.svg ? 2. 然后 CNI 負責給 Pod 分配一個 IP 地址。 d289dc1a-5216-11ed-a3b6-dac502259ad0.svg ? 3. 最后 CNI 將容器連接到網絡的其余部分。 d2b6142e-5216-11ed-a3b6-dac502259ad0.svg

那么,當你列出節點上的容器的命名空間會發生什么呢?

你可以通過 SSH 連接到 Kubernetes 節點并查看命名空間:

$lsns-tnet

NSTYPENPROCSPIDUSERNETNSIDNSFSCOMMAND
4026531992net1711rootunassigned/run/docker/netns/default/sbin/initnoembednorestore
4026532286net24808655350/run/docker/netns/56c020051c3b/pause
4026532414net55489655351/run/docker/netns/7db647b9b187/pause

lsns 是一個用于列出主機上所有可用命名空間的命令。

請記住,Linux 中有多種命名空間類型。

Nginx 容器在哪里?

那些 pause 容器是什么?

在 Pod 中,pause 容器創建了網絡命名空間

先列出節點上的所有命名空間,看看能否找到 Nginx 容器:

$lsns
NSTYPENPROCSPIDUSERCOMMAND
#truncatedoutput
4026532414net5548965535/pause
4026532513mnt15599rootsleep1d
4026532514uts15599rootsleep1d
4026532515pid15599rootsleep1d
4026532516mnt35777rootnginx:masterprocessnginx-gdaemonoff;
4026532517uts35777rootnginx:masterprocessnginx-gdaemonoff;
4026532518pid35777rootnginx:masterprocessnginx-gdaemonoff;

Nginx 容器在掛載 (mnt)、Unix time-sharing (uts) 和 PID (pid) 命名空間中,但不在網絡命名空間 (net) 中。

不幸的是,lsns 只顯示每個進程最小的 PID,但你可以根據這個進程 ID 進一步過濾。

使用以下命令,在所有命名空間中檢索 Nginx 容器:

$sudolsns-p5777

NSTYPENPROCSPIDUSERCOMMAND
4026531835cgroup1781root/sbin/initnoembednorestore
4026531837user1781root/sbin/initnoembednorestore
4026532411ipc5548965535/pause
4026532414net5548965535/pause
4026532516mnt35777rootnginx:masterprocessnginx-gdaemonoff;
4026532517uts35777rootnginx:masterprocessnginx-gdaemonoff;
4026532518pid35777rootnginx:masterprocessnginx-gdaemonoff;

pause 進程再次出現,它劫持了網絡命名空間。

這是怎么回事?

集群中的每個 Pod 都有一個額外的隱藏容器在后臺運行,稱為 pause 容器。

列出在節點上運行的容器并獲取 pause 容器:

$dockerps|greppause

fa9666c1d9c6k8s.gcr.io/pause:3.4.1"/pause"k8s_POD_kube-dns-599484b884-sv2js…
44218e010aebk8s.gcr.io/pause:3.4.1"/pause"k8s_POD_blackbox-exporter-55c457d…
5fb4b5942c66k8s.gcr.io/pause:3.4.1"/pause"k8s_POD_kube-dns-599484b884-cq99x…
8007db79dcf2k8s.gcr.io/pause:3.4.1"/pause"k8s_POD_konnectivity-agent-84f87c…

可以看到,節點上的每一個 Pod 都會有一個對應的 pause 容器。

這個 pause 容器負責創建和維持網絡命名空間。

底層容器運行時會完成網絡命名空間的創建,通常是由 containerd 或 CRI-O 完成。

在部署 Pod 和創建容器之前,由運行時創建網絡命名空間。

容器運行時會自動完成這些,不需要手工執行 ip netns 創建命名空間。

話題回到 pause 容器。

它包含非常少的代碼,并且在部署后立即進入睡眠狀態。

但是,它是必不可少的,并且在 Kubernetes 生態系統中起著至關重要的作用。

創建 Pod 時,容器運行時會創建一個帶有睡眠容器的網絡命名空間。

d2e99eca-5216-11ed-a3b6-dac502259ad0.svg ? 2. Pod 中的其他容器都會加入由 pause 容器創建的網絡名稱空間。 d2fdf0b4-5216-11ed-a3b6-dac502259ad0.svg ? 3. 此時,CNI 分配 IP 地址并將容器連接到網絡。 d32322da-5216-11ed-a3b6-dac502259ad0.svg

一個進入睡眠狀態的容器有什么用?

為了理解它的用途,讓我們想象一個 Pod 有兩個容器,就像前面的例子一樣,但沒有 pause 容器。

一旦容器啟動,CNI 將會:

使 busybox 容器加入之前的網絡命名空間。

分配 IP 地址。

將容器連接到網絡。

如果 Nginx 崩潰了怎么辦?

CNI 將不得不再次執行所有步驟,并且兩個容器的網絡都將中斷。

由于睡眠容器不太可能有任何錯誤,因此創建網絡命名空間通常是一種更安全、更健壯的選擇。

如果 Pod 中的一個容器崩潰了,剩下的仍然可以回復其他網絡請求。



分配一個 IP 地址給 Pod

前面我提到 Pod 和兩個容器將具有同一個 IP 地址。

那是怎樣配置的呢?

在 Pod 網絡命名空間內,創建了一個接口,并分配了一個 IP 地址。

讓我們驗證一下。

首先,找到 Pod 的 IP 地址:

$ kubectlgetPodmulti-container-Pod-ojsonpath={.status.PodIP}

10.244.4.40

接下來,找到相關的網絡命名空間。

由于網絡命名空間是從物理接口創建的,需要先訪問集群節點。

如果你運行的是 minikube,使用 minikube ssh 訪問節點。如果在云廠中運行,那么應該有某種方法可以通過 SSH 訪問節點。

進入后,找到最新創建的命名網絡命名空間:

$ls-lt/var/run/netns

total0
-r--r--r--1rootroot0Sep2513:34cni-0f226515-e28b-df13-9f16-dd79456825ac
-r--r--r--1rootroot0Sep2409:39cni-4e4dfaac-89a6-2034-6098-dd8b2ee51dcd
-r--r--r--1rootroot0Sep2409:39cni-7e94f0cc-9ee8-6a46-178a-55c73ce58f2e
-r--r--r--1rootroot0Sep2409:39cni-7619c818-5b66-5d45-91c1-1c516f559291
-r--r--r--1rootroot0Sep2409:39cni-3004ec2c-9ac2-2928-b556-82c7fb37a4d8

在示例中,就是 cni-0f226515-e28b-df13-9f16-dd79456825ac。然后,可以在該命名空間內運行 exec 命令:

$ipnetnsexeccni-0f226515-e28b-df13-9f16-dd79456825acipa

#outputtruncated
3:eth0@if12:mtu1450qdiscnoqueuestateUPgroupdefault
link/ether16f856:77brdffffff:fflink-netnsid0
inet10.244.4.40/32brd10.244.4.40scopeglobaleth0
valid_lftforeverpreferred_lftforever
inet6fe80:f8ff5677/64scopelink
valid_lftforeverpreferred_lftforever

這個 IP 就是 Pod 的 IP 地址!通過查找 @if12 中的 12 找到網絡接口

$iplink|grep-A1^12

12:vethweplb3f36a0@if16:mtu1376qdiscnoqueuemasterweavestateUPmodeDEFAULTgroupdefault
link/ether7273d9:f6brdffffff:fflink-netnsid1

你還可以驗證 Nginx 容器是否監聽了來自該命名空間內的 HTTP 流量:

$ipnetnsexeccni-0f226515-e28b-df13-9f16-dd79456825acnetstat-lnp

ActiveInternetconnections(onlyservers)
ProtoRecv-QSend-QLocalAddressForeignAddressStatePID/Programname
tcp000.0.0.0:800.0.0.0:*LISTEN692698/nginx:master
tcp600:::80:::*LISTEN692698/nginx:master

如果你無法通過 SSH 訪問集群中的工作節點,你可以使用 kubectl exec 獲取到 busybox 容器的 shell 并直接在內部使用 ip 和 netstat 命令。

剛剛我們介紹了容器之間的通信,再來看看如何建立 Pod 到 Pod 的通信吧。

查看集群中 Pod 到 Pod 的流量

Pod 到 Pod 的通信有兩種可能的情況:

Pod 流量的目的地是同一節點上的 Pod。

Pod 流量的目的地是在不同節點上的 Pod。

整個工作流依賴于虛擬接口對和網橋,下面先來了解一下這部分的內容。

為了讓一個 Pod 與其他 Pod 通信,它必須先訪問節點的根命名空間。

通過虛擬以太網對來實現 Pod 和根命名空間的連接。

這些虛擬接口設備(veth 中的 v)連接并充當兩個命名空間之間的隧道。

使用此 veth 設備,你將一端連接到 Pod 的命名空間,另一端連接到根命名空間。

d32322da-5216-11ed-a3b6-dac502259ad0.svg

CNI 可以幫你執行這些操作,但你也可以手動執行:

$iplinkaddveth1netnsPod-namespacetypevethpeerveth2netnsroot

現在 Pod 的命名空間有一個可以訪問根命名空間的 隧道。

節點上,新建的每一個 Pod 都會設置這樣的 veth 對。

一個是,創建接口對;另一個是為以太網設備分配地址并配置默認路由。

下面看看如何在 Pod 的命名空間中設置 veth1 接口:

$ipnetnsexeccni-0f226515-e28b-df13-9f16-dd79456825acipaddradd10.244.4.40/24devveth1
$ipnetnsexeccni-0f226515-e28b-df13-9f16-dd79456825aciplinksetveth1up
$ipnetnsexeccni-0f226515-e28b-df13-9f16-dd79456825aciprouteadddefaultvia10.244.4.40

在節點上,讓我們創建另一個 veth2 對:

$ipaddradd169.254.132.141/16devveth2
$iplinksetveth2up

可以像前面一樣檢查現有的 veth 對。

在 Pod 的命名空間中,檢索 eth0 接口的后綴。

$ipnetnsexeccni-0f226515-e28b-df13-9f16-dd79456825aciplinkshowtypeveth

3:eth0@if12:mtu1450qdiscnoqueuestateUPmodeDEFAULTgroupdefault
link/ether16f856:77brdffffff:fflink-netnsid0

在這種情況下,可以使用命令 grep -A1 ^12 查找(或滾動到目標所在處):

$iplinkshowtypeveth

#outputtruncated
12:cali97e50e215bd@if3:mtu1450qdiscnoqueuestateUPmodeDEFAULTgroupdefault
link/ethereeeeee:eebrdffffff:fflink-netnscni-0f226515-e28b-df13-9f16-dd79456825ac

也可以使用 ip -n cni-0f226515-e28b-df13-9f16-dd79456825ac link show type veth.命令

注意 3: eth0@if12和12: cali97e50e215bd@if3 接口上的符號。

從 Pod 命名空間,該 eth0 接口連接到根命名空間的 12 號接口,因此是 @if12.

在 veth 對的另一端,根命名空間連接到 Pod 命名空間的 3 號接口。

接下來是連接 veth 對兩端的橋接器

Pod 網絡命名空間連接到以太網橋

網橋會匯聚位于根命名空間中的每一個虛擬接口。這個網橋允許虛擬 pair 之間的流量,也允許穿過公共根命名空間的流量。

補充一下相關原理。

以太網橋位于 OSI 網絡模型 的第 2 層。

你可以將網橋視為接受來自不同命名空間和接口的連接的虛擬交換機

以太網橋可以連接節點上的多個可用網絡。

因此,可以使用網橋連接兩個接口,即 Pod 命名空間的 veth 連接到同一節點上另一個 Pod 的 veth。

d378d414-5216-11ed-a3b6-dac502259ad0.svg

接下來,繼續看網橋和 veth 對的用途。

跟蹤在同一節點上 Pod 到 Pod 的流量

假設同一個節點上有兩個 Pod,Pod-A 向 Pod-B 發送消息。

由于訪問目標不在同一個命名空間,Pod-A 將數據包發送到其默認接口 eth0。這個接口與 veth 對的一端綁定,作為隧道。這樣,數據包會被轉發到節點上的根命名空間。

d3a3e686-5216-11ed-a3b6-dac502259ad0.svg ? 2. 以太網網橋作為一個虛擬交換機,需要目標 Pod-B 的 MAC 地址才能工作。 d3c2ffc6-5216-11ed-a3b6-dac502259ad0.svg ? 3. ARP 協議會解決這個問題。當幀到達網橋時,會向所有連接的設備發送 ARP 廣播。網橋廣播詢問持有 Pod-B 的 IP 地址 d3e91d6e-5216-11ed-a3b6-dac502259ad0.svg ? 4. 此時會收到一個帶有 Pod-B IP 的 MAC 地址應答,這條消息會被存儲在橋接 ARP 緩存(查找表)中。 d40e1e48-5216-11ed-a3b6-dac502259ad0.svg ? 5. IP 地址和 MAC 地址的映射關系存儲之后,網橋就在表中查找,并將數據包轉發到正確的端點。數據包到達根命名空間內 Pod-B 的 veth 之后,很快又到達 Pod-B 命名空間內的 eth0 接口。 d455ecaa-5216-11ed-a3b6-dac502259ad0.svg

至此,Pod-A 和 Pod-B 之間的通信就成功了。

跟蹤不同節點上的 Pod 到 Pod 通信

對于跨節點 Pod 之間的通信,會經過額外的通信跳躍。

前幾個步驟保持不變,直到數據包到達根命名空間并需要發送到 Pod-B。

d475b18e-5216-11ed-a3b6-dac502259ad0.svg ? 2. 當目的 IP 不在本地網絡中時,報文被轉發到節點的默認網關。節點的出口網關或默認網關,通常位于節點與網絡相連的物理接口 eth0 上。 d4ade1ee-5216-11ed-a3b6-dac502259ad0.svg

此時 不會發生 ARP 解析,因為源 IP 和目標 IP 不在同一個網段中。

網段的檢查是使用按位運算完成的。

當目的 IP 不在當前網絡段時,數據包被轉發到節點的默認網關。

按位運算的工作原理

在確定數據包的轉發位置時,源節點必須執行位運算

這也稱為與操作。

復習一下,按位與運算的規則:

0AND0=0
0AND1=0
1AND0=0
1AND1=1

除了 1 與 1 以外的都是 false。

如果源節點的 IP 為 192.168.1.1,子網掩碼為 /24,目標 IP 為 172.16.1.1/16,則按位與運算將得知它們位于不同的網段上。

這意味著目標 IP 與數據包的源不在同一個網絡上,數據包將通過默認網關轉發。

數學時間。

我們必須從二進制的 32 位地址開始進行 AND 操作。

先找出源 IP 網絡和目標 IP 網段。

Type Binary Converted
Src. IP Address 11000000.10101000.00000001.00000001 192.168.1.1
Src. Subnet Mask 11111111.11111111.11111111.00000000 255.255.255.0(/24)
Src. Network 11000000.10101000.00000001.00000000 192.168.1.0
Dst. IP Address 10101100.00010000.00000001.00000001 172.16.1.1
Dst. Subnet Mask 11111111.11111111.00000000.00000000 255.255.0.0(/16)
Dst. Network 10101100.00010000.00000000.00000000 172.16.0.0

按位運算之后,需要將目標 IP 與數據包源節點的子網進行比較。

Type Binary Converted
Dst. IP Address 10101100.00010000.00000001.00000001 172.16.1.1
Src. Subnet Mask 11111111.11111111.11111111.00000000 255.255.255.0(/24)
Network Result 10101100.00010000.00000001.00000000 172.16.1.0

運算的結果是 172.16.1.0,不等于 192.168.1.0(源節點的網絡)。說明源 IP 地址和目標 IP 地址不在同一個網絡上。

如果目標 IP 是 192.168.1.2,即與發送 IP 在同一子網中,則 AND 操作將得到節點的本地網絡。

Type Binary Converted
Dst. IP Address 11000000.10101000.00000001.00000010 192.168.1.2
Src. Subnet Mask 11111111.11111111.11111111.00000000 255.255.255.0(/24)
Network 11000000.10101000.00000001.00000000 192.168.1.0

進行逐位比較后,ARP 通過查找表查找默認網關的 MAC 地址。

如果有條目,將立即轉發數據包。

否則,先進行廣播以找到網關的 MAC 地址。

現在,數據包路由到另一個節點的默認接口,我們稱為 Node-B。

d4ceb5cc-5216-11ed-a3b6-dac502259ad0.svg

以相反的順序。現在,數據包位于 Node-B 的根命名空間,并到達網橋,這里會進行 ARP 解析。

d4fc7e62-5216-11ed-a3b6-dac502259ad0.svg

路由系統將返回與 Pod-B 相連的接口的 MAC 地址。

d5730f46-5216-11ed-a3b6-dac502259ad0.svg ? 4. 網橋通過 Pod-B 的 veth 設備轉發幀,并到達 Pod-B 的命名空間。 d5cc88d2-5216-11ed-a3b6-dac502259ad0.svg

至此,你應該已經熟悉了 Pod 之間的流量是如何流轉的。下面,讓我們花點時間來看看 CNI 如何管理上訴內容。

容器網絡接口 - CNI

容器網絡接口(CNI)主要關注的是當前節點中的網絡。

d5ecf2fc-5216-11ed-a3b6-dac502259ad0.svg

可以將 CNI 看作為解決 Kubernetes 網絡需求,而遵循的一組規則。

有這些 CNI 實現可供使用:

Calico

Cillium

Flannel

Weave Net

其他網絡插件

他們都遵循相同的 CNI 標準。

如果沒有 CNI,你需要人工完成如下操作:

創建接口。

創建 veth 對。

設置網絡命名空間。

設置靜態路由。

配置以太網橋。

分配 IP 地址。

創建 NAT 規則。

還有其他大量事情。

這還不包括,在刪除或重啟 Pod 時,需要進行類似的全部操作。

CNI 必須支持四種不同的操作:

ADD - 向網絡添加一個容器。

DEL - 從網絡中刪除一個容器。

CHECK - 如果容器的網絡出現問題,則返回錯誤。

VERSION - 顯示插件的版本。

我們一起看下,CNI 是如何工作的。

當 Pod 被分配到特定節點時,Kubelet 自身不會初始化網絡。

相反,Kubelet 將這個任務交給 CNI。

但是,Kubelet 以 JSON 格式指定配置并發送至 CNI 插件。

你可以進入節點上的 /etc/cni/net.d 文件夾,使用以下命令查看當前的 CNI 配置文件:

$cat10-calico.conflist

{
"name":"k8s-Pod-network",
"cniVersion":"0.3.1",
"plugins":[
{
"type":"calico",
"datastore_type":"kubernetes",
"mtu":0,
"nodename_file_optional":false,
"log_level":"Info",
"log_file_path":"/var/log/calico/cni/cni.log",
"ipam":{"type":"calico-ipam","assign_ipv4":"true","assign_ipv6":"false"},
"container_settings":{
"allow_ip_forwarding":false
},
"policy":{
"type":"k8s"
},
"kubernetes":{
"k8s_api_root":"https://10.96.0.1:443",
"kubeconfig":"/etc/cni/net.d/calico-kubeconfig"
}
},
{
"type":"bandwidth",
"capabilities":{"bandwidth":true}
},
{"type":"portmap","snat":true,"capabilities":{"portMappings":true}}
]
}

每個 CNI 插件都會使用不同類型的網絡配置。

例如,Calico 使用基于 BGP 的三層網絡連接 Pod

Cilium 從三層到七層使用的是基于 eBPF 的 overlay 網絡

與 Calico 一樣,Cilium 也支持通過配置網絡策略來限制流量。

那么你應該使用哪一個呢?主要有兩類 CNI。

在第一類中,使用基本網絡設置(也稱為平面網絡),從集群的 IP 池為 Pod 分配 IP 地址的 CNI。

這種方式可能很快耗盡 IP 地址,而成為負擔。

相反,另一類是使用 overlay 網絡。

簡單來說,overlay 網絡是主(底層)網絡之上的重建網絡。

overlay 網絡通過封裝來自底層網絡的數據包工作,這些數據包被發送到另一個節點上的 Pod。

overlay 網絡的一種流行技術是 VXLAN,它可以在 L3 網絡上建立 L2 域的隧道。

那么哪個更好呢?

沒有單一的答案,這取決于你的需求。

你是否正在構建具有數萬個節點的大型集群?

也許 overlay 網絡更好。

你是否在意更簡單的配置和審查網絡流量,而不會愿意在復雜網絡中丟失這種能力?

扁平網絡更適合你。

現在我們討論完了 CNI,接著讓我們來看看 Pod 到服務的通信是如何連接的。

檢查 Pod 到 Service 的流量

由于 Pod 在 Kubernetes 中是動態的,分配給 Pod 的 IP 地址不是靜態的。

Pod 的 IP 是短暫的,每次創建或刪除 Pod 時都會發生變化。

Kubernetes 中的 Service 解決了這個問題,為連接一組 Pod 提供了可靠的機制。

d627c7c4-5216-11ed-a3b6-dac502259ad0.svg

默認情況下,在 Kubernetes 中創建 Service 時,被分配一個虛擬 IP。

在 Service 中,可以使用選擇器將 Service 與目標 Pod 相關聯。

當刪除或添加一個 Pod 時會發生什么呢?

Service 的虛擬 IP 保持靜態不變。

但流量可以再無需干預的情況下,到達新創建的 Pod。

換句話說,Kubernetes 中的 Service 類似于負載均衡器。

但它們是如何工作的?

使用 Netfilter 和 Iptables 攔截和重寫流量

Kubernetes 中的 Service 是基于 Linux 內核中的兩個組件構建的:

網絡過濾器

iptables

Netfilter是一個可以配置數據包過濾、創建NAT、端口轉發規則以及管理網絡中流量的框架

此外,它可以屏蔽和禁止未經同意的訪問。

另一方面,iptables 是一個用戶態程序,可以用來配置 Linux 內核防火墻的 IP 數據包過濾規則。

iptables 是作為不同的 Netfilter 模塊實現的。

可以使用 iptables CLI 即時修改過濾規則,并將它們插入 netfilters 掛載點。

過濾器配置在不同的表中,其中包含用于處理網絡流量數據包的鏈。

不同的協議使用不同的內核模塊和程序。

當提到 iptables 時,通常指的是 IPv4。對于 IPv6 ,終端工具是 ip6tables。

iptables 有五種鏈,每一種鏈都直接映射到 Netfilter 的鉤子上。

從 iptables 的角度來看,它們是:

PRE_ROUTING

INPUT

FORWARD

OUTPUT

POST_ROUTING

它們對應地映射到 Netfilter 鉤子:

NF_IP_PRE_ROUTING

NF_IP_LOCAL_IN

NF_IP_FORWARD

NF_IP_LOCAL_OUT

NF_IP_POST_ROUTING

當一個數據包到達時,根據它所處的階段,將 “觸發” 一個 Netfilter 鉤子。這個鉤子會執行特定的 iptables 過濾規則。

d6430296-5216-11ed-a3b6-dac502259ad0.svg

哎呀!看起來很復雜!

不過沒什么好擔心的。

這就是我們使用 Kubernetes 的原因,以上所有內容都是通過使用 Service 抽象出來的,并且一個簡單的 YAML 定義可以自動設置這些規則。

如果你有興趣查看 iptables 規則,可以連接到節點并運行:

$iptables-save

你還可以使用這個工具來可視化節點上的 iptables 鏈。

這是來自 GKE 節點上的可視化 iptables 鏈的示例圖:

d677c814-5216-11ed-a3b6-dac502259ad0.svg

注意,這里可能配置了幾百條規則,想想一下自己動手怎么配置!

至此,我們已經了解了,相同節點上的 Pod 和不同節點上 Pod 之間是如何通信的。

在 Pod 與 Service 的通信中,鏈路的前半部分是一樣的。

d6a7557a-5216-11ed-a3b6-dac502259ad0.svg

當請求從 Pod-A 走向 Pod-B 時,由于 Pod-B 在 Service 的 “后面”,在傳輸的過程中,會有一些不一樣。

原始的請求,在 Pod-A 命名空間的 eth0 接口發出。

接著,請求通過 veth到達根名稱空間的網橋。

一旦到達網橋,數據包就會立即通過默認網關轉發。

與 Pod-to-Pod 部分一樣,主機進行按位比較。由于服務的虛擬 IP 不是節點 CIDR 的一部分,因此數據包將立即通過默認網關轉發。

如果默認網關的 MAC 地址尚未出現在查找表中,則會進行 ARP 解析找出默認網關的 MAC 地址。

現在神奇的事情發生了。

在數據包通過節點的路由之前,Netfilter 的 NF_IP_PRE_ROUTING 掛鉤被觸發,并執行 iptables 規則。這個規則會修改 Pod-A 數據包的目標 IP 地址 DNAT。

d7077392-5216-11ed-a3b6-dac502259ad0.svg

前面服務的虛擬 IP 地址被重寫為 Pod-B 的 IP 地址。

接下來,數據包路由過程與 Pod 到 Pod 的通信一樣。

d73a34a8-5216-11ed-a3b6-dac502259ad0.svg

數據包重寫后,通信是 Pod 到 Pod。

然而,在所有這些通信中,使用了一個第三方的功能。

此功能稱為 conntrack 或鏈路跟蹤。

當 Pod-B 發回響應時,conntrack 會將數據包與鏈路相關聯,并跟蹤其來源。

NAT 嚴重依賴于 conntrack。

如果沒有鏈路跟蹤,將不知道將包含響應的數據包發回何處。

使用 conntrack 時,數據包的返回路徑很容易設置為相同的源或目標 NAT 更改。

通信的另一部分與現在的鏈路相反。

Pod-B 接收并處理了請求,現在將數據發送回 Pod-A。

現在會發生什么呢?

檢查來自服務的響應

Pod-B 發送響應,將其 IP 地址設置為源地址,并將 Pod-A 的 IP 地址設置為目標地址。

d75cc496-5216-11ed-a3b6-dac502259ad0.svg

當數據包到達 Pod-A 所在節點的接口時,會發生另一個 NAT。

d773b304-5216-11ed-a3b6-dac502259ad0.svg

這時,conntrack 開始工作,修改源 IP 地址,iptables 規則執行 SNAT,并將 Pod-B 的源 IP 地址修改為原始服務的虛擬 IP。

d7bc326e-5216-11ed-a3b6-dac502259ad0.svg

對于 Pod-A 來說,響應是來自于 Service 而不是 Pod-B。

其余的都是一樣的。一旦 SNAT 完成,數據包就會到達根命名空間中的網橋,并通過 veth 對轉發到 Pod-A。

總 結

讓我們一起回顧下本文相關要點

容器如何在本地或 Pod 內通信。

在相同節點和不同節點上的 Pod 如何通信。

Pod-to-Service - Pod 如何將流量發送到 Kubernetes 中服務后面的 Pod 時。

什么是命名空間、veth、iptables、chains、conntrack、Netfilter、CNI、overlay 網絡,以及 Kubernetes 網絡工具箱中所需的一切。

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11310

    瀏覽量

    209586
  • 容器
    +關注

    關注

    0

    文章

    495

    瀏覽量

    22064
  • 網絡流量
    +關注

    關注

    0

    文章

    58

    瀏覽量

    10370
  • kubernetes
    +關注

    關注

    0

    文章

    224

    瀏覽量

    8722

原文標題:跟蹤 Kubernetes 的網絡流量路徑

文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    運營商將能夠應對網絡流量的增長

    當半年前人們預測網絡流量增長的幅度時,認為網絡流量帶來的沖擊還是人為可控的。如今隨著各種互聯網應用的不斷普及、網絡視頻需求的進一步上升、以及移動智能終端的流行,固網和移動網絡數據
    發表于 12-01 10:36

    分布式網絡流量監測

    分析2種現行網絡流量監測技術:利用標準的網絡管理方法記錄IP流量和利用NETFLOW的方法進行流量統計。針對這2種方法的局限性,提出分布式網絡流量
    發表于 04-13 09:12 ?8次下載

    網絡流量測量的研究與實現

    網絡流量測量是研究網絡行為和網絡流量特性的有效方法。文章探討了網絡流量測量的關鍵技術,提出了網絡流量測量基于FPGA 的硬件實現方法,給出了
    發表于 08-03 11:57 ?14次下載

    淺談基于PCA的網絡流量分析

    網絡流量的特性分析一直是通信網絡性能分析的一個極其重要的問題。本文主要采用主成分分析(PCA)的方法對采樣到的網絡流量數據進行分析,發現這些流量數據呈現低維特性
    發表于 08-15 08:29 ?28次下載

    網絡流量監測和管理平臺的設計與實現

    網絡流量的監測是提高網絡管理的效率的重要手段之一 ,通過流量的測量,過濾規則設定和報警系統的設置,從而能夠清楚的了解到自治域之間,網絡之間流量
    發表于 09-23 11:51 ?9次下載

    基于分組采樣組播網絡流量預測研究

    組播網中網絡流量分布的不均衡是網絡擁塞主要原因,而網絡流量預測是解決擁塞問題的關鍵。本文介紹了網絡流量預測的兩種重要方法:分組采樣和頻率采樣。通過建立相應的采
    發表于 09-25 15:52 ?11次下載

    基于FPGA的網絡流量計設計與實現

    網絡測量是研究網絡行為和網絡流量特性的有效方法。網絡計費變得越來越重要,基于流量網絡計費將成為
    發表于 12-18 12:09 ?28次下載

    基于多組博弈的新型網絡流量控制模型

    該文研究了具有強分布式特征和分層結構的通信網絡流量控制問題,借鑒多組博弈模型來研究新型的網絡流量控制模型,構造了基于網絡流量速率和時延為參數的流量效用函數,使
    發表于 02-08 15:42 ?8次下載

    基于混沌理論和神經網絡網絡流量預測

    針對目前網絡流量預測不能很好地滿足智能網絡管理需求的現狀,分析網絡流量數據內在混沌特性,主要包括時間延遲、嵌入維數、關聯維數及Lyapunov指數的計算,并將此分析耦合人工神
    發表于 02-26 14:33 ?11次下載

    基于FPGA的網絡流量計設計與實現

    網絡測量是研究網絡行為和網絡流量特性的有效方法。網絡計費變得越來越重要,基于流量網絡計費將成為
    發表于 07-21 17:39 ?14次下載

    基于覆蓋網絡的多路徑流量均衡研究

    本文在建立一種覆蓋網絡的多路徑流量均衡的模型的基礎上,引入一個網絡流量預測算法,通過網絡節點間的協作對網絡流量進行均衡。
    發表于 08-16 10:48 ?1487次閱讀
    基于覆蓋<b class='flag-5'>網絡</b>的多<b class='flag-5'>路徑流量</b>均衡研究

    基于KPCA優化ESN的網絡流量預測方法_田中大

    基于KPCA優化ESN的網絡流量預測方法_田中大
    發表于 01-08 13:26 ?0次下載

    園區網絡流量管理與優化_李振剛

    園區網絡流量管理與優化_李振剛
    發表于 03-20 09:20 ?0次下載

    基于 ossim 的網絡流量監控系統的分析

    基于 ossim 的網絡流量監控系統的分析
    發表于 09-05 15:20 ?5次下載
    基于 ossim 的<b class='flag-5'>網絡流量</b>監控系統的分析

    IP網絡流量矩陣估計方法

    針對IP網絡流量矩陣(TM)估計的高度病態性,導致很難精確估計網絡流量矩陣,因此提出了一種基于蟻群優化(ACO)算法的IP網絡流量矩陣估計方法。通過適當的建模,將流量矩陣估計問題轉化為
    發表于 02-09 16:24 ?0次下載
    IP<b class='flag-5'>網絡流量</b>矩陣估計方法
    主站蜘蛛池模板: 黑人操白逼| 三级在线观看网站| 免费视频不卡| 午夜不卡av免费| 99久久就热视频精品草| 国产亚洲视频中文字幕| 日本边添边摸边做边爱边| 一个人免费观看完整视频日本| 成人在线视频免费观看| 蜜芽手机在线观看| 在线看片av以及毛片| 国产一卡2卡3卡4卡孕妇网站| 亚洲午夜电影| 国产亚洲精品品视频在线| 伊人久久久久久久久久| 漂亮的av女演员| AV色蜜桃一区二区三区| 蜜桃臀无码内射一区二区三区| JK白丝校花爽到娇喘视频| 棉签和冰块怎么弄出牛奶视频 | 乌克兰少妇大胆大BBW| 风月宝鉴之淫乱英雄传 电影| 欧美精品成人久久网站| 99久久久精品| 鞋奴的视频VK| 国内精品免费视频精选在线观看| 午夜剧场1000| 麻豆成人AV久久无码精品| 最近日本字幕MV免费观看在线| 狂躁美女BBBBBB视频| 伊人久久青草青青综合| 热中文热国产热综合| 精品午夜视频| 97精品一区二区视频在线观看| 久久热在线视频精品1| 最新男同鸭子ktv| 午夜爽喷水无码成人18禁三级| 女人吃男人的鸡鸡| 吃寂寞寡妇的奶| 中文字幕在线观看国产| 羞羞答答dc视频|