之前整理總結過有關flannel的相關原理以及詳細的傳輸過程,一直都想總結一篇通俗易懂的有關calico的相關原理和傳輸過程的,因為平常事情較多,沒想到一拖就是這麼久,這回藉著複習的機會,將calico的原理,傳輸過程,以及各元件的作用還有兩種模式的對比進行了細緻的講解和分析對比,也是對自己之前學習的一個總結,希望對大家有幫助。
什麼是Calico:
Calico是一個基於BGP的純三層網路方案,其會為每個容器(pod)分配一個可路由的IP,在通訊時不需要解包和拆包,因此網路效能損耗小,易於排查和水平擴充套件。Calico網路功能強大,可以與istio整合。Calico IPIP模式與Vxlan類似,也是透過網路隧道技術實現的,與Vxlan的差別就是,VXLAN本質上本質上是一個UDP包,而IPIP則將包封裝在本身的報文包上。它其實是利用了Linux 的tun/tap裝置,對IP層的報文再加了一層IP層的封裝實現的一種overlay模式。因為IPIP模式比BGP模式多了一層封包與拆包,所以效能會有所損耗。既然如此,為什麼不直接使用BGP模式就行了呢?因為BGP模式是需要透過路由廣播交換容器網路的路由資訊,而路由廣播只能在區域網中進行,在BGP模式下,如果kubernetes叢集中的工作節點不在同一個子網,則跨子網的工作節點上的POD無法正常通訊,下面就來詳細講解calico的這兩種網路模式的原理以及他們各自的優缺點和適用場景
Calico的兩種模式:
ipip模式:
Calico 的ipip模式是適用於node節點處於不同網段之間的pod的通訊模式,也就是pod節點所在的node節點不在同一個二層網路中,在VXLAN中的報頭裡VNI標記不同
BGP模式:
Calico 的BGP模式是適用於node節點處於相同網段之間的pod的通訊模式,是把每個node節點都當成是路由器的一種模式(將節點之間的路由規則配置在node節點上),每個node節點都維護著到其他節點的路由轉發表(由felix進行維護,BIRD將路由表向其他節點進行廣播和轉發)
Calico 網路模型的設計思路:
相同網段轉發原理(BGP模式):
我們看圖中的兩臺物理機。它們的物理網路卡是同一個二層網路裡面的。由於兩臺物理機的容器網段不同,我們完全可以將兩臺物理機配置成為路由器,並按照容器的網段配置路由表。
例如,在物理機 A 中,我們可以這樣配置:要想訪問網段 172.17.9.0/24,下一跳是 192.168.100.101,也即到物理機 B 上去。
這樣在容器 A 中訪問容器 B,當包到達物理機 A 的時候,就能夠匹配到這條路由規則,並將包發給下一跳的路由器,也即發給物理機 B。在物理機 B 上也有路由規則,要訪問 172.17.9.0/24,從 docker0 的網路卡進去即可。
當容器 B 返回結果的時候,在物理機 B 上,可以做類似的配置:要想訪問網段 172.17.8.0/24,下一跳是 192.168.100.100,也即到物理機 A 上去。
不同網段轉發原理(IPIP模式):
跨網段訪問問題
上面的 Calico 模式還有一個問題,就是跨網段問題,這裡的跨網段是指物理機跨網段。
前面我們說的那些邏輯成立的條件,是我們假設物理機可以作為路由器進行使用。例如物理機 A 要告訴物理機 B,你要訪問 172.17.8.0/24,下一跳是我 192.168.100.100;同理,物理機 B 要告訴物理機 A,你要訪問 172.17.9.0/24,下一跳是我 192.168.100.101。
之所以能夠這樣,是因為物理機 A 和物理機 B 是同一個網段的,是連線在同一個交換機上的。那如果物理機 A 和物理機 B 不是在同一個網段呢?
例如,物理機 A 的網段是 192.168.100.100/24,物理機 B 的網段是 192.168.200.101/24,這樣兩臺機器就不能透過二層交換機連線起來了,需要在中間放一臺路由器,做一次路由轉發,才能跨網段訪問。
本來物理機 A 要告訴物理機 B,你要訪問 172.17.8.0/24,下一跳是我 192.168.100.100 的,但是中間多了一臺路由器,下一跳不是我了,而是中間的這臺路由器了,這臺路由器的再下一跳,才是我。這樣之前的邏輯就不成立了。
我們看剛才那張圖的下半部分。物理機 B 上的容器要訪問物理機 A 上的容器,第一跳就是物理機 B,IP 為 192.168.200.101,第二跳是中間的物理路由器右面的網口,IP 為 192.168.200.1,第三跳才是物理機 A,IP 為 192.168.100.100。
這是咱們透過拓撲圖看到的,關鍵問題是,在系統中物理機 A 如何告訴物理機 B,怎麼讓它才能到我這裡?物理機 A 根本不可能知道從物理機 B 出來之後的下一跳是誰,況且現在只是中間隔著一個路由器這種簡單的情況,如果隔著多個路由器呢?誰能把這一串的路徑告訴物理機 B 呢?
我們能想到的第一種方式是,讓中間所有的路由器都來適配 Calico。本來它們互相告知路由,只互相告知物理機的,現在還要告知容器的網段。這在大部分情況下,是不可能的。
第二種方式,還是在物理機 A 和物理機 B 之間打一個隧道,這個隧道有兩個端點,在端點上進行封裝,將容器的 IP 作為乘客協議放在隧道里面,而物理主機的 IP 放在外面作為承載協議。這樣不管外層的 IP 透過傳統的物理網路,走多少跳到達目標物理機,從隧道兩端看起來,物理機 A 的下一跳就是物理機 B,這樣前面的邏輯才能成立。
calico架構圖:
BGP模式下各元件的作用:
Felix作用:Calico Agent,執行在每一臺 Host 的 agent 程序,主要負責網路介面管理和監聽、路由、ARP 管理、ACL 管理和同步、狀態上報等,保證跨主機容器的網路互通。
BGP Client(BIRD)作用:在 Calico 的角色是監聽 Host 上由 Felix 注入的路由資訊,然後透過 BGP 協議廣播告訴剩餘 Host 節點,從而實現網路互通。
BGP Route Reflector:在大型網路規模中,如果僅僅使用 BGP client 形成 mesh 全網互聯的方案就會導致規模限制,因為所有節點之間倆倆互聯,需要 N^2 個連線,為了解決這個規模問題,可以採用 BGP 的 Router Reflector 的方法,使所有 BGP Client 僅與特定 RR 節點互聯並做路由同步,從而大大減少連線數。
Calico BGP模式的優點:CalicoBGP模式是一種純三層的實現,因此可以避免與二層方案相關的資料包封裝的操作,中間沒有任何的NAT,沒有任何的overlay,所以它的轉發效率可能是所有方案中最高的,因為它的包直接走原生TCP/IP的協議棧,它的隔離也因為這個棧而變得好做。因為TCP/IP的協議棧提供了一整套的防火牆的規則,所以它可以透過IPTABLES的規則達到比較複雜的隔離邏輯。
二層網路通訊需要依賴廣播訊息機制,廣播訊息的開銷與 host 的數量呈指數級增長,Calico 使用的三層路由方法,則完全抑制了二層廣播,減少了資源開銷。
另外,二層網路使用 VLAN 隔離技術,天生有 4096 個規格限制,即便可以使用 vxlan 解決,但 vxlan 又帶來了隧道開銷的新問題。而 Calico 不使用 vlan 或 vxlan 技術,使資源利用率更高。
IPIP模式資料包傳輸流程:
測試環境:
一個msater節點,ip 172.171.5.95,一個node節點 ip 172.171.5.96 :
建立一個daemonset的應用,pod1落在master節點上 ip地址為192.168.236.3,pod2落在node節點上 ip地址為192.168.190.203:
pod1 ping pod2:
資料包傳輸的具體流程如下:
pod1上的路由資訊:
根據路由資訊,ping 192.168.190.203,會匹配到第一條。第一條路由的意思是:去往任何網段的資料包都發往網管169.254.1.1,然後從eth0網路卡傳送出去。
路由表中Flags標誌的含義:
U up表示當前為啟動狀態
H host表示該路由為一個主機,多為達到資料包的路由
G Gateway 表示該路由是一個閘道器,如果沒有說明目的地是直連的
D Dynamicaly 表示該路由是重定向報文修改
M 表示該路由已被重定向報文修改
master節點上的路由資訊:
當ping包來到master節點上,會匹配到路由tunl0。該路由的意思是:去往192.169.190.192/26的網段的資料包都發往閘道器172.171.5.96。因為pod1在5.95,pod2在5.96。所以資料包就透過裝置tunl0發往到node節點上。
node節點上路由資訊:
當node節點網路卡收到資料包之後,發現發往的目的ip為192.168.190.203,於是匹配到紅線的路由。該路由的意思是:192.168.190.203是本機直連裝置,去往裝置的資料包發往caliadce112d250。
那麼該裝置是什麼呢?如果到這裡你能猜出來是什麼,那說明你的網路功底是不錯的。這個裝置就是veth pair的一端。在建立pod2時calico會給pod2建立一個veth pair裝置。一端是pod2的網路卡,另一端就是我們看到的caliadce112d250。下面我們驗證一下。在pod2中安裝ethtool工具,然後使用ethtool -S eth0,檢視veth pair另一端的裝置號。
pod2 網路卡另一端的裝置好號是18,在node上檢視編號為18的網路裝置,可以發現該網路裝置就是caliadce112d250。
所以,node上的路由,傳送caliadce112d250的資料其實就是傳送到pod2的網路卡中。ping包的旅行到這裡就到了目的地。
檢視一下pod2中的路由資訊,發現該路由資訊和pod1中是一樣的。
顧名思義,IPIP網路就是將IP網路封裝在IP網路裡。IPIP網路的特點是所有pod的資料流量都從隧道tunl0傳送,並且在tunl0這增加了一層傳輸層的封包。
在master網路卡上抓包分析該過程:
開啟ICMP 285,pod1 ping pod2的資料包,能夠看到該資料包一共5層,其中IP所在的網路層有兩個,分別是pod之間的網路和主機之間的網路封裝:
根據資料包的封裝順序,應該是在pod1 ping pod2的ICMP包外面多封裝了一層主機之間的資料包:
之所以要這樣做是因為tunl0是一個隧道端點裝置,在資料到達時要加上一層封裝,便於傳送到對端隧道裝置中。
兩層IP封裝的具體內容:
BGP模式資料包傳輸流程:
測試環境:
在安裝calico網路時,預設安裝是IPIP網路。calico.yaml檔案中,將CALICO_IPV4POOL_IPIP的值修改成 "off",就能夠替換成BGP網路。
BGP網路相比較IPIP網路,最大的不同之處就是沒有了隧道裝置 tunl0。 前面介紹過IPIP網路pod之間的流量傳送tunl0,然後tunl0傳送對端裝置。BGP網路中,pod之間的流量直接從網路卡傳送目的地,減少了tunl0這個環節。
master節點上路由資訊。從路由資訊來看,沒有tunl0裝置。
同樣建立一個daemonset,pod1在master節點上,pod2在node節點上。
資料包傳輸的具體流程如下:
pod1 ping pod2。
根據pod1中的路由資訊,ping包透過eth0網路卡傳送到master節點上。
master節點上路由資訊。根據匹配到的 192.168.190.192 路由,該路由的意思是:去往網段192.168.190.192/26 的資料包,傳送網段172.171.5.96。而5.96就是node節點。所以,該資料包直接傳送了5.96節點。
node節點上的路由資訊。根據匹配到的192.168.190.192的路由,資料將傳送給 cali6fcd7d1702e裝置,該裝置和上面分析的是一樣,為pod2的veth pair 的一端。資料就直接傳送給pod2的網路卡。
當pod2對ping包做出回應之後,資料到達node節點上,匹配到192.168.236.0的路由,該路由說的是:去往網段192.168.236.0/26 的資料,傳送給閘道器 172.171.5.95。資料包就直接透過網路卡ens160,傳送到master節點上。
透過在master節點上抓包,檢視經過的流量,篩選出ICMP,找到pod1 ping pod2的資料包。
可以看到BGP網路下,沒有使用IPIP模式,資料包是正常的封裝。
值得注意的是mac地址的封裝。192.168.236.0是pod1的ip,192.168.190.198是pod2的ip。而源mac地址是 master節點網路卡的mac,目的mac是node節點的網路卡的mac。這說明,在 master節點的路由接收到資料,重新構建資料包時,使用arp請求,將node節點的mac拿到,然後封裝到資料鏈路層。
兩種模式的對比:
區別主要有兩個:
1.BGP模式適用於同網段之間node節點上的不同Pod的通訊,而IPIP模式適用於不同網段之間的通訊
2.BGP模式將容器所在節點化身為路由器(vRouter),提供了路由的功能,並透過BGP協議將路由規則進行分發,再透過路由器上的路由規則,將包轉發到目的地。在這個過程中,沒有IPIP模式隧道的封包解包,僅僅是單純的路由轉發,效能會好很多。