Flannel和Calico網路外掛工作流程對比

vfanCloud發表於2021-02-26
Flannel和Calico網路外掛對比
 
Calico簡介
Calico是一個純三層的網路外掛,calico的bgp模式類似於flannel的host-gw
Calico方便整合 OpenStack這種 IaaS雲架構,為openstack虛擬機器、容器、裸機提供多主機間通訊。
 
calico 架構

calico包括如下重要元件:Felix,etcd,BGP Client,BGP Route Reflector。下面分別說明一下這些元件:
  • Felix:主要負責路由配置以及ACLS規則的配置以及下發,它存在在每個node節點上。
  • etcd:分散式鍵值儲存,主要負責網路後設資料一致性,確保Calico網路狀態的準確性,可以與kubernetes共用;
  • BGPClient(BIRD), 主要負責把 Felix寫入 kernel的路由資訊分發到當前 Calico網路,確保 workload間的通訊的有效性;
  • BGPRoute Reflector(BIRD), 大規模部署時使用,摒棄所有節點互聯的mesh模式,通過一個或者多個 BGPRoute Reflector 來完成集中式的路由分發;

 

 
calico 原理
calico是一個純三層的虛擬網路,它沒有複用docker的docker0網橋,而是自己實現的, calico網路不對資料包進行額外封裝,不需要NAT和埠對映,擴充套件性和效能都很好。Calico網路提供了DockerDNS服務, 容器之間可以通過hostname訪問,Calico在每一個計算節點利用Linux Kernel實現了一個高效的vRouter(虛擬路由)來負責資料轉發,它會為每個容器分配一個ip,每個節點都是路由,把不同host的容器連線起來,從而實現跨主機間容器通訊。而每個vRouter通過BGP協議(邊界閘道器協議)負責把自己節點的路由資訊向整個Calico網路內傳播——小規模部署可以直接互聯,大規模下可通過指定的BGProute reflector來完成;Calico基於iptables還提供了豐富而靈活的網路策略,保證通過各個節點上的ACLs來提供多租戶隔離、安全組以及其他可達性限制等功能。
 
calico網路模式
1、ipip模式
把一個IP資料包又套在一個IP包裡,即把IP層封裝到IP層的一個 tunnel,它的作用其實基本上就相當於一個基於IP層的網橋,一般來說,普通的網橋是基於mac層的,根本不需要IP,而這個ipip則是通過兩端的路由做一個tunnel,把兩個本來不通的網路通過點對點連線起來;

 
calico以ipip模式部署完畢後,node上會有一個tunl0的網路卡裝置,這是ipip做隧道封裝用的,也是一種overlay模式的網路。當我們把節點下線,calico容器都停止後,這個裝置依然還在,執行 probe -r ipip 命令可以將它刪除。

9: tunl0@NONE: <NOARP,UP,LOWER_UP> mtu 1440 qdisc noqueue state UNKNOWN qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
    inet 10.233.110.0/32 brd 10.233.110.0 scope global tunl0
       valid_lft forever preferred_lft forever

 

官方提供的calico.yaml模板裡,預設開啟了ip-ip功能,該功能會在node上建立一個裝置tunl0,容器的網路資料會經過該裝置被封裝一個ip頭再轉發。這裡,calico.yaml中通過修改calico-node的環境變數:CALICO_IPV4POOL_IPIP來實現ipip功能的開關:預設是Always,表示開啟;Off表示關閉ipip。

# kubectl get daemonsets. calico-node -n kube-system -o yaml | grep -iA 1 ipip
        - name: CALICO_IPV4POOL_IPIP
          value: "Always"

 

補充:
Linux支援的五種ip隧道,可以通過ip tunnel help檢視

[root@yq01-aip-aikefu06e1a866 ~]# ip tunnel help
Usage: ip tunnel { add | change | del | show | prl | 6rd } [ NAME ]
          [ mode { ipip | gre | sit | isatap | vti } ] [ remote ADDR ] [ local ADDR ]
  • ipip:即 IPv4 in IPv4,在 IPv4 報文的基礎上再封裝一個 IPv4 報文。
  • gre:即通用路由封裝(Generic Routing Encapsulation),定義了在任意一種網路層協議上封裝其他任意一種網路層協議的機制,IPv4 和 IPv6 都適用。
  • sit:和 ipip 類似,不同的是 sit 是用 IPv4 報文封裝 IPv6 報文,即 IPv6 over IPv4。
  • isatap:即站內自動隧道定址協議(Intra-Site Automatic Tunnel Addressing Protocol),和 sit 類似,也是用於 IPv6 的隧道封裝。
  • vti:即虛擬隧道介面(Virtual Tunnel Interface),是 cisco 提出的一種 IPsec 隧道技術。

