k8s容器互聯(lián)flannel?vxlan通信原理
k8s容器互聯(lián)-flannel vxlan 原理篇
vxlan 模式通信原理
flannel 在為不同主機(jī)的pod分配ip地址的時(shí)候,會(huì)在一個(gè)大的網(wǎng)段范圍內(nèi)分配ip地址,而同一臺(tái)主機(jī)上的pod,則是在大的網(wǎng)段下延伸出一個(gè)較小的子網(wǎng),同一臺(tái)主機(jī)上的ip地址則是在較小的子網(wǎng)范圍內(nèi)去進(jìn)行分配。
例如k8s啟動(dòng)flannel插件時(shí),會(huì)通過(guò)flannel的配置文件指定大的網(wǎng)段的范圍和flannel啟動(dòng)方式,我們選用的是vxlan模式
net-conf.json: | { "Network": "10.10.0.0/16", "Backend": { "Type": "vxlan" } }
這樣整個(gè)集群的ip地址就是在10.10.0.0/16 網(wǎng)段去進(jìn)行分配。 而各個(gè)主機(jī)上的ip地址范圍 則是在例如10.10.1.0/24 ,10.10.2.0/24這樣的網(wǎng)段去進(jìn)行分配。
跨主機(jī)通信的目的,就是讓主機(jī)A上的網(wǎng)段10.10.1.0/24 內(nèi)分配的ip能夠ping通主機(jī)B上的 10.10.2.0/24 網(wǎng)段分配的ip。
flannel的xvlan模式是如何辦到的呢?
為了更好的理解vxlan的模式,我搭建了一個(gè)真實(shí)的3節(jié)點(diǎn)集群環(huán)境,然后實(shí)際的去主機(jī)上分析vxlan工作模式
集群網(wǎng)絡(luò)模型
集群有3個(gè)節(jié)點(diǎn):
master 集群的控制節(jié)點(diǎn),ip地址是 192.168.2.17;
worker1 工作節(jié)點(diǎn) ip地址是 192.168.2.16;
worker2 工作節(jié)點(diǎn) ip 地址是 192.168.2.15 ;
由于工作節(jié)點(diǎn)才承擔(dān)具體的pod承載認(rèn)為,所以我們只看工作節(jié)點(diǎn)即可。
這里先放一張集群網(wǎng)絡(luò)模型的圖,接下來(lái)的分析都將會(huì)根據(jù)這個(gè)圖一步步分析網(wǎng)絡(luò)包時(shí)如何從worker2 的pod到達(dá)到worker1的pod的。
查看worker2網(wǎng)絡(luò)設(shè)備類(lèi)型
查看網(wǎng)絡(luò)接口有哪些
parallels@worker2:~/Desktop$ ifconfig cni0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet 10.10.2.1 netmask 255.255.255.0 broadcast 10.10.2.255 ... docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 ether 02:42:41:ce:a9:49 txqueuelen 0 (Ethernet) ... enp0s5: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.2.15 netmask 255.255.255.0 broadcast 192.168.2.255 ... flannel.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet 10.10.2.0 netmask 255.255.255.255 broadcast 0.0.0.0 inet6 fe80::647c:5aff:fe24:c42e prefixlen 64 scopeid 0x20<link> ether 66:7c:5a:24:c4:2e txqueuelen 0 (Ethernet) ... lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 ... veth9c0a9a53: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet6 fe80::fc7d:fdff:fe6f:a32e prefixlen 64 scopeid 0x20<link> ether fe:7d:fd:6f:a3:2e txqueuelen 0 (Ethernet) ... vethd6f08999: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet6 fe80::68b2:41ff:fee2:9074 prefixlen 64 scopeid 0x20<link> ether 6a:b2:41:e2:90:74 txqueuelen 0 (Ethernet) ...
k8s 在主上創(chuàng)建一個(gè)cni0和flannel.1的虛擬網(wǎng)絡(luò)設(shè)備,cni0是網(wǎng)橋類(lèi)型的設(shè)備,flannel.1是vxlan類(lèi)型的設(shè)備 (準(zhǔn)確的說(shuō)是vtep設(shè)備,在vxlan模式下,我們將這個(gè)封包解包的設(shè)備叫做vtep設(shè)備VXLAN Tunnel Endpoints)。
記下這里worker2節(jié)點(diǎn)上cni0的ip地址10.10.2.1 ,flannel.1的ip地址 10.10.2.0
parallels@worker2:~/Desktop$ ethtool -i flannel.1 driver: vxlan ... parallels@worker2:~/Desktop$ ethtool -i cni0 driver: bridge ...
先看下網(wǎng)橋的作用(vxlan設(shè)備作用稍后進(jìn)行分析) 網(wǎng)橋擁有交換機(jī)的作用。
我們知道,在同一臺(tái)主機(jī)上,不同pod的網(wǎng)絡(luò)命名空間是不同的,在linux上有一種veth的虛擬網(wǎng)絡(luò)設(shè)備,它是成對(duì)出現(xiàn)的,所以也被叫做veth pair,可以連接不同命名空間。
從veth一端發(fā)出去的包能夠被另外一端接收到,通過(guò)veth pair能夠連通兩個(gè)命名空間。
但是如果一臺(tái)主機(jī)上,有許多pod,要想讓那么多pod都連通的話,就得兩兩建立veth pair設(shè)備,這樣的排列組合數(shù)量隨著pod的增加會(huì)變得相當(dāng)大。
而網(wǎng)橋的出現(xiàn)能夠讓這個(gè)網(wǎng)絡(luò)模型變成 veth pair的一端連通著pod的網(wǎng)絡(luò)命名空間,一端是連接在網(wǎng)橋上,讓網(wǎng)橋充當(dāng)交換機(jī)的作用,同一臺(tái)主機(jī)的不同pod的數(shù)據(jù)包都經(jīng)過(guò)網(wǎng)橋去進(jìn)行轉(zhuǎn)發(fā)。
交換機(jī)是工作在網(wǎng)絡(luò)的第二層,所以只會(huì)將數(shù)據(jù)包解析到數(shù)據(jù)幀的格式,只認(rèn)mac地址,如果是廣播幀,轉(zhuǎn)發(fā)給所有接入網(wǎng)橋的設(shè)備,如果是單播幀,那么就會(huì)發(fā)往特定的端口。
但是網(wǎng)橋作為交換機(jī)與之不同的一點(diǎn)是,網(wǎng)橋具有將轉(zhuǎn)發(fā)數(shù)據(jù)包到主機(jī)的三層網(wǎng)絡(luò)協(xié)議棧的功能,如果發(fā)往網(wǎng)橋的數(shù)據(jù)包的mac地址就是網(wǎng)橋自身mac地址的話,那么網(wǎng)橋就會(huì)認(rèn)為數(shù)據(jù)包是要發(fā)往數(shù)據(jù)的數(shù)據(jù)包,然后去對(duì)其進(jìn)行轉(zhuǎn)發(fā)。
查看集群pod 信息
再結(jié)合 pod 看看pod內(nèi)部的網(wǎng)絡(luò)數(shù)據(jù)包是如何輸出到網(wǎng)橋上的。我在集群內(nèi)部啟動(dòng)了一個(gè)3副本的busybox鏡像的 pod。
來(lái)看看pod分布的工作節(jié)點(diǎn)以及其ip地址
(base) ? ~ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES busybox-8647b8666c-74nmg 1/1 Running 0 3h19m 10.10.1.3 worker1 <none> <none> busybox-8647b8666c-bwgh9 1/1 Running 1 (4h29m ago) 12d 10.10.2.4 worker2 <none> <none> busybox-8647b8666c-qwzrh 1/1 Running 1 (4h29m ago) 4h57m 10.10.2.5 worker2 <none> <none>
我們的目的就是讓worker2節(jié)點(diǎn)上ip為10.10.2.4 的pod能ping通 worker1節(jié)點(diǎn)上ip為10.10.1.3的pod
進(jìn)入worker2節(jié)點(diǎn)上 ip為10.10.2.4 的pod內(nèi)部看看路由信息。
/ # route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 10.10.2.1 0.0.0.0 UG 0 0 0 eth0 10.10.0.0 10.10.2.1 255.255.0.0 UG 0 0 0 eth0 10.10.2.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
還記得剛剛說(shuō)的worker2節(jié)點(diǎn)上的cni0網(wǎng)橋的ip是10.10.2.1 嗎?
通過(guò)路由信息,可以看到10.10.2.1正是pod的網(wǎng)關(guān),所以如果在pod內(nèi)部 ping worker1上的pod ip 10.10.1.3 ,就會(huì)匹配上第二條路由信息。
那么worker2 的pod發(fā)出去的數(shù)據(jù)包就指定到達(dá)10.10.2.1這個(gè)ip上,所以mac地址就是10.10.2.1對(duì)應(yīng)的mac地址,即cni0的mac地址。
正是由于這個(gè)原因,觸發(fā)了cni0網(wǎng)橋的轉(zhuǎn)發(fā)到主機(jī)上的三層網(wǎng)絡(luò)協(xié)議棧的這個(gè)機(jī)制,而到達(dá)worker2主機(jī)后,通過(guò)ip要看具體轉(zhuǎn)發(fā)到哪張網(wǎng)卡是看主機(jī)的路由信息的,所以,先看下worker2的路由信息。
parallels@worker2:~/Desktop$ route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.2.1 0.0.0.0 UG 100 0 0 enp0s5 10.10.0.0 10.10.0.0 255.255.255.0 UG 0 0 0 flannel.1 10.10.1.0 10.10.1.0 255.255.255.0 UG 0 0 0 flannel.1 10.10.2.0 0.0.0.0 255.255.255.0 U 0 0 0 cni0 172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0 192.168.2.0 0.0.0.0 255.255.255.0 U 100 0 0 enp0s5 192.168.2.1 0.0.0.0 255.255.255.255 UH 100 0 0 enp0s5
我們數(shù)據(jù)包目的地是worker1上的pod ,ip是10.10.1.3 ,通過(guò)路由信息,看到屬于10.10.1.0/24這個(gè)網(wǎng)段的數(shù)據(jù)包都會(huì)經(jīng)過(guò) flannel.1發(fā)出,網(wǎng)關(guān)是10.10.1.0 ,這個(gè)ip也就是對(duì)端vtep設(shè)備的ip地址。
數(shù)據(jù)包就這樣從worker2的pod來(lái)到了worker2節(jié)點(diǎn)上的flannel.1 這個(gè)網(wǎng)卡上。
flannel.1會(huì)對(duì)數(shù)據(jù)包進(jìn)行一些加工,加工時(shí)需要加上對(duì)端vtep的mac地址,由于flannel.1 通過(guò)路由信息已經(jīng)知道對(duì)端vtep的ip地址,通過(guò)查詢本地arp緩存表,得到目的vtep的mac地址。
parallels@worker2:~/Desktop$ ip neigh show dev flannel.1 10.10.1.0 lladdr 72:5a:79:44:22:7b PERMANENT 10.10.0.0 lladdr 62:03:91:cb:cc:36 PERMANENT
k8s是通過(guò)flanneld(在flannel插件工作模式下,每個(gè)節(jié)點(diǎn)上都有一個(gè)flanneld的后臺(tái)進(jìn)程,對(duì)節(jié)點(diǎn)上的一些網(wǎng)絡(luò)信息進(jìn)行配置)在worker2的arp緩存中寫(xiě)入了mac地址,且永不過(guò)期。
同時(shí)還會(huì)加上vxlan頭部信息,在頭部信息中表明了這是一個(gè)vxlan幀,這樣worker1節(jié)點(diǎn)收到數(shù)據(jù)包時(shí),知道這是一個(gè)vxlan幀后,會(huì)將這個(gè)包去進(jìn)行解包操作,同時(shí)頭部信息中也包含一個(gè)vni的信息,只有vni相同的網(wǎng)絡(luò)設(shè)備才有解包的資格。
這樣封裝以后,還需要將這個(gè)包發(fā)往對(duì)端vtep所在的主機(jī)節(jié)點(diǎn),怎么發(fā)送呢?
worker2的flannel.1用udp格式的數(shù)據(jù)包再包裹一下vxlan幀,封裝成udp時(shí),需要知道對(duì)端的ip地址。
這里封裝成udp包的時(shí)候,是如何知道目的節(jié)點(diǎn)主機(jī)的ip的呢。 flannel.1 通過(guò)查詢本機(jī)的一個(gè)叫做fdb的轉(zhuǎn)發(fā)數(shù)據(jù)庫(kù)獲取目的節(jié)點(diǎn)主機(jī)的ip。
parallels@worker2:~/Desktop$ bridge fdb show flannel.1 | grep 72:5a:79:44:22:7b 72:5a:79:44:22:7b dev flannel.1 dst 192.168.2.16 self permanent
注意這些配置信息是在woker1節(jié)點(diǎn)啟動(dòng)后,就會(huì)在worker2節(jié)點(diǎn)自動(dòng)加上的,而完成配置信息的動(dòng)作是由各個(gè)主機(jī)上的flanneld進(jìn)程完成的
知道了udp的目的ip后,就是一個(gè)正常數(shù)據(jù)包在宿主機(jī)上的封包,發(fā)送流程了。
這樣,數(shù)據(jù)包就到達(dá)了worker1。
worker1節(jié)點(diǎn)的接收過(guò)程
worker1 的內(nèi)核協(xié)議棧收到數(shù)據(jù)包以后,發(fā)現(xiàn)有vxlan header以及vni標(biāo)記是1,就將這個(gè)vxlan包發(fā)給本機(jī)的vni標(biāo)記也為1的flannel.1設(shè)備。
然后flannel.1進(jìn)行解包,取出數(shù)據(jù)包的目的ip是10.10.1.3,然后查看worer1本機(jī)路由信息。
arallels@worker1:~/Desktop$ route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.2.1 0.0.0.0 UG 100 0 0 enp0s5 10.10.0.0 10.10.0.0 255.255.255.0 UG 0 0 0 flannel.1 10.10.1.0 0.0.0.0 255.255.255.0 U 0 0 0 cni0 10.10.2.0 10.10.2.0 255.255.255.0 UG 0 0 0 flannel.1 172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0 192.168.2.0 0.0.0.0 255.255.255.0 U 100 0 0 enp0s5 192.168.2.1 0.0.0.0 255.255.255.255 UH 100 0 0 enp0s5 parallels@worker1:~/Desktop$
發(fā)現(xiàn)發(fā)往10.10.1.0/24這個(gè)網(wǎng)段的包要經(jīng)過(guò)cni0網(wǎng)橋,所以flannel.1將解包后的數(shù)據(jù)包轉(zhuǎn)發(fā)給了cni0網(wǎng)橋。
接下來(lái)就是cni0網(wǎng)橋在一個(gè)10.10.1.0/24 子網(wǎng)內(nèi)發(fā)送目的ip為 10.10.1.3 的流程了。
cni0網(wǎng)橋先通過(guò)10.10.1.3查找本地mac地址,如果有則發(fā)往mac地址對(duì)應(yīng)的端口,端口連通的另一端是veth設(shè)備也是worker1上的pod的網(wǎng)卡。
如果沒(méi)有10.10.1.3的mac地址,則先通過(guò)arp協(xié)議,在一個(gè)局域網(wǎng)內(nèi)獲得arp響應(yīng)包后,再發(fā)送數(shù)據(jù)包到對(duì)應(yīng)端口連通的pod veth網(wǎng)卡上。
至此,worker1成功收到了worker2發(fā)送的數(shù)據(jù)包了。
再看flannel xvlan模式
本質(zhì)上是通過(guò)flannel.1這個(gè)vxlan設(shè)備對(duì)主機(jī)發(fā)出去的數(shù)據(jù)包進(jìn)行udp封裝,然后發(fā)往經(jīng)過(guò)物理網(wǎng)卡發(fā)往對(duì)端。
再進(jìn)一步思考下,udp是可以丟包的,那么經(jīng)過(guò)udp去封裝數(shù)據(jù)包 的網(wǎng)絡(luò)傳輸是可靠的嗎?
答案是不需要可靠,整個(gè)flannel的轉(zhuǎn)發(fā)模型,可以看出flannel完成的是網(wǎng)絡(luò)模型的第三層次ip層的互通, 這里udp封裝的ip包實(shí)際上是充當(dāng)了第二層鏈路層的工作了,傳輸?shù)目煽啃允强總鬏攲訉?shí)現(xiàn)的,傳輸層的靠是在對(duì)應(yīng)pod所在命名空間中的tcp 的重傳保證的。
以上就是k8s容器互聯(lián)flannel vxlan通信原理的詳細(xì)內(nèi)容,更多關(guān)于k8s容器互聯(lián)flannel vxlan的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
詳解Golang中文件系統(tǒng)事件監(jiān)聽(tīng)
文件系統(tǒng)事件是指文件系統(tǒng)相關(guān)的各種操作和狀態(tài)變化,當(dāng)一個(gè)應(yīng)用層的進(jìn)程操作文件或目錄時(shí),會(huì)觸發(fā)system call,內(nèi)核的notification子系統(tǒng)可以守在那里,把該進(jìn)程對(duì)文件的操作上報(bào)給應(yīng)用層的監(jiān)聽(tīng)進(jìn)程,這篇文章主要介紹了Golang之文件系統(tǒng)事件監(jiān)聽(tīng),需要的朋友可以參考下2024-01-01go-zero源碼閱讀之布隆過(guò)濾器實(shí)現(xiàn)代碼
布隆過(guò)濾器可以用于檢索一個(gè)元素是否在一個(gè)集合中。它的優(yōu)點(diǎn)是空間效率和查詢時(shí)間都比一般的算法要好的多,缺點(diǎn)是有一定的誤識(shí)別率和刪除困難,這篇文章主要介紹了go-zero源碼閱讀-布隆過(guò)濾器,需要的朋友可以參考下2023-02-02golang 刪除切片的某個(gè)元素及剔除切片內(nèi)的零值方式
這篇文章主要介紹了golang 刪除切片的某個(gè)元素及剔除切片內(nèi)的零值方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04Go框架三件套Gorm?Kitex?Hertz基本用法與常見(jiàn)API講解
這篇文章主要為大家介紹了Go框架三件套Gorm?Kitex?Hertz的基本用法與常見(jiàn)API講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR>2023-02-02Go?WEB框架使用攔截器驗(yàn)證用戶登錄狀態(tài)實(shí)現(xiàn)
這篇文章主要為大家介紹了Go?WEB框架使用攔截器驗(yàn)證用戶登錄狀態(tài)實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07Go語(yǔ)言使用HTTP包創(chuàng)建WEB服務(wù)器的方法
這篇文章主要介紹了Go語(yǔ)言使用HTTP包創(chuàng)建WEB服務(wù)器的方法,結(jié)合實(shí)例形式分析了Go語(yǔ)言基于HTTP包創(chuàng)建WEB服務(wù)器客戶端與服務(wù)器端的實(shí)現(xiàn)方法與相關(guān)注意事項(xiàng),需要的朋友可以參考下2016-07-07