堅持看下去,文末送機械鍵盤一個 本文中,筆者主要結合自己使用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
網橋設備上,這樣就實現了宿主機內容器的通信;
最後容器綁定到網橋設備之後,如果需要訪問外網,那麼藉助於linux
的IP
轉發規則,以及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
,因爲container2
的IP
地址爲10.244.1.14
,根據路由規則,從而進入到flannel0
設備中。
最後flannel0
看到container1
要訪問的IP
地址爲10.244.1.14
的容器,因爲flannel
在etcd
中存儲着子網和宿主機ip
的對應關係,所以能夠找到10.244.1.14
對應的宿主機IP
爲11.101.1.3
,進而開始組裝UDP
數據包發送數據到目的主機。當然這個請求得以完成的原因每個節點上都啓動着一個flanneld udp
進程,都監聽着8285
端口,所以node1
通過flanneld
進程把數據包發送給node2
的flanneld
進程的相應端口即可。
可以看出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
的兩臺虛擬終端,其通信過程可以概括爲如下的步驟:
發送方向接收方發送數據幀,幀中包含了發送方和接收方的虛擬
MAC
地址。發送方連接的
VTEP
節點收到了數據幀,通過查找發送方所在的VXLAN
以及接收方所連接的VTEP
節點,將該報文添加VXLAN
首部、外部UDP
首部、外部IP首部後,發送給目的VTEP
節點。報文經過物理網絡傳輸到達目的
VTEP
節點。目的
VTEP
節點接收到報文後,拆除報文的外部IP
首部和外部UDP
首部,檢查報文的VNI
以及內部數據幀的目的MAC
地址,確認接收方與本VTEP
節點相連後,拆除VXLAN
首部,將內部數據幀交付給接收方。接收方收到數據幀,傳輸完成。
通過以上的步驟可以看出: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
地址,通過這個過程,容器在通信過程中就減少了封包和解包的性能損耗。如下圖所示:
同
UDP、VXLAN
模式一致,通過容器A的路由表IP
包到達cni0
,到達cni0
的IP
包匹配到node1
中的路由規則(10.244.1.1/24)
,且網關爲11.101.1.3
,即主機node2
,所以內核將IP
包發送給node2
,IP
包通過物理網絡到達node2
的eth0
;到達
node2
的eth0
的IP
包匹配到node2
上的路由表(10.244.0.1/24)
,IP
包轉發給cni0
,cni0
將IP
包轉發給連接在cni0
上的Container2
。
通過上述這個過程可以看出這臺主機的host
就充當了容器通信路徑裏的網關,IP
封裝成幀的時候,會使路由表中的下一跳來設置目的MAC
地址,它會經過二層網絡達到宿主機,但同時這個限制也是有問題的,首先要求我們必須保證集羣內部所有主機二層網絡必須是連通的,然後在大規模集羣路由表的動態更新也存在一定壓力。採用host-gw
模式後,flanneld
的唯一作用就是負責主機上路由表的動態更新。當然這個限制也是有解決方案的,這裏不在過多介紹,詳細可以瞭解Calico
。
總結
通過如上過程,我們可以看到flannel
從UDP、wxlan、host-gw
網絡通信方案的技術演進過程,通過一系列的演進使得架構更簡單、同時性能得到了提高。如有問題請留言或者關注後拉你進羣討論。希望能夠幫助到大家,謝謝閱讀!
贈送電競系列機械鍵盤福利
爲感謝各位讀者支持 6月27日12:00前在留言區討論交流,精選留言點贊第 1 名,即可免費獲得此鍵盤。
推薦閱讀
完整的Kubernetes Deployment yaml文件應該包含什麼?
原創不易,隨手關注或者”在看“,誠摯感謝!