2、BGP模式
邊界閘道器協議(BorderGateway Protocol, BGP)是網際網路上一個核心的去中心化的自治路由協議。它通過維護IP路由表或‘字首’表來實現自治系統(AS)之間的可達性,屬於向量路由協議。BGP不使用傳統的內部閘道器協議(IGP)的指標,而是基於路徑、網路策略或規則集來決定路由。因此,它更適合被稱為向量性協議,而不是路由協議,通俗的說就是將接入到機房的多條線路(如電信、聯通、移動等)融合為一體,實現多線單IP;
BGP 機房的優點:伺服器只需要設定一個IP地址,最佳訪問路由是由網路上的骨幹路由器根據路由跳數與其它技術指標來確定的,不會佔用伺服器的任何系統。
 
Flannel
flannel 架構

flannel的udp模式和vxlan模式都是屬於隧道方式,也就是在udp的基礎之上,構建虛擬網路,然後通過一個封包解包的過程來實現資料的傳輸。

 

flannel的幾種模式
    flannel通過在每一個節點上啟動一個叫flannel的程式,負責為每一個節點上的子網劃分,並將相關配置資訊(如各節點的子網網段、外部IP等)儲存到etcd中,而具體的網路報文轉發交給backend實現。
    flanneld可以在啟動時通過配置檔案指定不同的backend進行網路通訊,目前比較 成熟的backend有UDP、VXLAN和host-gateway三種。目前,VXLAN是官方比較推崇的一種backend實現方式。
    UDP模式和VXLAN模式基於三層網路層即可實現,而host-gateway模式就必須要求叢集所有機器在同一個廣播域,也就是需要在二層網路同一個交換機下才能實現。
    host-gateway一般用於對網路效能要求比較高的場景,但需要基礎網路架構的支援;UDP則用於測試及一般比較老的不支援VXLAN的Linux核心。
 
1、UDP模式
採用UDP模式時,需要在flanneld的配置檔案中指定Backend.Type為UDP,可通過直接修改flanneld的ConfigMap的方式實現。

# kubectl get cm kube-flannel-cfg -n kube-system -o yaml
 kubectl
   net-conf.json: |
    {
      "Network": "10.233.64.0/18",
      "Backend": {
        "Type": "udp"
      }
    }
通過ip addr 命令可以發現節點上會多出一個flannel 0的網路介面,在UDP模式中,flanneld的主要作用為:
(1)UDP包封包解包
(2)節點上路由表的動態更新

 
工作流程圖:

熟悉Linux的應該知道,Linux頻繁核心態-使用者態的切換,會造成頻繁的上下文切換,會引發效能問題,所以從上面可以看到container的資料包,從離開src container後,經過了多次核心態-使用者態的切換,並且,資料包是由使用者態的flannel進行進行封包/解包的,從而導致了比較大的效能損耗,這也是為什麼生產基本不會用這個方案,因為效能實在非常差。

 

2、VXLAN模式
同樣需要在Backend.Type修改為VXLAN

net-conf.json: |
    {
      "Network": "10.233.64.0/18",
      "Backend": {
        "Type": "vxlan"
      }
    }
VXLAN模式下,會建立一個名為flannel 1的VTEP裝置,資料的轉發由核心完成,並不是flanned,flanned僅動態設定ARP和FDB表項

 

流程圖:

vxlan本身就是核心特性,使用vxlan會在伺服器中建立一個vtep裝置(flannel 1),裝置的封包/解包操作都在該裝置下操作,所以直接在核心態操作,不需要CPU上下文切換,且和UDP直接三層封包不一樣,vxlan是直接對二層資料幀進行封包。

 
3、host-gateway模式
同上需要在Backend.Type修改為host-gw。
由於host-gw是純路由模式,flannel需要通過etcd維護所有的靜態路由,核心是IP包在封裝成楨的時候,使用路由表的"下一跳"設定上的MAC地址,這樣可以經過二層網路到達目的宿主機。這就要求所有的伺服器在同一個二層網路下,這就使host-gw模式無法適用於叢集規模較大且需要對節點進行網段劃分的場景。
host-gw另外一個限制則是隨著叢集中節點規模的增大,flanneld維護主機上成千上萬條路由表的動態更新也是一個不小的壓力,因此在路由方式下,路由表規則的數量是限制網路規模的一個重要因素。
 
流程圖:

在效能上,host-gw由於沒有封包/解包,故效能最好

相關文章