Flannel Network
實現原理
Flannel為每個主機提供獨立的子網,整個集群的網絡信息存儲在etcd上。對於跨主機的轉發,目標容器的IP地址,需要從etcd獲取。
先上圖,比較直觀:

步驟:
(1)IP數據報被封裝並通過容器的eth0發送。
(2)Container1的eth0通過veth對與Docker0交互並將數據包發送到Docker0。然后Docker0轉發包。
(3)Docker0確定Container3的IP地址,通過查詢本地路由表到外部容器,並將數據包發送到虛擬NIC Flannel0。
(4)Flannel0收到的數據包被轉發到Flanneld進程。 Flanneld進程封裝了數據包通過查詢etcd維護的路由表並發送數據包通過主機的eth0。
(5)數據包確定網絡中的目標主機主機。
(6)目的主機的Flanneld進程監聽8285端口,負責解封包。
(7)解封裝的數據包將轉發到虛擬NICFlannel0。
(8)Flannel0查詢路由表,解封包,並將數據包發送到Docker0。
(9)Docker0確定目標容器並發送包到目標容器。
在常用的vxlan模式中,涉及到上面步驟提到的封包和拆包,這也是Flannel網絡傳輸效率相對低的原因。
圖片描述

VXLAN是Linux內核本身支持的一種網絡虛擬化技術,是內核的一個模塊,在內核態實現封裝解封裝,構建出覆蓋網絡,其實就是一個由各宿主機上的Flannel.1設備組成的虛擬二層網絡。
由於VXLAN由於額外的封包解包,導致其性能較差,所以Flannel就有了host-gw模式,即把宿主機當作網關,除了本地路由之外沒有額外開銷,性能和calico差不多,由於沒有疊加來實現報文轉發,這樣會導致路由表龐大。因為一個節點對應一個網絡,也就對應一條路由條目。
下面重點說一下host-gw模式。
hostgw是最簡單的backend,它的原理非常簡單,直接添加路由,將目的主機當做網關,直接路由原始封包。
例如,我們從etcd中監聽到一個EventAdded事件subnet為10.1.15.0/24被分配給主機Public IP 192.168.0.100,hostgw要做的工作就是在本主機上添加一條目的地址為10.1.15.0/24,網關地址為192.168.0.100,輸出設備為上文中選擇的集群間交互的網卡即可。對於EventRemoved事件,只需刪除對應的路由。
因為沒有了封包和拆包,host-gw的性能是最好的。
配置Host-gw:(在etcd集群中任意節點)
[root@node203 etcd]# ./etcdctl set /coreos.com/network/config '{"Network": "172.7.0.0/16", "Backend": {"Type": "host-gw"}}'

host-gw雖然VXLAN網絡性能要強很多。,但是種方式有個缺陷:要求各宿主機node節點必須在同一個二層網絡中。
物理節點必須在同一網段中。這樣會使得一個網段中的主機量會非常多,萬一發一個廣播報文就會產生干擾。
在私有雲場景下,宿主機不在同一網段是很常見的狀態,所以就不能使用host-gw了。
#https://www.cnblogs.com/liucx
Flnnel的VXLAN模式有兩種:
VXLAN: 原生的VXLAN,即擴展的虛擬LAN
Directrouting:直接路由型
使用Vxlan模式flanneld創建了一個flannel.1接口,它是專門用來封裝隧道協議的

(1)配置Vxlan模式:
[root@node203 etcd]#./etcdctl set /coreos.com/network/config '{"Network": "172.7.0.0/16", "Backend": {"Type": "VxLAN"}}'
修改后記得重啟flanneld
(2)配置Directrouting直接路由模式:((智能判定)推薦)
[root@node203 etcd]#../etcdctl set /coreos.com/network/config '{"Network": "172.7.0.0/16", "Backend": {"Type": "VxLAN","Directrouting": true}}'
修改后記得重啟flanneld

VXLAN支持host-gw,如果兩個節點在同一網段時使用host-gw通信,如果不在同一網段中,即 當前pod所在節點與目標pod所在節點中間有路由器,就使用VXLAN這種方式,使用疊加網絡。
結合了Host-gw和VXLAN,這就是VXLAN的Directrouting模式
