成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

特洛伊木馬-圖解VXLAN容器網絡通信方案

云計算 云原生
這篇文章我主要通過下面這張全景圖來講述K8s是如何利用VXLAN來實現K8s的容器通信方案的。

一篇文章圍繞一張圖,講述一個主題。不過這個主題偏大,我估計需要好幾篇文章才能說得清楚。

云原生的代表技術包括容器、服務網格、微服務、不可變基礎設施和聲明式API。其中K8s是不可變基礎設施的壓艙石。典型的K8s集群由數十個Node, 成百個Pod,上千個Container組成。相互隔離的容器間需要協作才能完成更大規模的應用。而協作就需要網絡通信。

這篇文章我主要通過下面這張全景圖來講述K8s是如何利用VXLAN來實現K8s的容器通信方案的。網絡通信不是量子糾纏,網絡流量是實打實地通過了各個虛擬的、實體的網絡設備,途徑每個設備節點時自然也會受到設備上的路由、iptables等策略控制。

圖:VXLAN容器網絡方案全景圖

K8s的容器通信方案有很多種。譬如flannel實現的host-gw方案、calico基于三層轉發實現的方案以及本文著重講述的flannel.1 VXLAN方案。為什么我要挑flannel.1 VXLAN方案來細聊呢,因為它夠復雜,涉及到了比較多的虛擬網絡設備和組網技術。

這張圖里面涉及到如下幾種網絡設備,有機會我們單獨拿一篇出來過一下這些設備。

  • eth: 物理網卡在內核中的表示。它一端連著網絡棧,另一端通過驅動連接著物理網卡。
  • veth: virtual eth。它是成對出現的,類似交叉網線連接的一對物理網卡。從網卡一端流出的數據會原樣流入另外一端。每個veth都有自己的MAC地址,也可以給它設置IP地址。
  • bridge: bridge的行為類似二層交換機,又翻譯成網橋。可以將veth,tap等虛擬網絡設備連(插)到它上面。如果數據包的目的 MAC 地址為網橋本身,并且網橋設置了 IP 地址的話,那該數據包就會被認為是bridge收到了發往創建網橋那臺主機的數據包,這個數據包將不會轉發到任何設備,而是直接交給上層(三層)協議棧去處理。
  • VTEP:VXLAN 網絡的每個邊緣入口上,布置有一個 VTEP(VXLAN Tunnel Endpoints)設備,它既可以是物理設備,也可以是虛擬化設備,主要負責 VXLAN 協議報文的封包和解包。圖中flannel.1就是一個VTEP設備,它既有IP地址,又有MAC地址。

雖然容器間的網絡方案多種多樣,但所有的容器網絡通信問題,其實都可以歸結為以下幾種場景。本篇我們專注容器間通信的場景,故略去了其它通信主體與容器通信的情形,比如本地Node里面的進程也會和容器通信。留個彩蛋,以后再聊。

  • 同一個Pod內的容器間通信。
  • 同一個Node內的容器間通信。
  • 跨Node的容器間通信。

這里需要強調的一個點是,雖然Pod是K8s編排調度的基本單位,但是通信的需求卻發端于Pod里面的容器。

環境說明

這張圖里面,Node 1 和Node X位于同一個局域網17.168.0.0/24。Node 1的IP地址是17.168.0.2,Node X的IP是17.168.0.3。

K8s集群所使用的子網為10.244.0.0/16。對于網絡17.168.0.0/24和它里面的交換機和路由器來說,K8s集群所使用的子網是無效的網絡,交換機和路由器更是無從轉發、路由任何源IP或目的IP為K8s子網的數據包。

非常明顯的矛盾出現了:K8s集群要通過子網為10.244.0.0/16通信,而宿主機環境卻根本不認識這個子網。我們接下來將看到"特洛伊木馬"的故事在這里再次上演。

