Kubernetes網絡插件Flannel的3種工作模式


前言

跨主機通信的一個解決方案是Flannel,由CoreOS推出,支持3種實現:UDP、VXLAN、host-gw
udp模式:使用設備flannel.0進行封包解包,不是內核原生支持,上下文切換較大,性能非常差
vxlan模式:使用flannel.1進行封包解包,內核原生支持,性能較強
host-gw模式:無需flannel.1這樣的中間設備,直接宿主機當作子網的下一跳地址,性能最強
host-gw的性能損失大約在10%左右,而其他所有基於VXLAN“隧道”機制 的網絡方案,性能損失在20%~30%左右

一、UDP模式(性能差)

核心就是通過TUN設備flannel0實現(TUN設備是工作在三層的虛擬網絡設備,功能是:在操作系統內核和用戶應用程序之間傳遞IP包)
相比兩台宿主機直接通信,多出了flanneld的處理過程,這個過程,使用了flannel0這個TUN設備,僅在發出IP包的過程中就要經過了三次用戶態到內核態的數據拷貝(linux的上下文切換代價比較大),所以性能非常差
原理如下:

以flanel0為例,操作系統將一個IP包發給flanel0,flanel0把IP包發給創建這個設備的應用程序:flanel進程(內核態->用戶態)
相反,flanel進程向flanel0發送一個IP包,IP包會出現在宿主機的網絡棧中,然后根據宿主機的路由表進行下一步處理(用戶態->內核態)
當IP包從容器經過docker0出現在宿主機,又根據路由表進入flanel0設備后,宿主機上的flanneld進程就會收到這個IP包

flannel管理的容器網絡里,一台宿主機上的所有容器,都屬於該宿主機被分配的“子網”,子網與宿主機的對應關系,存在Etcd中(例如Node1的子網是100.96.1.0/24,container-1的IP地址是100.96.1.2)
當flanneld進程處理flannel0傳入的IP包時,就可以根據目的IP地址(如100.96.2.3),匹配到對應的子網(比如100.96.2.0/24),從Etcd中找到這個子網對應的宿主機的IP地址(10.168.0.3)
然后flanneld在收到container-1給container-2的包后,把這個包直接封裝在UDP包里,發送給Node2(UDP包的源地址,就是Node1,目的地址是Node2)
每台宿主機的flanneld都監聽着8285端口,所以flanneld只要把UDP發給Node2的8285端口就行了。然后Node2的flanneld再把IP包發送給它所管理的TUN設備flannel0,flannel0設備再發給docker0

二、VXLAN模式(性能較好)

什么是VXLAN?
VXLAN,即Virtual Extensible LAN(虛擬可擴展局域網),是Linux本身支持的一網種網絡虛擬化技術。VXLAN可以完全在內核態實現封裝和解封裝工作,從而通過“隧道”機制,構建出覆蓋網絡(Overlay Network)

VXLAN的設計思想是:
在現有的三層網絡之上,“覆蓋”一層虛擬的、由內核VXLAN模塊負責維護的二層網絡,使得連接在這個VXLAN二nfcu網絡上的“主機”(虛擬機或容器都可以),可以像在同一個局域網(LAN)里那樣自由通信。
為了能夠在二nfcu網絡上打通“隧道”,VXLAN會在宿主機上設置一個特殊的網絡設備作為“隧道”的兩端,叫VTEP:VXLAN Tunnel End Point(虛擬隧道端點)
原理如下:

flanel.1設備,就是VXLAN的VTEP,即有IP地址,也有MAC地址
與UPD模式類似,當container-發出請求后,上的地址10.1.16.3的IP包,會先出現在docker網橋,再路由到本機的flannel.1設備進行處理(進站)
為了能夠將“原始IP包”封裝並發送到正常的主機,VXLAN需要找到隧道的出口:上的宿主機的VTEP設備,這個設備信息,由宿主機的flanneld進程維護

VTEP設備之間通過二層數據楨進行通信
源VTEP設備收到原始IP包后,在上面加上一個目的MAC地址,封裝成一個導去數據楨,發送給目的VTEP設備(獲取 MAC地址需要通過三層IP地址查詢,這是ARP表的功能)

封裝過程只是加了一個二層頭,不會改變“原始IP包”的內容
這些VTEP設備的MAC地址,對宿主機網絡來說沒什么實際意義,稱為內部數據楨,並不能在宿主機的二層網絡傳輸,Linux內核還需要把它進一步封裝成為宿主機的一個普通的數據楨,好讓它帶着“內部數據楨”通過宿主機的eth0進行傳輸,Linux會在內部數據楨前面,加上一個我死的VXLAN頭,VXLAN頭里有一個重要的標志叫VNI,它是VTEP識別某個數據楨是不是應該歸自己處理的重要標識。
在Flannel中,VNI的默認值是1,這也是為什么宿主機的VTEP設備都叫flannel.1的原因

一個flannel.1設備只知道另一端flannel.1設備的MAC地址,卻不知道對應的宿主機地址是什么。
在linux內核里面,網絡設備進行轉發的依據,來自FDB的轉發數據庫,這個flannel.1網橋對應的FDB信息,是由flanneld進程維護的
linux內核再在IP包前面加上二層數據楨頭,把Node2的MAC地址填進去。這個MAC地址本身,是Node1的ARP表要學習的,需
Flannel維護,這時候Linux封裝的“外部數據楨”的格式如下

然后Node1的flannel.1設備就可以把這個數據楨從eth0發出去,再經過宿主機網絡來到Node2的eth0
Node2的內核網絡棧會發現這個數據楨有VXLAN Header,並且VNI為1,Linux內核會對它進行拆包,拿到內部數據楨,根據VNI的值,所它交給Node2的flannel.1設備

三、host-gw模式(性能最高)

這是一種純三層網絡的方案,性能最高

howt-gw模式的工作原理,就是將每個Flannel子網的下一跳,設置成了該子網對應的宿主機的IP地址,也就是說,宿主機(host)充當了這條容器通信路徑的“網關”(Gateway),這正是host-gw的含義
所有的子網和主機的信息,都保存在Etcd中,flanneld只需要watch這些數據的變化 ,實時更新路由表就行了。
核心是IP包在封裝成楨的時候,使用路由表的“下一跳”設置上的MAC地址,這樣可以經過二層網絡到達目的宿主機


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM