天天看點

二三層轉發原理及過程_容器網絡 calico 基本原理和模拟

摘要

在容器網絡跨 Host 互聯方案中,除了 Flannel 的隧道實作方案,還有一種比較主流的純三層路由的方案 Calico ,與 Flannel 不同的是 Calico 不使用隧道或 NAT 來實作轉發,而是巧妙的把所有二三層流量轉換成三層流量,并通過 host 上路由配置完成跨 Host 轉發,本文對 Calico 的方案進行基本原理分析和模拟驗證。

簡介

Calico 官方定義如下:

Calico provides secure network connectivity for containers and virtual machine workloads.

Calico creates and manages a flat layer 3 network, assigning each workload a fully routable IP address. Workloads can communicate without IP encapsulation or network address translation for bare metal performance, easier troubleshooting, and better interoperability. In environments that require an overlay, Calico uses IP-in-IP tunneling or can work with other overlay networking such as flannel.

Calico also provides dynamic enforcement of network security rules. Using Calico’s simple policy language, you can achieve fine-grained control over communications between containers, virtual machine workloads, and bare metal host endpoints.

總結如下:

Calico 為容器和 vm 等提供一個安全的網路互聯方法,我們把 VM、Container、白盒等執行個體統稱為 workloads,通過給 workload 配置設定一個扁平的三層路由可達 IP 位址實作轉發,是一種純三層轉發的方案,workload 之間不使用隧道或 NAT 技術,這種方式提供更好的網絡性能,提高易維護和可互動性。同時也支援 IPIP 隧道和與 Flannel 內建能力。Calico 提供動态實施的網絡安全政策,可使用簡單的安全模型語言實作細粒度的安全控制。

相對 Overlay,為什麼用 Calico?

Calico 有一篇官方 博文 說明,總結如下:

Calico 是一種 workloads 之間互通的網絡方案,并支援以上任意一種場景。在虛拟化平台中,比如 OpenStack、Docker 等都需要實作 workloads 之間互連,但同時也需要對 workloads 做隔離控制,就像在 Internet 中的服務僅開放80端口、公有雲的多租戶一樣,提供隔離和管控機制。

而在多數的虛拟化平台實作中,通常都使用二層隔離技術來實作 workloads 的網絡,這些二層的技術有一些弊端,比如需要依賴 VLAN、bridge 和隧道等技術,其中 bridge 帶來了複雜性,vlan 隔離和 tunnel 隧道則消耗更多的資源并對實體環境有要求,随着網絡規模的增大,整體會變得越加複雜。

那麼有更好的方案嗎?我們在審視了二層方案并思考如何支援大型網絡時從 Internet 網絡實作中獲得了靈感。我們知道在 Internet 的網絡中,路由器作為網關連接配接着自己的子網絡,之間通過 BGP 互相學習,并使用防火牆控制不同子網之間安全政策,所有這些子網絡共同組成了 Internet 網絡,那麼,這種方式能否也應用到虛拟化基礎平台中呢?

借鑒這種思路,我們嘗試把 Host 當作 Internet 中的路由器,同樣使用 BGP 同步路由,并使用 iptables 來做安全通路政策,最終設計出了 Calico 方案,整個方案的優勢為:

  1. 更優的資源利用

二層網絡通訊需要依賴廣播消息機制,廣播消息的開銷與 host 的數量呈指數級增長,Calico 使用的三層路由方法,則完全抑制了二層廣播,減少了資源開銷。

另外,二層網絡使用 VLAN 隔離技術,天生有 4096 個規格限制,即便可以使用 vxlan 解決,但 vxlan 又帶來了隧道開銷的新問題。而 Calico 不使用 vlan 或 vxlan 技術,使資源使用率更高。

  1. 可擴充性

Calico 使用與 Internet 類似的方案,Internet 的網絡比任何資料中心都大,Calico 同樣天然具有可擴充性。

  1. 簡單而更容易 debug

因為沒有隧道,意味着 workloads 之間路徑更短更簡單,配置更少,在 host 上更容易進行 debug 調試。

  1. 更少的依賴

Calico 僅依賴三層路由可達。

  1. 可适配性

Calico 較少的依賴性使它能适配所有 VM、Container、白盒或者混合環境場景。

除了以上,還有更多其他優勢,是以,如果你在為 OpenStack 或 docker 建構虛拟化網絡環境的話,可以好好考慮下 Calico 的方案。

架構

Calico 由 5 部分元件組成,整體構架如下:

二三層轉發原理及過程_容器網絡 calico 基本原理和模拟
  1. Felix:運作在每一台 Host 的 agent 程序,主要負責網絡接口管理和監聽、路由、ARP 管理、ACL 管理和同步、狀态上報等
  2. Orchestrator Plugin:編排插件,并不是獨立運作的某些程序,而是設計與 k8s、OpenStack 等平台內建的插件,如 Neutron’s ML2 plugin 用于使用者使用 Neutron API 來管理 Calico,本質是要解決模型和 API 間的相容性問題。
  3. Etcd:Calico 模型的存儲引擎。
  4. BGP Client(BIRD):Calico 為每一台 Host 部署一個 BGP Client,使用 BIRD 實作,BIRD 是一個單獨的持續發展的項目,實作了衆多動态路由協定比如 BGP、OSPF、RIP 等。在 Calico 的角色是監聽 Host 上由 Felix 注入的路由資訊,然後通過 BGP 協定廣播告訴剩餘 Host 節點,進而實作網絡互通。
  5. BGP Route Reflector(BIRD):在大型網絡規模中,如果僅僅使用 BGP client 形成 mesh 全網互聯的方案就會導緻規模限制,因為所有節點之間倆倆互聯,需要 N^2 個連接配接,為了解決這個規模問題,可以采用 BGP 的 Router Reflector 的方法,使所有 BGP Client 僅與特定 RR 節點互聯并做路由同步,進而大大減少連接配接數。