我們的目標是在這種矛盾的網絡環境下,解釋清楚pod a里面的container-1訪問pod b里面的container-1時發生了哪些事情。圖中藍色的標線展示了數據流的方向。

圖中的綠色標線和綠色的框圖表示了與VXLAN相關的數據流和網絡封包示意圖。

出于簡單,Node 1里面只畫出了一個Pod, pod a,所有的Pod都連在了bridge cni0上,子網為10.244.0.1/24。Node X里面只畫了兩個Pod, pod b和pod c ,所有的Pod也一樣都連在了bridge cni0上,子網為10.244.1.1/24。

每個Node上面的bridge都分配有IP地址。Pod a的IP地址是10.244.0.2,Pod b的IP地址是10.244.1.3。

同一個Pod內的容器間通信

這是最簡單的情形,內核自帶技能,不需額外的組網技術加持。

需要強調的一個知識點是Pod內部所有的容器是共享同一個網絡棧、routes以及iptables的,因為它們屬于同一個network namespace。

在一個k8s cluster內部,每個Pod擁有獨一無二的IP地址,Pod內部所有的container共享分配Pod的地址。Pod內部的容器共享pod的IP地址,但各個容器的端口不能沖突。

由于Pod調度的原子性,一個Pod內部的所有container只會被調度到一臺主機上運行。類似本地機器上兩個應用程序通過localhost進行進程間通信一樣,同一個Pod內部的容器間可以直接通過localhost來通信。此時的traffic直接通過loopback 網絡設備在兩個容器間流動。圖中的bridge無法感知這樣的traffic,主機上的網絡棧和其它網絡設備更不會感知到。

同一個Node內的容器間通信

圖中Node X上畫出了多個Pod。當Pod b里面的container-1想要訪問Pod c里面的container-1時屬于這個場景。

Pod b里面的路由表決定了訪問Pod c的traffic需要從自己的interface eth0出去。

  • src IP:10.244.1.3,dest IP:10.244.1.8。
  • src MAC為Pod b veth MAC,dest MAC為Pod c veth MAC。

從圖中可以看到Pod b和Pod c都是插在了bridge上面。作為一個虛擬的二層交換機,它按照二層交換機的行為交換、轉發數據包。

在這種場景下,這兩個container之間的通信行為不會超出bridge的范圍,包括Pod b的container-1通過ARP得知目的container的MAC地址也是在bridge內處理。也不會涉及NAT等地址轉換操作。

跨Node的容器間通信

這是最常用的通信場景。容器訪問api server即是典型的例子。

下面開始最復雜的步驟,這些步驟發生在Node 1。Node X收到以太幀后的操作是一個逆過程,這里不做贅述。

我們按照traffic的流向,以它途徑的各個網絡設備(虛擬的、實體的)為分割節點,分段講述每段發生了什么。

從container到cni0

從Pod a的路由表可知,以太幀需要從它的NIC eth0離開。因為eth0是veth的其中一端,另外一端插在bridge cni0上面,于是以太幀進入cni0。此以太幀的目的MAC地址為bridge。

  • src IP:10.244.0.2,dest IP:10.244.1.3。
  • src MAC為Pod a veth MAC,dest MAC為cni0 MAC。

從cni0到flannel.1

前面提到該網橋配置有IP地址,現在它收到一個目的MAC地址為自己的數據包,于是觸發了 Linux Bridge 的特殊轉發規則:網橋不會將這個數據包轉發給任何設備,而是直接轉交給主機的三層協議棧處理。

主機協議棧根據host的路由表,從而得知需要把IP包交給本機的flannel.1。

從這步以后就是三層路由了,已經不在網橋的工作范圍之內,而是由 Linux 主機依靠 Netfilter 進行 IP 轉發(IP Forward)去實現的。注意這里是IP包轉發,接收者收到的是3層的package,因而它不包含二層的數據。

flannel.1組裝內部數據幀

至此,越過千山萬水,本機的flannel.1終于收到了IP包。

