flannel跨主網絡通信方案(UDP、VXLAN、HOST-GW)詳解

堅持看下去,文末送機械鍵盤一個 本文中,筆者主要結合自己使用flannel心得,以及flannel的技術演進,介紹下flannel網絡實現方案。在沒有介紹flannel overlay網絡實現方案之前,先回顧下docker網絡實現方案。

docker網絡模式有哪些?

bridge、host、none 新版本docker出現了macvlan、overlay跨主機網絡通信方案。

橋接模式是如何實現的呢?

首先docker在默認安裝情況下,啓動之後會默認建立docker0 linux網橋設備、該網橋設備擁有一個私有網絡地址以及子網,通常使用子網中第一個沒有被佔用的地址。比如:172.16.0.1;

然後docker容器在啓動的時候會連接到網橋設備上,並分配一個子網地址。容器連接到網橋的網絡接口會把docker0設備作爲網關。創建容器時,docker會創建一對網絡設備接口,並把他們放到獨立的命名空間中:一個網絡設備放到容器的網絡命名空間中eth0,另一個網絡設備會放到宿主機網絡空間中,例如:veth80025c52,並連接到docker0網橋設備上。所以如果仔細觀察容器內部網卡設備信息和宿主機的網卡信息,你會發現這一對網絡設備是一一對應的。當然宿主機上其它容器也會連接到docker0網橋設備上,這樣就實現了宿主機內容器的通信;

最後容器綁定到網橋設備之後,如果需要訪問外網,那麼藉助於linuxIP轉發規則,以及docker引擎管理的防火牆規則以及nat功能,實現了外部網絡的訪問。

flannel三層網絡實現方式

需求描述:node1(11.101.1.2)上的container1(10.244.0.13)需要跨主機訪問node2(11.101.1.3)上的container2(10.244.1.14)。對於flannel是如何實現的呢?

UDP跨主通信模式

如上圖所示:首先flannel會在各個節點上創建路由規則,這些路由規則存儲在etcd中,跟宿主機節點IP一一對應。

然後在node1上,container1跨主訪問node2上的container2,因爲container2IP地址爲10.244.1.14,根據路由規則,從而進入到flannel0設備中。

最後flannel0看到container1要訪問的IP地址爲10.244.1.14的容器,因爲flanneletcd中存儲着子網和宿主機ip的對應關係,所以能夠找到10.244.1.14對應的宿主機IP11.101.1.3,進而開始組裝UDP數據包發送數據到目的主機。當然這個請求得以完成的原因每個節點上都啓動着一個flanneld udp進程,都監聽着8285端口,所以node1通過flanneld進程把數據包發送給node2flanneld進程的相應端口即可。

可以看出flannel UDP模式提供了一個三層OverLay網絡,這就好比在不同宿主機的容器上打通了一條隧道,容器不用關心IP地址即可直接通信。它首先對發出端的數據包進行UDP封裝,然後在接收端進行解包,進而把包發送到目的容器地址。但是這裏面有一個非常嚴重的問題,就是flannel UDP進程運行在用戶態,而數據的交互和傳遞則在內核態完成,這就造成了爲了傳遞數據,需要內核態和用戶態的頻繁切換,這個切換過程有一定性能損耗代價,所以UDP模式已經廢棄。

VXLAN跨主通信模式

VXLAN(Vitrue Extension lan虛擬可擴展局域網)Linux本身支持的一種虛擬可擴展局域網。VXLAN完全在內核態完成上述封包和解包的過程。從而通過前面的隧道機制完成overlay 覆蓋網絡。rfc7348詳細地介紹了VXLAN的實現機制。本質上VXLAN是一種隧道技術。通過將虛擬網絡中的數據幀封裝在實際物理網絡中的報文中進行傳輸。具體實現方式爲:將虛擬網絡的數據幀添加VXLAN首部後,封裝在物理網絡中的UDP報文中,然後以傳統網絡的通信方式傳送該UDP報文,到達目的主機後,去掉物理網絡報文的頭部信息以及VXLAN首部,將報文交付給目的終端。整個通信過程目的終端不會感知到物理網絡的存在。

  • VXLAN技術組網過程圖中兩臺終端T1和T2位於不同的網絡中,二者通過路由器來實現互通,通過VXLAN可以使得這兩臺終端在“邏輯上”位於“同一個”鏈路層網絡中而與兩臺終端直接相連的路由器也在邏輯上構建了一條在虛擬鏈路中的通道vxlan tunnel,這樣的路由器我們稱之爲vxlan隧道終端(VXLAN Tunnel End Point, VTEP)。在包含VXLAN的網絡中,VXLAN的實現機制僅僅對VTEP節點可見。

  • VXLAN通信原理VXLAN通過將邏輯網絡中通信的數據幀封裝在物理網絡中進行傳輸,封裝和解封裝的過程由VTEP節點完成。VXLAN將邏輯網絡中的數據幀添加VXLAN首部後,封裝在物理網絡中的UDP報文中傳送,VXLAN首部的格式如下:VXLAN首部由8個字節組成,第1個字節爲標誌位,其中標誌位I設爲1表示是一個合法的VXLAN首部,其餘標誌則保留,在傳輸過程中必須置爲0;第2-4字節爲保留部分,第5-7字節爲VXLAN標識符,用來表示唯一的一個邏輯網絡;第8個字節同樣爲保留字段,暫未使用。VXLAN傳輸過程中,將邏輯鏈路網絡的數據幀添加VXLAN首部後,依次添加UDP首部,IP首部,以太網幀首部後,在物理網絡中傳輸,數據幀的封裝格式可以用下圖來描述:需要注意的是,外部UDP首部的目的端口號爲4789,該數值爲默認VXLAN解析程序的端口,外層IP首部中的源IP和目的IP地址均填寫通信雙方的VTEP地址,協議的其餘部分和傳統網絡相同。

  • 通信過程