模拟組網

組網如下:

二三層轉發原理及過程_容器網絡 calico 基本原理和模拟
  1. guest 配置 169.254.1.1 的預設路由
  2. host 上配置 10.20.2.0/24 和 10.20.1.3/32 路由
  3. 開啟 arp proxy 和 ip_forward 能力

網絡連通性測試:

# HOST0[[email protected] ~]# ip netns exec ns0 ping 10.20.2.2PING 10.20.2.2 (10.20.2.2) 56(84) bytes of data. bytes from 10.20.2.2: icmp_seq=1 ttl=62 time=0.774 ms bytes from 10.20.2.2: icmp_seq=2 ttl=62 time=0.332 ms
           

10.20.1.2 與跨 Host 跨子網 10.20.2.2 互通成功

# HOST0[[email protected] ~]# ip netns exec ns0 ping 10.20.1.3PING 10.20.1.3 (10.20.1.3) 56(84) bytes of data. bytes from 10.20.1.3: icmp_seq=1 ttl=62 time=957 ms bytes from 10.20.1.3: icmp_seq=2 ttl=62 time=0.432 ms bytes from 10.20.1.3: icmp_seq=3 ttl=62 time=0.563 ms
           

10.20.1.2 與跨 Host 同子網 10.20.1.3 互通成功

[[email protected] ~]# ip netns exec ns0 ping 192.168.100.3PING 192.168.100.3 (192.168.100.3) 56(84) bytes of data. bytes from 192.168.100.3: icmp_seq=1 ttl=63 time=1.00 ms bytes from 192.168.100.3: icmp_seq=2 ttl=63 time=0.695 ms
           

在未做安全政策下,10.20.1.2 與 Host 192.168.100.3 互通成功

轉發過程:

  1. guest0 本地所有資料包都轉發到一個虛假的位址 169.254.1.1,發送 ARP Req。
  2. Host0 的 veth 端收到 ARP Req 時通過開啟網卡的 proxy arp 代理功能直接把自己的 MAC 位址傳回給 guest0
  3. guest0 發送目的位址為 guest1 的 IP 資料包
  4. 因為使用了 169.254.1.1 這樣的位址,Host 判斷為三層路由轉發,查詢本地路由 10.20.2.0/24 via 192.168.0.3 dev eth0 發送給對端 host1,如果配置 BGP,這裡會看到 proto 協定為 BIRD
  5. 在發送之前比對本地的 iptables 規則進行安全政策控制,這裡略
  6. 當 host1 收到 10.20.2.2 的資料包時查找本地路由表比對 10.20.2.2/32 dev veth0 scope link 轉發到對應的 veth0 端進而到達 guest1
  7. 回程類似,略

整體轉發流程簡單清晰。是以可以看到,Calico 需要給所有 guest 配置一條特别的路由并利用 veth 的 proxy arp 的能力讓 guest 出來的所有轉發都變成三層路由轉發,再利用 host 的路由表進行轉發,這種方式不僅僅實作了同 host 的二三層轉發,也能實作跨 host 的轉發。

遺留問題

  1. 租戶隔離問題
  2. Calico 的三層方案是直接在 host 上進行路由尋址,那麼對于多租戶如果使用同一個 CIDR 網絡就面臨着位址沖突的問題。
  3. 路由規模問題
  4. 通過路由規則可以看出,路由規模和 guest 分布有關,如果 guest 離散分布在 host 叢集中,勢必會産生較多的路由項。
  5. iptables 規則規模問題
  6. 1台 Host 上可能虛拟化十幾或幾十個容器執行個體,過多的 iptables 規則造成複雜性和不可調試性,同時也存在性能損耗。
  7. 跨子網時的網關路由問題
  8. 當對端網絡不為二層可達時,需要通過三層路由機時,需要網關支援自定義路由配置,即 guest 的目的位址為本網段的網關位址,再由網關進行跨三層轉發。

總結

  1. Calico 通過巧妙的引導 workload 所有的流量至一個特殊的網關 169.254.1.1,進而引流到 host 的 calixxx 網絡裝置上,形成了二三層流量全部轉換 host 的三層流量轉發。
  2. 在 Host 上通過開啟 arp proxy 的能力實作 arp 代答,arp 廣播被抑制在 host 裡,arp 記錄變成“無效記錄”,抑制了廣播風暴和不會有 arp 表膨脹的問題。
  3. 使用 iptables 在 host 做 policy 實作的複雜的安全模型,安全政策應用在每一台虛拟路由器上,最終形成了一個分布式的安全系統。