從這里開始,flannel.1需要想辦法營造幻象:跨主機營造一個虛擬的網絡10.244.0.0/16,好讓Pod a看起來Pod b和它正處于一個完全合法的、信息交換自由無障礙的環境。天真的Pod們完全不知這個網絡是一個虛擬的、私有的、宿主機網絡里面的交換機和路由器根本不認識它這樣一個事實。

前面提到flannel.1收到的是 IP 包,既然是IP包,那它就沒有MAC地址,但flannel.1同時又要想辦法把“原始 IP 包”加上一個目的 MAC 地址(當然也需要包含源flannel.1的MAC地址),封裝成一個完整的二層數據幀,然后發送給位于Node X上的flannel.1。

而大家都知道要組裝一個完整的二層數據幀,首先需要解決的問題是目標 flannel.1的MAC地址是什么呢?下面的提示給出了答案。

Node X上的flannel.1的 MAC 地址是什么?

我們已經知道了Node X上的flannel.1的 IP 地址,它是數據包的目的地。要根據三層 IP 地址查詢對應的二層 MAC 地址,這正是 ARP(Address Resolution Protocol )表的功能。這里要用到的 ARP 記錄,也是 flanneld 進程在 Node 1 節點啟動時,自動添加在 Node 1 上的。我們可以通過 ip 命令看到它,如下所示:

# 在Node 1
$ ip neigh show dev flannel.1
10.244.1.0 lladdr 5e:f8:4f:00:e3:37 PERMANENT

通過ARP,我們知道了目的 flannel.1的MAC是 5e:f8:4f:00:e3:37。到此時,已經完整地產生了內部數據載荷(Inner payload), 內部IP頭(Inner IP Header) 10.244.1.3和內部Ethernet頭(Inner Ethernet Header)5e:f8:4f:00:e3:37了。

但是,因為上面提到的這些 VTEP 設備的 MAC 地址,對于宿主機網絡來說并沒有什么實際意義,所以上面封裝出來的這個數據幀,并不能在我們的宿主機二層網絡里傳輸。為了方便敘述,我們把它稱為“內部數據幀”(Inner Ethernet Frame),或者叫"原始二層數據幀"(Original Layer 2 Frame)。

封裝好的內部數據幀如全景圖中藍色的方框所示。

接下來,Linux 內核還需要再把“原始二層數據幀”進一步封裝成為宿主機網絡里的一個普通的外部數據幀,好讓它載著“原始二層數據幀”,通過宿主機的 eth0 網卡進行傳輸。

flannel.1組裝VXLAN數據幀

如下圖所示,原始二層數據幀加上VXLAN頭,我們把它叫做“VXLAN數據幀”。在全景圖中,我在藍色的方框上面加了一個灰色的方框,用來表示VXLAN頭。需要特別注意下灰色方框中VNI=1這個部分。VNI(Virtual Network Identifier)長24-bit,在這里flannel.1默認把它設置為1,這樣Node X上面的flannel.1就知道這個數據幀是需要它處理的。

  • Flannel 中,VNI 的默認值是 1,這也是宿主機上的 VTEP 設備都叫作 flannel.1 的原因。

有了VXLAN數據幀,就可以開始演繹一個和“特洛伊木馬”相同的故事。VXLAN數據幀如同希臘戰士,但我們的目的不是攻打特洛伊城,而是把這個VXLAN數據幀完整地、神不知鬼不覺地送到城內的flannel.1手里。要達到這個目的,我們還需要一個木馬。

圖:VXLAN數據幀

從flannel.1發起UDP連接

好了,“希臘戰士”有了,我們就差一個木馬了。接下來要做的事情是,像把希臘戰士藏到木馬里一樣,Linux 內核要把這個VXLAN數據幀塞進一個 UDP 包里發出去。上面的全景圖中,我特意把VXLAN數據幀畫得窄了一些,好讓你感覺外圍稍胖的UDP包確實像是個木馬。

