Flannel的VXLAN模式工作原理
- 2019 年 10 月 21 日
- 筆記
跨主機通訊的一個解決方案是Flannel,由CoreOS推出,最早支援的是UDP模式,但是因為性能太差被淘汰了,
過時的UDP模式
相比兩台宿主機直接通訊,多出了flanneld的處理過程,發出IP包的過程經過了三次用戶態到內核態的數據拷貝(linux的上下文切換代價比較大)
flannel進行udp的封裝和解封都是在用戶態完成的。
工作原理如下
以flanel0是一個TUN設備,功能是:在作業系統內核和用戶應用程式之間傳遞IP包,作業系統將一個IP包發給flanel0,flanel0把IP包發給創建這個設備的應用程式:flanel進程(內核態->用戶態)
2.相反,flanel進程向flanel0發送一個IP包,IP包會出現在宿主機的網路棧中,然後根據宿主機的路由表進行下一步處理(用戶態->內核態)
當IP包從容器經過docker0出現在宿主機,又根據路由表進入flanel0設備後,宿主機上的flanneld進程就會收到這個IP包
flanneld如何知道IP地址對應的容器運行在哪個Node上?
flannel管理的容器網路里,一台宿主機上的所有容器,都屬於該宿主機被分配的「子網」,例如Node1的子網是100.96.1.0/24,container-1的IP地址是100.96.1.2
子網與宿主機的對應不關係,存在Etcd中
當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(虛擬隧道端點)
Flannel的VXLAN工作原理
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設備