大家好,我是二哥。在文章《特洛伊木馬-圖解VXLAN容器網(wǎng)絡(luò)通信方案》里,二哥畫(huà)了下面這張鳥(niǎo)瞰大圖。它把基于Flannel VXLAN模式實(shí)現(xiàn)的K8s Overlay網(wǎng)絡(luò)模型所需要的各類(lèi)網(wǎng)路設(shè)備放在了一起,主要突出的是這些設(shè)備之間的數(shù)據(jù)流向。但那篇文章有些許缺點(diǎn)(凡爾賽一下):
-
配圖沒(méi)有很好地顯示這些網(wǎng)絡(luò)設(shè)備和協(xié)議棧之間的相對(duì)位置關(guān)系。
-
對(duì)于容器來(lái)說(shuō),network namespace是一個(gè)非常重要的隔離手段,這張圖沒(méi)有很好地展示出這個(gè)重要性。
-
文章沒(méi)有交代清楚一個(gè)重要的網(wǎng)絡(luò)包封裝節(jié)點(diǎn):根據(jù)本機(jī)路由,cni0把從Pod a發(fā)過(guò)來(lái)的請(qǐng)求轉(zhuǎn)至flannel.1后,到底發(fā)生了什么?
-
配圖是為Flannel VXLAN模式準(zhǔn)備的。我們知道為了效率,VXLAN模式下,所有的封裝和解封裝都是由VXLAN內(nèi)核模塊完成的。因?yàn)樵趦?nèi)核,看不見(jiàn)摸不著就比較抽象。本來(lái)K8s Overlay網(wǎng)絡(luò)模型就已經(jīng)挺復(fù)雜了,加上這個(gè)更加不利于我們學(xué)習(xí)理解。
編輯搜圖
圖 1:基于flannel實(shí)現(xiàn)的Overlay網(wǎng)絡(luò)模型設(shè)備關(guān)系圖
新視角
二哥真是一個(gè)貼心的人,我特地畫(huà)了下面這張圖。換了一個(gè)視角,它突出了幾個(gè)重要的方面:
-
每個(gè)Pod都有自己的network namespace,因而有屬于它自己的routing table + iptables,這在圖中 1.1 ~ 1.3 以及 2.9 ~ 2.11 這兩條data path上能比較清晰地看得出來(lái)。你會(huì)看到在每個(gè)Node上都出現(xiàn)了若干個(gè)routing table + iptables,這很好解釋?zhuān)驗(yàn)檫@個(gè)Node上有多個(gè)network namespace。
-
為了強(qiáng)調(diào)容器本質(zhì)上也是一個(gè)進(jìn)程,我將每個(gè)Pod里面的container特意畫(huà)到最上面的用戶(hù)態(tài)的位置。
-
可以在Link Layer這一層看到有若干種網(wǎng)絡(luò)設(shè)備:veth、bridge、eth0、tun。它們都是組成Overlay網(wǎng)絡(luò)模型不可或缺的關(guān)鍵設(shè)備。但無(wú)論它們所司何職,都必須要統(tǒng)一位于Link Layer。嗯,找準(zhǔn)自己的位置很重要。
-
這張圖是為Flannel UDP模式準(zhǔn)備的。通過(guò)將圖1中的VXLAN內(nèi)核模塊拆解成tun設(shè)備和flannel daemon,并將它們挪動(dòng)到用戶(hù)態(tài),我們可以非常清晰地看到進(jìn)行數(shù)據(jù)封裝、解封的確切地點(diǎn)以及數(shù)據(jù)的流向。雖然因?yàn)樾蕟?wèn)題,F(xiàn)lannel UDP模式已經(jīng)不具備工程價(jià)值,但對(duì)我們學(xué)習(xí)來(lái)說(shuō),卻是極好的。
編輯搜圖
圖 2:設(shè)備和協(xié)議棧關(guān)系圖
圖2中Pod a的IP是10.244.0.2,Pod b的IP是10.244.1.3。左圖中bridge cni0配有IP地址10.244.0.1,右圖中bridge的IP是10.244.1.1。一切都和圖1保持一樣,只是換了個(gè)視角。我們的故事從左圖 Pod a中的容器發(fā)起請(qǐng)求開(kāi)始,請(qǐng)求的對(duì)象是右圖 Pod b。也即src IP是10.244.0.2,dest IP是10.244.1.3。1.x 代表的是在Node 1上面,從容器內(nèi)產(chǎn)生網(wǎng)絡(luò)包到它離開(kāi)網(wǎng)卡的完整流程。而相應(yīng)地,2.x表示在Node X上,從網(wǎng)卡收到請(qǐng)求到這個(gè)請(qǐng)求最終送至Pod b中容器的完整流程。這張圖沒(méi)有畫(huà)出響應(yīng)流程,故圖中箭頭都是單向的。其實(shí)把所有的箭頭反過(guò)來(lái)就是響應(yīng)流程了。此去路途山路十八彎,客官坐好,我要發(fā)車(chē)了。
發(fā)生在Pod里的故事
1.2 這個(gè)位置routing table + iptables用來(lái)控制Pod內(nèi)容器的網(wǎng)絡(luò)路由。對(duì)于Pod a的容器而言,10.244.0.1扮演了網(wǎng)關(guān)的角色,而10.244.0.1正是圖中 cni0 這個(gè)bridge。下面是 1.2 處的路由表。
# on container of Pod a $ route -n Destination Gateway Genmask Flags Metric Ref Use Iface default 10.244.0.1 0.0.0.0 UG 0 0 0 eth0 10.244.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth01.2.3.4.5.
有一個(gè)概念再次強(qiáng)調(diào)一遍:雖然 1.2 和 1.6 處有兩個(gè)分屬不同network namespace的路由表,但TCP/IP協(xié)議棧卻只有一份。也即對(duì)于協(xié)議棧而言,它只是在處理相同數(shù)據(jù)結(jié)構(gòu)的不同數(shù)據(jù)實(shí)例罷了。
完美轉(zhuǎn)場(chǎng)
當(dāng)網(wǎng)絡(luò)包沿著 1.4 流進(jìn)bridge cni0后,藉由bridge的一個(gè)特殊功能,實(shí)現(xiàn)了網(wǎng)絡(luò)包從一個(gè)network namespace完美跳轉(zhuǎn)到另一個(gè)network namespace的神奇效果。
bridge即為網(wǎng)橋,它的行為類(lèi)似二層交換機(jī)。如果網(wǎng)絡(luò)包的目的 MAC 地址為網(wǎng)橋本身,并且網(wǎng)橋設(shè)置了 IP 地址的話(huà),那么bridge就認(rèn)為該網(wǎng)絡(luò)包應(yīng)該是發(fā)往創(chuàng)建該網(wǎng)橋的那臺(tái)主機(jī)。因而這個(gè)網(wǎng)絡(luò)包將不會(huì)被bridge轉(zhuǎn)發(fā)到任何設(shè)備,而是直接交給上層(三層)協(xié)議棧去處理。處理的過(guò)程會(huì)涉及到基于本機(jī)路由表的路由查詢(xún)。1.6 處的路由表開(kāi)始發(fā)揮它的作用。因?yàn)槟康腎P是10.244.1.3,所以網(wǎng)絡(luò)包需要被送往tun設(shè)備flannel.1。
# on host machine Node 1 $ route -n Destination Gateway Genmask Flags Metric Ref Use Iface default 17.168.0.1 0.0.0.0 UG 0 0 0 eth0 10.244.0.0 0.0.0.0 255.255.255.0 U 0 0 0 cni0 10.244.1.0 10.244.1.0 255.255.255.0 UG 0 0 0 flannel.1 17.168.0.3 17.168.0.3 255.255.255.255 UG 0 0 0 eth01.2.3.4.5.6.7.
其實(shí)在 1.4 ~ 1.5 這里涉及到更多的有趣問(wèn)題。比如網(wǎng)絡(luò)包在veth pair之間是如何流轉(zhuǎn)的?網(wǎng)絡(luò)包在bridge內(nèi)部是如何處理的?但這并非本文的重點(diǎn),以后二哥再聊。不過(guò)我先把圖3 放上來(lái)。老鐵們?cè)谖业奈恼隆犊磮D寫(xiě)話(huà):聊聊veth數(shù)據(jù)流》見(jiàn)過(guò)這張圖,我在那篇文章的配圖基礎(chǔ)上加上了bridge的處理細(xì)節(jié),后面有機(jī)會(huì)二哥會(huì)細(xì)聊這個(gè)地方。
編輯搜圖
圖 3:veth + bridge網(wǎng)絡(luò)包接收流程中,Bridge處理細(xì)節(jié)
反著來(lái)一遍
當(dāng)Node X收到從Node 1發(fā)來(lái)的數(shù)據(jù)后,沿著 2.1 一路兜兜轉(zhuǎn)轉(zhuǎn),繞繞彎彎來(lái)到 2.11 ,Pod b也就收到了Pod a發(fā)出的請(qǐng)求。你也看到了,除了箭頭方向不同外,圖2的左、右兩部分幾乎完全一樣。是的,實(shí)際上畫(huà)圖的時(shí)候,我就是粘貼、拷貝加批量改箭頭方向這樣搞的。
右圖中 2.6 和 2.10 位置處的路由表和iptables的作用和左圖相同,就不再贅述了。雖然路途比較艱辛,但總歸是完整到達(dá)了,本篇也就到此結(jié)束了