【容器網絡】Flannel容器網絡方案

Flannel容器網絡方案

Flannel共有三個容器網絡方案:Flannel UDP、Flannel VXLAN舊和Flannel VXLAN新。

Flannel UDP方案

Flannel UDP數據面如下:
在這裏插入圖片描述

同節點容器通信

容器A訪問容器B,數據面流程如下:

  1. 容器A和容器B在相同網絡,直接發送
  2. 容器A向容器B發送ARP請求,br0交換機flood該ARP請求
  3. 容器B接收到ARP請求,並響應
  4. br0交換機flood該ARP響應
  5. 容器A接收到ARP響應,封裝二層報文併發出
  6. br0交換機直接轉發報文到容器B
  7. 容器B接收到報文

跨節點容器通信

容器A訪問容器D,數據面流程如下:

  1. 容器A和容器D在不同網絡,通過網關轉發
  2. 容器A發送ARP請求給網關(10.10.1.1)
  3. 節點1內核響應ARP請求,併發送到br0口
  4. br0交換機轉發ARP響應給容器A
  5. 容器A收到ARP請求,封裝二層報文(目的MAC爲網關的MAC),併發出報文
  6. 報文通過veth設備到達br0,並通過br0接口上送至節點內核
  7. Host1內核根據報文目的IP地址,判斷需要路由轉發,查找路由表並匹配,通過tunX設備直接送達
  8. Host1內核發送ARP請求給容器D,併發送到tunX設備上
  9. flanneld創建了tunX設備的socket,flanned收到ARP請求報文
  10. flanneld響應ARP請求,並通過tunX socket發送ARP響應,該響應報文會被tunX設備接收並進入協議棧
  11. Host1內核收到ARP響應後,修改報文二層頭,併發送給tunXX設備
  12. flanneld收到該報文,並根據拓撲信息,把該報文封裝在UDP中,flanneld發送UDP報文給Host2
  13. Host2接收到UDP報文,經過協議棧上送給flanneld進程
  14. flanneld解封外層報文,並把內層報文通過tunXX設備發送給內核
  15. Host2內核根據報文的目的IP地址,查找路由,發現通過br0可以直達
  16. Host2內核發送ARP請求給容器D,併發送給br0接口
  17. br0交換機轉發ARP請求給容器D,容器D響應ARP請求,ARP響應通過br0接口上送到協議棧
  18. Host2內核更新報文的二層頭,併發送報文到br0接口
  19. br0交換機轉發報文給容器D
  20. 容器D接收到報文

flanneld接收到ARP請求後如何響應,有兩種做法:

  • 以對端tunXX設備的MAC地址響應
  • 固定tunXX設備的MAC地址,並且以該地址來響應

Flannel UDP方案總結

  • 網絡性能差
    • 使用socket機制報文轉發過程中,會從內核態切換到用戶態;
    • 對數據進行了外層封裝,內核對UDP封裝沒有優化;
  • 可以支持數據加密
    • flanneld可以做很多定製化的工作,容易擴展

Flannel VXLAN舊版方案

Flannel VXLAN舊版數據面如下:
在這裏插入圖片描述

同節點容器通信

容器A訪問容器B,數據面流程如下(同Flannel UDP):

  1. 容器A和容器B在相同網絡,直接發送
  2. 容器A向容器B發送ARP請求,br0交換機flood該ARP請求
  3. 容器B接收到ARP請求,並響應
  4. br0交換機flood該ARP響應
  5. 容器A接收到ARP響應,封裝二層報文併發出
  6. br0交換機直接轉發報文到容器B
  7. 容器B接收到報文

跨節點容器通信

容器A訪問容器D,數據面流程如下:

  1. 容器A和容器D在同一個網絡
  2. 容器A直接發送ARP請求
  3. br0交換機flood ARP請求
  4. vxlan設備接收到ARP請求
  5. 由於vxlan設備配置了arp proxy,查找內核ARP表項,如果未找到,則上報L3MISS
  6. flanneld接收到L3MISS,根據拓撲信息向內核中添加ARP表項
  7. 容器A由於未收到ARP響應,將會再次發送ARP請求,此時vxlan設備能夠響應該ARP請求(內核已添加該ARP表項)
  8. 容器A收到ARP響應,封裝二層報文,併發送
  9. br0轉發該報文到vxlan端口
  10. vxlan封裝外層vxlan頭,udp頭,IP頭,mac頭,其中目的IP需要根據內層報文目的MAC來獲取
  11. vxlan設備在內核FDB轉發表查找目的MAC的轉發項,未找到,則上報L2MISS
  12. flanneld接收到L2MISS信息,根據拓撲信息,向內核中添加FDB表項
  13. 此報文未成功發送,容器A重發報文
  14. vxlan設備此時能夠正確地封裝外層報文,併發送報文
  15. Host2接收到報文,通過UDP Socket,並進入到VXLAN解包處理,最終作爲vxlan設備收包處理,vxlan設備掛載到br0交換機
  16. br0交換機轉發報文給容器D

