flannel網路概述

神祕玩家Y發表於2020-11-08

**

flannel網路概述

**
flannel 是 CoreOS 開發的容器網路解決方案。flannel 為每個 host 分配一個 subnet(子網),容器從此 subnet 中分配 IP,這些 IP 可以在主機間路由,容器間無需 NAT 和 port mapping(埠對映) 就可以跨主機通訊。

flannel的作用
因為flannel實現跨主機的子網通訊是通過主機中的dr0網路卡進行通訊的,由flannel分配的子網都是從手動指定的一個大的子網中劃分出來分配的。

flannel 會在每個主機上執行一個叫 flanneld 的代理。其職責就是從池子中分配 subnet。為了在各個主機間共享資訊,flannel 用 etcd(與 consul 類似的 key-value 分散式資料庫)存放網路配置、已分配的 subnet、host 的 IP 等資訊。

資料包轉發原理
資料包如何在主機間轉發是由 backend 實現的。flannel 提供了多種 backend,最常用的有 vxlan 和 host-gw

其他 backend 請參考 https://github.com/coreos/flannel

跨主機容器網路通訊實現工具
Docker跨主機容器間網路通訊實現的工具有pipework、flannel、weave、open vswitch(虛擬交換機)、calico

其中flannel和weave的區別是:

weave的思路
在每個宿主機上佈置一個特殊的route的容器,不同宿主機的route容器連線起來。 route攔截所有普通容器的ip請求,並通過udp包傳送到其他宿主機上的普通容器。這樣在跨機的多個容器端看到的就是同一個扁平網路。 weave解決了網路問題,不過部署依然是單機的。不是跨主機的。

flannel的思路
flannel是CoreOS團隊針對Kubernetes設計的一個網路規劃服務,也就是說使用k8s一般都會使用flannel。簡單來說,它的功能是讓叢集中的不同節點主機建立的Docker容器都具有全叢集唯一的虛擬IP地址。也就是前面說過的指定一個大的網段來劃分子網,所有的容器ip都包含在大網段之內,所以可以進行通訊,而ip不重複。最終可以通過內網ip橋接到dr0與外網通訊

flannel實質上是一種”覆蓋網路(overlay network)”,即表示執行在一個網上的網(應用層網路),並不依靠ip地址來傳遞訊息,而是採用一種對映機制,把ip地址和identifiers(識別符號)做對映來資源定位。也就是將TCP資料包裝在另一種網路包裡面進行路由轉發和通訊,目前已經支援UDP、VxLAN、AWS VPC和GCE路由等資料轉發方式。

flannel 使用etcd儲存配置資料和子網分配資訊。flannel 啟動之後,後臺程式首先檢索配置和正在使用的子網列表,然後選擇一個可用的子網,然後嘗試去註冊它。etcd也儲存這個每個主機對應的ip。flannel 使用etcd的watch機制監視/coreos.com/network/subnets下面所有元素的變化資訊,並且根據它來維護一個大路由表,在flannel網路中只有這一個路由表。為了提高效能,flannel優化了Universal TAP/TUN裝置,對TUN和UDP之間的ip分片做了代理。

如果將TCP資料包封裝在UDP包中,他們的MTU(最大傳輸單元)值是不同的,也就是說傳送的每個資料包的大小是不同的,TCP為1500,UDP為1450。

flannel工作原理
每個主機配置一個ip段和子網個數。例如,可以配置一個覆蓋網路使用 10.100.0.0/16段,每個主機/24個子網。因此主機a可以接受10.100.5.0/24,主機B可以接受10.100.18.0/24的包。flannel使用etcd來維護分配的子網到實際的ip地址之間的對映。

對於資料路徑,flannel 使用udp來封裝ip資料包,轉發到遠端主機。選擇UDP作為轉發協議是因為他能穿透防火牆。例如,AWS Classic無法轉發IPoIP or GRE 網路包。是因為它的安全組僅僅支援TCP/UDP/ICMP

Flannel工作原理流程圖如下 (預設的節點間資料通訊方式是UDP轉發; flannel預設使用8285埠作為UDP封裝報文的埠,VxLan使用8472埠

flannel工作原理
在這裡插入圖片描述

如圖所示中

為flanneld指定了ip地址池後,如:10.10.0.0/16,並指定每臺主機以/24的子網掩碼來劃分子網,當啟動了flanneld服務之後,叢集中每臺物理機會生成一個flannel.1的網路卡,且網段為已經分配好的網段,如圖中所示,且在主機路由也會出現該地址池的路由條目,來自該地址池中的ip都會通過flannel.1網路卡來轉發資料包。

然後將docker0與flannel.1通過在docker啟動項裡面增加bip和mtu的方式,使得子網網段由docker0來轉發,也就是docker0作為了子網的閘道器,如圖docker0所示

此時如果1.12的容器要去與1.13的容器進行互發ping包測試,容器中的ip會通過docker0的橋接到flannel.1來轉發ping包,並由flanneld服務對資料包進行UDP封裝,根據路由表傳送到1.13的flanneld服務解封裝,再次由目的主機的docker0橋接轉發到目標容器中實現互通。

flanneld中管理了一張大的路由表,裡面儲存了整個叢集中使用了由他分配的ip的路由條目及網段資訊等等。

相關文章