對於處於同一個VXLAN的兩臺虛擬終端,其通信過程可以概括爲如下的步驟:

  1. 發送方向接收方發送數據幀,幀中包含了發送方和接收方的虛擬MAC地址。

  2. 發送方連接的VTEP節點收到了數據幀,通過查找發送方所在的VXLAN以及接收方所連接的VTEP節點,將該報文添加VXLAN首部、外部UDP首部、外部IP首部後,發送給目的VTEP節點。

  3. 報文經過物理網絡傳輸到達目的VTEP節點。

  4. 目的VTEP節點接收到報文後,拆除報文的外部IP首部和外部UDP首部,檢查報文的VNI以及內部數據幀的目的MAC地址,確認接收方與本VTEP節點相連後,拆除VXLAN首部,將內部數據幀交付給接收方。

  5. 接收方收到數據幀,傳輸完成。

通過以上的步驟可以看出:VXLAN的實現細節以及通信過程對於處於VXLAN中的發送方和接收方是不可見的,基於發送方和接收方的視角,其通信過程和二者真實處於同一鏈路層網絡中的情況完全相同。

對於Kubernetes flannel也是完全依賴linux vxlan實現了overlay的跨主網絡通信,如下圖所示:

從形式和流程上看,這個通信過程和上面基於UDP的通信方式是非常類似的,只不過flannel UDP進程換成了VTEP設備,通過VTEP設備完成封包和解包的過程,另外一點這個過程完全在內核中完成。flannel.1充當網橋的角色,進行UDP數據包的轉發。其中vxlan的通信過程也是flannel網絡插件中默認的通信方式,如下圖所示:

巨人的肩膀:

https://blog.csdn.net/jsh13417/article/details/80303098

host-gw跨主通信方式

host-gw的工作原理就是將每個flannel子網轉發地址設置成了該子網對應的宿主機的IP地址,通過這個過程,容器在通信過程中就減少了封包和解包的性能損耗。如下圖所示:

  1. UDP、VXLAN模式一致,通過容器A的路由表IP包到達cni0,到達cni0IP包匹配到node1中的路由規則(10.244.1.1/24),且網關爲11.101.1.3,即主機node2,所以內核將IP包發送給node2,IP包通過物理網絡到達node2eth0;

  2. 到達node2eth0IP包匹配到node2上的路由表(10.244.0.1/24)IP包轉發給cni0, cni0IP包轉發給連接在cni0上的Container2

通過上述這個過程可以看出這臺主機的host就充當了容器通信路徑裏的網關,IP封裝成幀的時候,會使路由表中的下一跳來設置目的MAC地址,它會經過二層網絡達到宿主機,但同時這個限制也是有問題的,首先要求我們必須保證集羣內部所有主機二層網絡必須是連通的,然後在大規模集羣路由表的動態更新也存在一定壓力。採用host-gw模式後,flanneld的唯一作用就是負責主機上路由表的動態更新。當然這個限制也是有解決方案的,這裏不在過多介紹,詳細可以瞭解Calico

總結

通過如上過程,我們可以看到flannelUDP、wxlan、host-gw網絡通信方案的技術演進過程,通過一系列的演進使得架構更簡單、同時性能得到了提高。如有問題請留言或者關注後拉你進羣討論。希望能夠幫助到大家,謝謝閱讀!

贈送電競系列機械鍵盤福利

爲感謝各位讀者支持 6月27日12:00前在留言區討論交流,精選留言點贊第 1 名,即可免費獲得此鍵盤。

推薦閱讀


完整的Kubernetes Deployment yaml文件應該包含什麼?

喧囂之後,關於Kubernetes的一點思考


原創不易,隨手關注或者”在看“,誠摯感謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章