由於L3MISS和L2MISS何時上報與網上的文檔剛好相反,代碼是最有說服力的,如下是VXLAN設備處理ARP請求的代碼片段:

	n = neigh_lookup(&arp_tbl, &tip, dev);	//查找本地ARP表項

	if (n) {
		struct vxlan_fdb *f;
		struct sk_buff	*reply;

		......

		if (netif_rx_ni(reply) == NET_RX_DROP)	
			dev->stats.rx_dropped++;
	} else if (vxlan->flags & VXLAN_F_L3MISS) {
		union vxlan_addr ipa = {
			.sin.sin_addr.s_addr = tip,
			.sin.sin_family = AF_INET,
		};

		vxlan_ip_miss(dev, &ipa);
	}

如下代碼是VXLAN設備封裝外層IP頭時,獲取目的IP的代碼片段:

	f = vxlan_find_mac(vxlan, eth->h_dest);  //以目的mac查找FDB表
	did_rsc = false;

	if (f && (f->flags & NTF_ROUTER) && (vxlan->flags & VXLAN_F_RSC) &&
	    (ntohs(eth->h_proto) == ETH_P_IP ||
	     ntohs(eth->h_proto) == ETH_P_IPV6)) {
		did_rsc = route_shortcircuit(dev, skb);
		if (did_rsc)
			f = vxlan_find_mac(vxlan, eth->h_dest);
	}

	if (f == NULL) {
		f = vxlan_find_mac(vxlan, all_zeros_mac);  //以全零mac查找FDB表
		if (f == NULL) {
			if ((vxlan->flags & VXLAN_F_L2MISS) &&
			    !is_multicast_ether_addr(eth->h_dest))
				vxlan_fdb_miss(vxlan, eth->h_dest);	    //上報L2MISS

			dev->stats.tx_dropped++;
			kfree_skb(skb);
			return NETDEV_TX_OK;
		}
	}

Flannel VXLAN舊版方案總結

  • 採用L2MISS和L3MISS機制,首包將會被丟棄,嚴重影響首包的延時
  • L2MISS和L3MISS採用network link機制,性能低
  • 容器爲大二層網絡,不支持多個網絡
  • 對節點網絡無依賴(已經被封裝到節點網絡)
  • 僅需要一個vtep設備,通過FDB表確定目標vtep設備
  • 每個容器有一條ARP記錄,大規模時節點上的ARP表項過多
  • FDB記錄數與容器數量成正比,大規模時節點上的FDB表項過多

Flannel VXLAN新版方案

Flannel VXLAN新版數據面如下:
在這裏插入圖片描述

同節點容器通信

容器A訪問容器B,數據面流程如下(同Flannel UDP):

  1. 容器A和容器B在相同網絡,直接發送
  2. 容器A向容器B發送ARP請求,br0交換機flood該ARP請求
  3. 容器B接收到ARP請求,並響應
  4. br0交換機flood該ARP響應
  5. 容器A接收到ARP響應,封裝二層報文併發出
  6. br0交換機直接轉發報文到容器B
  7. 容器B接收到報文

跨節點容器通信

容器A訪問容器D,數據面流程如下:

  1. 容器A和容器D在不同網絡,通過網關轉發
  2. 容器A發送ARP請求給網關(10.10.1.1)
  3. 節點1內核響應ARP請求,併發送到br0接口
  4. br0交換機轉發ARP響應給容器A
  5. 容器A收到ARP請求,封裝二層報文(目的MAC爲網關的MAC),併發出報文
  6. br0交換機轉發報文給br0接口,並進入到協議棧
  7. Host1內核查找路由表,需要10.10.2.0轉發,並且是通過vtep0設備
  8. Host1內核查找ARP表項,發現了10.10.2.0的MAC表項,直接封裝二層報文,併發送到vtep0設備
  9. vtep0設備查找FDB表,發現10.10.2.0MAC的表項
  10. vtep0封裝外層vxlan頭,udp頭,ip頭,mac頭(由於節點在同一個網絡,mac可以通過ARP請求獲取)
  11. vtep0發送報文
  12. Host2接收到報文,通過UDP Socket,並進入到VXLAN解包處理,最終以vtep0收包並進入到協議棧
  13. Host2內核查找路由表,發現通過br0可以直接到達
  14. Host2內核發送ARP請求給容器D,併發送給br0接口
  15. br0交換機轉發ARP請求給容器D,容器D響應ARP請求,ARP響應通過br0接口上送到協議棧
  16. Host2收到ARP響應,修改報文的二層頭,併發送到br0接口
  17. br0交換機轉發報文給容器D
  18. 容器D接收到報文

其中目的vtep設備的MAC地址,FDB表項都需要flanneld來預置

Flannel VXLAN新版方案總結

  • 每個節點分配一個網絡CIDR
  • 不支持創建容器時指定IP地址
  • 節點的路由表數量較少,和節點數成正比
  • 對節點網絡無依賴(已經被封裝到節點網絡)
  • 每個節點僅需要一個vtep設備,通過FDB表確定目標vtep設備
發佈了92 篇原創文章 · 獲贊 7 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章