一、Calico基本介紹
Calico是一個純三層的協議,為OpenStack虛機和Docker容器提供多主機間通信。Calico不使用重疊網絡比如flannel和libnetwork重疊網絡驅動,它是一個純三層的方法,使用虛擬路由代替虛擬交換,每一台虛擬路由通過BGP協議傳播可達信息(路由)到剩余數據中心。
二、Calico結構組成
Calico不使用重疊網絡比如flannel和libnetwork重疊網絡驅動,它是一個純三層的方法,使用虛擬路由代替虛擬交換,每一台虛擬路由通過BGP協議傳播可達信息(路由)到剩余數據中心;Calico在每一個計算節點利用Linux Kernel實現了一個高效的vRouter來負責數據轉發,而每個vRouter通過BGP協議負責把自己上運行的workload的路由信息像整個Calico網絡內傳播——小規模部署可以直接互聯,大規模下可通過指定的BGP route reflector來完成。
結合上面這張圖,我們來過一遍 Calico 的核心組件:
Felix: Calico agent,跑在每台需要運行 workload 的節點上,主要負責配置路由及 ACLs 等信息來確保 endpoint 的連通狀態;
etcd: 分布式鍵值存儲,主要負責網絡元數據一致性,確保 Calico 網絡狀態的准確性;
BGPClient(BIRD): 主要負責把 Felix 寫入 kernel 的路由信息分發到當前 Calico 網絡,確保 workload 間的通信的有效性;
BGP Route Reflector(BIRD): 大規模部署時使用,摒棄所有節點互聯的 mesh 模式,通過一個或者多個BGP Route Reflector來完成集中式的路由分發;
通過將整個互聯網的可擴展 IP 網絡原則壓縮到數據中心級別,Calico 在每一個計算節點利用Linux kernel實現了一個高效的vRouter來負責數據轉發而每個vRouter通過BGP
協議負責把自己上運行的 workload 的路由信息像整個 Calico 網絡內傳播 - 小規模部署可以直接互聯,大規模下可通過指定的BGP route reflector 來完成。這樣保證最終所有的 workload 之間的數據流量都是通過 IP 包的方式完成互聯的。
三、Calico 工作原理
Calico把每個操作系統的協議棧認為是一個路由器,然后把所有的容器認為是連在這個路由器上的網絡終端,在路由器之間跑標准的路由協議——BGP的協議,然后讓它們自己去學習這個網絡拓撲該如何轉發。所以Calico方案其實是一個純三層的方案,也就是說讓每台機器的協議棧的三層去確保兩個容器,跨主機容器之間的三層連通性。
對於控制平面,它每個節點上會運行兩個主要的程序,一個是Felix,它會監聽ECTD中心的存儲,從它獲取事件,比如說用戶在這台機器上加了一個IP,或者是分配了一個容器等。接着會在這台機器上創建出一個容器,並將其網卡、IP、MAC都設置好,然后在內核的路由表里面寫一條,注明這個IP應該到這張網卡。綠色部分是一個標准的路由程序,它會從內核里面獲取哪一些IP的路由發生了變化,然后通過標准BGP的路由協議擴散到整個其他的宿主機上,讓外界都知道這個IP在這里,你們路由的時候得到這里來。
由於Calico是一種純三層的實現,因此可以避免與二層方案相關的數據包封裝的操作,中間沒有任何的NAT,沒有任何的overlay,所以它的轉發效率可能是所有方案中最高的,因為它的包直接走原生TCP/IP的協議棧,它的隔離也因為這個棧而變得好做。因為TCP/IP的協議棧提供了一整套的防火牆的規則,所以它可以通過IPTABLES的規則達到比較復雜的隔離邏輯。
四、Calico網絡方式(兩種)
IPIP
從字面來理解,就是把一個IP數據包又套在一個IP包里,即把 IP 層封裝到 IP 層的一個 tunnel,看起來似乎是浪費,實則不然。它的作用其實基本上就相當於一個基於IP層的網橋!一般來說,普通的網橋是基於mac層的,根本不需 IP,而這個 ipip 則是通過兩端的路由做一個 tunnel,把兩個本來不通的網絡通過點對點連接起來。ipip 的源代碼在內核 net/ipv4/ipip.c 中可以找到。
BGP
邊界網關協議(Border Gateway Protocol, BGP)是互聯網上一個核心的去中心化自治路由協議。它通過維護IP路由表或‘前綴’表來實現自治系統(AS)之間的可達性,屬於矢量路由協議。BGP不使用傳統的內部網關協議(IGP)的指標,而使用基於路徑、網絡策略或規則集來決定路由。因此,它更適合被稱為矢量性協議,而不是路由協議。BGP,通俗的講就是講接入到機房的多條線路(如電信、聯通、移動等)融合為一體,實現多線單IP,BGP 機房的優點:服務器只需要設置一個IP地址,最佳訪問路由是由網絡上的骨干路由器根據路由跳數與其它技術指標來確定的,不會占用服務器的任何系統。
五、Calico網絡通信模型
calico是純三層的SDN 實現,它基於BPG 協議和Linux自身的路由轉發機制,不依賴特殊硬件,容器通信也不依賴iptables NAT或Tunnel 等技術。
能夠方便的部署在物理服務器、虛擬機(如 OpenStack)或者容器環境下。同時calico自帶的基於iptables的ACL管理組件非常靈活,能夠滿足比較復雜的安全隔離需求。
在主機網絡拓撲的組織上,calico的理念與weave類似,都是在主機上啟動虛擬機路由器,將每個主機作為路由器使用,組成互聯互通的網絡拓撲。當安裝了calico的主機組成集群后,其拓撲如下圖所示:
每個主機上都部署了calico/node作為虛擬路由器,並且可以通過calico將宿主機組織成任意的拓撲集群。當集群中的容器需要與外界通信時,就可以通過BGP協議將網關物理路由器加入到集群中,使外界可以直接訪問容器IP,而不需要做任何NAT之類的復雜操作。
當容器通過calico進行跨主機通信時,其網絡通信模型如下圖所示:
從上圖可以看出,當容器創建時,calico為容器生成veth pair,一端作為容器網卡加入到容器的網絡命名空間,並設置IP和掩碼,一端直接暴露在宿主機上,並通過設置路由規則,將容器IP暴露到宿主機的通信路由上。於此同時,calico為每個主機分配了一段子網作為容器可分配的IP范圍,這樣就可以根據子網的CIDR為每個主機生成比較固定的路由規則。
當容器需要跨主機通信時,主要經過下面的簡單步驟:
容器流量通過veth pair到達宿主機的網絡命名空間上。
根據容器要訪問的IP所在的子網CIDR和主機上的路由規則,找到下一跳要到達的宿主機IP。
流量到達下一跳的宿主機后,根據當前宿主機上的路由規則,直接到達對端容器的veth pair插在宿主機的一端,最終進入容器。
從上面的通信過程來看,跨主機通信時,整個通信路徑完全沒有使用NAT或者UDP封裝,性能上的損耗確實比較低。但正式由於calico的通信機制是完全基於三層的,這種機制也帶來了一些缺陷,例如:
calico目前只支持TCP、UDP、ICMP、ICMPv6協議,如果使用其他四層協議(例如NetBIOS協議),建議使用weave、原生overlay等其他overlay網絡實現。
基於三層實現通信,在二層上沒有任何加密包裝,因此只能在私有的可靠網絡上使用。
流量隔離基於iptables實現,並且從etcd中獲取需要生成的隔離規則,有一些性能上的隱患。