Node 1上的flannel.1 設備要扮演一個“網橋”的角色,在二層網絡進行 UDP 包的封包和轉發。在Node 1看來,它會以為自己的 flannel.1 設備只是在向另外一臺宿主機的 flannel.1 設備,發起了一次普通的 UDP 鏈接,卻全然不知它發送的是一個木馬(不要緊張,此木馬非木馬病毒)。

但且慢,先回答一個問題:剛才在組裝內部數據幀的時候,我們知道 flannel.1 設備已經知道了目的 flannel.1 設備的 MAC 地址,但這個 UDP 包該發給哪臺宿主機呢?也就是說,木馬有了,希臘戰士也藏到木馬肚子里了,但特洛伊城在哪里?

是時候輪到一個叫作轉發數據庫(FDB, Forwarding Database)上場幫忙了。這個 flannel.1“網橋”對應的 FDB 信息,也是 flanneld 進程負責維護的。它的內容可以通過 bridge fdb 命令查看到,如下所示:

# 在Node 1上,使用“目的VTEP設備”的MAC地址進行查詢
$ bridge fdb show flannel.1 | grep 5e:f8:4f:00:e3:37
5e:f8:4f:00:e3:37 dev flannel.1 dst 17.168.0.3 self permanent

在上面這條 FDB 記錄里,指定了這樣一條規則:發往我們前面提到的“目的 flannel.1”(MAC 地址是 5e:f8:4f:00:e3:37)的二層數據幀,應該通過本機的flannel.1 設備,發往 IP 地址為 17.168.0.3 的主機。顯然,這臺主機正是 Node X,UDP 包要發往的目的地就找到了。

得到了目的IP地址,自然也會得知Node X的MAC地址。接下來的流程,就是一個正常的,宿主機網絡上的封包工作,且最終從 Node 1 的 eth0 網卡發出去了。只不過這個過程發生在虛擬設備flannel.1上面罷了。

責任編輯:姜華 來源: 二哥聊云原生
相關推薦

2015-05-07 10:38:58

2010-07-06 10:45:25

2010-01-15 21:47:39

2010-01-14 20:49:08

2012-06-13 09:38:27

2013-10-10 09:24:34

2021-10-13 11:01:54

Android特洛伊木馬SOVA

2013-08-20 09:57:52

2019-09-09 07:03:37

2010-09-13 09:16:16

特洛伊木馬

2019-02-12 05:03:18

2019-09-11 13:23:33

2013-09-03 13:48:10

2009-01-22 09:51:17

2009-02-17 09:58:00

2021-08-27 12:33:00

LemonDuck木馬LemonCat

2014-08-21 11:09:31

2012-02-24 10:07:25

2009-07-27 09:51:48

2016-12-02 10:34:21

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 九九久久久 | 福利视频一区 | 精品一二区 | 精品在线一区 | 国产精品一区二区在线免费观看 | 欧美精品一区二区三区在线 | 日本粉嫩一区二区三区视频 | 久久福利电影 | 人人做人人澡人人爽欧美 | 午夜资源 | 国产 欧美 日韩 一区 | 黄色一级毛片免费看 | 亚洲国产精品美女 | 在线日韩在线 | 日产久久| 91在线精品视频 | 操操日 | 亚洲一区二区三区四区五区午夜 | 91在线精品秘密一区二区 | 一区二区在线看 | 国产三级一区二区三区 | 久久久精品 | 中文字幕中文字幕 | 亚洲精品久久国产高清情趣图文 | 成人免费一区二区三区视频网站 | 日韩福利电影 | 99免费视频 | 欧美日本一区 | av在线视 | av首页在线| 国产日韩欧美综合 | 精品一区二区三区在线播放 | 精品一区二区三区四区 | 欧美不卡 | 日韩视频免费看 | 男女爱爱网站 | 欧美精品久久久久久 | 一区二区视频免费观看 | 天天爽天天干 | 日韩成人免费中文字幕 | 国内成人免费视频 |