Kubernetes網路外掛Flannel的三種工作模式
跨主機通訊的一個解決方案是Flannel,由CoreOS推出,支援3種實現:UDP、VXLAN、host-gw
一、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地址,這樣可以經過二層網路到達目的宿主機
總結
udp模式:使用裝置flannel.0進行封包解包,不是核心原生支援,上下文切換較大,效能非常差
vxlan模式:使用flannel.1進行封包解包,核心原生支援,效能較強
host-gw模式:無需flannel.1這樣的中間裝置,直接宿主機當作子網的下一跳地址,效能最強
host-gw的效能損失大約在10%左右,而其他所有基於VXLAN“隧道”機制 的網路方案,效能損失在20%~30%左