計算規模驅動下的網路方案演進
本文其實是前一篇文章 邁入 Cilium+BGP 的雲原生網路時代 的鋪墊,二者合起來,是近期在公司所做的一次技術分享的內容。 拋磚引玉,希望可以引起大家一些思考。
1 引言
過去二十多年網路發生了很多的變化,比如,
- 資料中心物理拓撲方面,由接入-匯聚-核心三級網路架構演進到 Spine-Leaf 兩級架構;
- 軟體方面,出現了各種各樣的網路虛擬化,例如軟體實現的虛擬網橋、虛擬機器交換機、 虛擬路由器、軟體 overlay 網路等等;
- 另外還出現了很多新的概念和模型,例如軟體定義網路(SDN)的轉發與控制分離 思想,實現上可以像 Google 一樣基於 OpenFlow,可以是後來用的比較多的 BGP EVPN;另外還有 Spine-Leaf 中的分散式閘道器概念;還有大二層網路與純三層路 由網路等等概念。
Fig 1-1. Various network solutions over the past years
具體到一些我們所熟悉的計算平臺,
- 早起的 bare metal 叢集可能會採用 DHCP 加扁平二層(flat L2)網路,
- 虛擬機器時代 —— 比較有代表性的 OpenStack 平臺,採用的是 Neutron+OVS 大二層網路,
- Docker 內建的典型網路模型是宿主機內的 bridge 加出宿主機的 SNAT,並定義了 CNM 網路模型,
- Kubernetes 定義了 CNI 網路規範,符合這個規範的實現有我們現在所熟悉的 Flannel、Calico、Cilium 等等。
那麼,我們的一個問題是, 為什麼會有這麼多網路方案呢? 或者說,網路架構和解決 方案為什麼在不斷演進呢? 這其中當然有很多方面的原因 ,我們今天嘗試從 不斷增長的計算規模 來分析一下這個問題。
Fig 1-2. The ever-increasing compute endpoints' scale
這裡的計算資源基本單位可以是一臺 BM、VM,也可以是容器。相應的對應三個時代:
- 2000-2008 裸金屬時代:傳統計算模型。
- 2008-2016 虛擬機器時代:雲端計算興起。
- 2016- 容器時代:雲原生開篇。
2 裸金屬(BM)時代
2.1 平臺特點
Fig 2-1. Logical BM cluster topology and traffic patterns
如圖所示,BM 時期計算平臺的特點有:
- 計算資源沒有做虛擬化。
- 應用(applications)直接執行在物理伺服器上。
- 典型的 應用訪問模式 (application accessing pattern): 客戶端-伺服器 (client-server)模式。
- 南北向流量 (進出叢集的流量) 遠大於東西向流量 (叢集內應用互訪的的流量)。
2.2 網路需求
這種計算模型給網路提出的需求也很簡單:
首先,能夠比較高效地處理南北向流量;
第二,叢集內 應用之間的互訪 (東西向流量),也就是節點間的網路連通性,這與本文 討論的主題(計算例項規模)密切相關;
第三,在連通性的基礎上,要有必要的訪問控制和安全措施。例如可以基於硬體防火牆做網 段級別的控制、基於 iptables 做一些簡單的主機防火牆功能等等。這些內容不在本文 討論範圍。
2.3 網路解決方案
針對以上需求,業界設計了經典的 接入、匯聚、核心三級網路架構 ,如下圖所示:
Fig 2-2. Typical network solution for BM platforms
- 南北向流量在核心交換機處理。
- 所有內部子網的閘道器一般也配置在核心,因此叢集內跨網段需要經過核心交換機。
- 整張網路是一個 二層網路 ,也叫 橋接網路 或 交換網路 。
在這種模型中,由於節點/應用之間通訊都可能要經過核心,因此 核心交換機需要記錄所 有節點的 IP 和 MAC 地址資訊 。
2.4 網路瓶頸分析(計算規模相關)
在這種網路方案中, 與計算節點規模相關的瓶頸 最可能出現在核心交換機,因為要實現 任何兩臺之間節點之間可達,核心交換機需要佔用硬體表項(FIB TCAM)來記錄叢集內所有 主機的 IP/MAC 資訊。
Fig 2-3. Bottleneck analysis
我們來算一下。假設,
- 每個機房(或 POD)200 個機櫃
- 每個機櫃 10 臺伺服器
那可以算出整個機房有 2000 臺伺服器。假設每個 node 佔用一到兩個 IP 地址,核心交 換機將 佔用 2k~4k 條表項 。
假設使用的核心交換機有 16K 條表項,其中能用到 70% 左右(太高會導致雜湊衝突, 包只能交由交換機 CPU 軟體處理,導致 CPU 升高、丟包甚至宕機),因此 有效表項 是 11K 條 。
2K~4K
與 11K
相比可以得出結論:轉發表項非常充裕,核心交換機沒有表項瓶頸。
3 虛擬機器(VM)時代
2008 年以後,業界開始 對計算資源做大規模虛擬化 ,我們來到了雲端計算時代。
3.1 平臺特點
Fig 3-1. Logical VM cluster topology and traffic patterns
這一時期的特點:
- 將基礎設施作為服務(IaaS)交付給使用者,相應地,計算資源的基本單位也從物理機(BM)變成虛擬機器(VM)。
- 計算資源的數量或部署密度比之前高了一個數量級。
- 典型的 應用訪問模式 不再是之前的客戶端-伺服器模型,而是變成了 微服務 ( micro-service)模式。
- 與微服務模型對應的一個重要網路變化是: 東西向流量超過了南北向流量 ,成為資料中心的主要流量。
代表性的計算平臺有:
- Amazon Web Service (AWS), 2008
- OpenStack, 2010
3.2 網路需求
這時對網路的需求:
首先肯定虛擬機器之間的網路連通性,需要考慮的問題包括,
- 同宿主機、同網段的虛擬機器之間如何通訊;
- 同宿主機、跨網段的虛擬機器之間如何通訊;
- 跨宿主機、同網段的虛擬機器之間如何通訊;
- 跨宿主機、跨網段的虛擬機器之間如何通訊;
- 虛擬機器和宿主機或物理機之間如何通訊;
- 虛擬機器進出叢集(叢集邊界)如何通訊等等。
第二,虛擬機器的 IP 和 MAC 地址要在虛擬機器的生命週期內保持不變,這一點特別重要。本 質上來說 這是由 IAAS 計算模型決定的 :在 IAAS 模型中,交付給使用者的是一臺一臺的 虛擬機器資源,因此使用者看到的就是 虛擬機器這一層抽象 ,而 IP 和 MAC 是虛擬機器的資源 屬性,底層虛擬機器遷移要做到使用者無感知,因此 IP/MAC 地址不能變。
此外還有硬多租戶(hard multi-tenancy)和安全,這兩點也非常重要,但跟本文要討論的 關係不大,因此這裡也不展開。
3.3 網路解決方案
Fig 3-2. Typical network solution for VM platforms
針對以上需求,典型的解決方案是所謂的大二層網路,如上圖所示:
首先,在每個宿主機內執行一個虛擬交換機(vswitch),虛擬交換機向上連線到物理交換 機,向下連線到每個虛擬機器。因此網路的邊界從原來的接入交換機(頂置交換機)這一層, 下沉到宿主機內部,我們開始有了網路虛擬化(network virtualization)。 這樣整張網路成為一個大二層網路。
這裡大二層的意思是,同網段的虛擬機器,不管它們是否在同一臺宿主機上,彼此都能 夠通過二層(MAC)訪問到對方。即,邏輯上它們位於同一個二層網路(二層域)。
和這種模型對應的是一個 全域性的 (或中心式的)負責 IP 地址分配和管理的服務(IPAM)。
大二層網路可以基於資料中心網路實現,也可以在宿主機內用虛擬網路實現,例如 VxLAN 隧道,如果需要動態下發配置,還可以引入 SDN。
如果是基於資料中心網路的大二層,那核心交換機此時不僅需要記錄宿主機的 IP/MAC 資訊 ,還需要記錄所有虛擬機器的 IP/MAC 資訊,這樣才能支援虛擬機器全網可遷移。OpenStack 的 provider network 模型就是這樣的設計,如下圖所示:
Fig 3-3. OpenStack provider network model
OpenStack 網路方案中有如下幾個元件:
- Neutron-server:這是一個全域性的負責 IP、Network、Subnet 等網路資源的分配和管理的服務,即上面所說的 global IPAM。
- 每個計算節點上會執行一個 Neutron-OVS-agent,負責虛擬機器建立/銷燬時的網路配置。
- 每臺計算節點上會執行 OVS,負責連線所有虛擬機器、虛擬機器流量的轉發等資料平面的功 能。實際的拓撲比這個還要更復雜一些,因為為了支援安全組還引入了一層 Linux bridge。
Provider 模型中,閘道器配置在資料中心網路裝置(例如核心交換機)上,所有跨網段的 包要經過核心交換機轉發。圖中從 1 到 18 的數字連起來,就是跨網段的兩個虛擬機器之間的轉發路徑。
3.4 網路瓶頸分析(計算規模相關)
Fig 3-4. Bottleneck analysis
我們來算一下此時核心交換機的表項規模。假如這時我們機房更大了一些,
- 總共 300 個機櫃,但其中只有 2/3 的節點用來做虛擬化,1/3 跑傳統 BM 應用,例如資料庫服務,
- 每個 node 平均 15 臺虛擬機器,
那可以算出總共有 30k
虛擬機器,需要佔用核心交換機 ~30K
表項。
如果使用的是主流交換機,核心有 64K
表項,乘以 70% 是 44K
,也就是能支撐 4 萬 左右例項,大於 ~30K
,因此能滿足需求。
所以我們得出結論, 大二層方案是適合 VM 或 IAAS 模型的 。
4 容器時代
2016 年開始,我們進入了大規模容器時代。容器也被稱為輕量級虛擬機器,所以 它的很多 網路需求與虛擬機器類似 ,但 部署密度高了一個數量級 。典型的容器平臺:
- Mesos
- Kubernetes
4.1 沿用大二層模型
如果還是用前面的大二層模型,只是將虛擬機器換成容器,如下圖所示:
Fig 4-1. If still using large L2 network
如果沒有一些很特殊的業務需求,只是單純基於已有大二層網路實現這樣一套容器方案,其 技術難度和開發量都不是很大,例如,如果要將 Kubernetes 接入OpenStack Neutron 網路 ,開發一個針對 Neutron+OVS 的 CNI 外掛就可以了 [1]。
但前面提到,這種 global IPAM + central gateway 方案中, 核心交換機需要記錄 每個例項的 IP/MAC 資訊 ,再考慮到容器的部署密度,可以預見的是,交換機硬體表項將 撐不住。我們來具體算一下。
假設還是 2/3 節點做虛擬化,平均每臺 node 部署 75 個容器,那總容器將達到 150K
, 遠遠超過了核心的表項規模。所以 這種物理的大二層網路是無法支撐容器規模的 。
除了硬體交換機表項這個瓶頸,在軟體上,其實 global IPAM 也已經無法在效能上滿足容 器頻繁的漂移、建立、銷燬的需求了。所以大二層方案在軟體和硬體上都已經陷入了困境。
因此,網路在容器時代必須做出變化了。
4.2 避免網路瓶頸
剛才提到的 64K 表項交換機其實在今天還不算過時,那如何在這張物理網路上支撐 15萬、 20 萬甚至 30 萬以上容器呢(剛才的計算中,還有 1/3 的節點沒有做虛擬化,而且容器部 署密度可以進一步提高)?
顯然,最重要的一點就是 不能讓核心交換機記錄所有的容器的 IP 資訊 。怎麼做到這一 點呢?
Fig 4-2. If still using large L2 network
比較主流的方式是,
- 在每個 node 內用 虛擬路由器 (vrouter)替換 虛擬交換機 (vswitch),將整 張 大二層網路 拆分成眾多的 小二層網路 。
- 每個 node 管理一個網段,負責該節點內容器 IP 的分配和回收,即從原來的 global IPAM 變成了 local IPAM。
- 每個節點內是一個二層域,節點內容器之間走交換(bridging/switching);跨節點就 是跨二層域,需要走路由(routing)。
- 每個節點內執行一個 BGP agent,負責節點之間或節點和資料中心網路之間的路由同步。
採用這樣的設計之後,
- 核心交換機就只需要記錄 node 本身的 IP 和它管理的網段, 表項重新回到與宿主機數量同一量級 ,而與容器的數量沒有直接關係。
- IPAM 從中心式變成了分散式,效能瓶頸也解決了。
4.3 重新審視容器的網路需求
前面看到,只要對網路方案做出一些變化,就可以避免交換機的硬體瓶頸和 IPAM 的軟體瓶 頸。
現在我們來重新審視一下容器的特點,以便從需求的角度來討論什麼樣的方案才是最適合容 器平臺的。
Fig 4-3. Container platform vs. VM paltform
容器編排平臺,例如 Kubernetes,跟 OpenStack 這樣的虛擬機器編排平臺相比, 最大的不 同之一就是抽象的層次更高 。
- 虛擬機器平臺交付的是虛擬機器例項,抽象層次是計算資源本身這一層。
- 而容器平臺交付的是服務,例如 k8s 裡的 Service,服務遮蔽掉了後面的計算例項的細 節。客戶端只需要知道 ServiceIP 等一些更上層的訪問入口。
這帶來的一個重要變化就是: 客戶端不再關心服務的具體例項數量,以及每個例項的 IP/MAC 等資訊 。因此例項的 IP/MAC 地址沒有那麼重要了,例如 Kubernetes 裡大部 分型別的 Pod 在重新發布之後 IP 都會變化。
此時,容器的核心網路需求:
- 規模:例如還是剛才那個機房,現在要能支援 15 萬以上容器。
- 快速:包括 IPAM API 的相應時間、為容器建立和刪除網路的時間等,否則網路部分會 拖慢整體的容器釋出效率。
- 彈性:動態、大規模擴縮容。
- 其他一些需求,例如軟的多租戶、安全等等,本文不展開。
4.4 網路解決方案
綜合以上需求,合理的容器網路解決方案就是:
- 小二層網路,加每個 node local 的 IPAM,管理自己的網段
- 再加跨宿主機的直接路由或者隧道
如下圖所示,
Fig 4-4. Typical network solution for container platforms
那麼,和這種模型對應的容器網路方案有:
- Calico + BGP/VxLAN,前幾年用的比較多
- Cilium + BGP/VxLAN,最近一兩年越來越火
Spine-Leaf 架構
實際上資料中心網路拓撲近些年也有一個變化,從原來的接入-匯聚-核心三級架構變成了現 在的 Spine-Leaf 量級架構,如下圖所示:
Fig 4-5. Typical network solution for container platforms, with Spine-Leaf
Spine 層和 Leaf 層組成一個全連線網路,換句話說,任何一個 Leaf 都連線到了任何一個 Spine。這種架構的好處:
- 橫向擴充套件性非常好:任何一層有頻寬瓶頸,只需要新增一臺新裝置,然後和另一層的所 有裝置連線起來。
- 鏈路利用率更高:通過三層(L3)組網,不需要 STP 協議(STP 避免了二層環路,但使 可用頻寬減半)。
- 東西向頻寬更高:更適合現代微服務的場景。
- 故障域更小:掛掉一臺裝置,影響範圍更小。
Spine-Leaf 拓撲下,容器的網路方案是類似的,還是基於小二層加 local IPAM,只是 BGP 建連會稍有不同 [2]。
4.5 雲原生網路 Cilium+BGP
這裡稍微就 Cilium 網路展開一些討論,這是最近一兩年流行起來的網路方案。
Fig 4-6. Cilium powered Kubernetes cluster [5]
Cilium 的元件如上圖所示,主要包括,
- cilium-agent:每臺 node 上跑一個,同時監聽 k8s apiserver 和 cilium kvstore。
- cilium kvstore:儲存 cilium 的一些全域性狀態,例如 identity。
- cilium-operator:每個叢集一個,圖中沒畫出來,在公有云上承擔 IPAM 的功能。
Cilium 的核心基於 eBPF,這是 4.8 核心 引入的一項革命性技術:它使得核心變得可程式設計 。這裡可程式設計的意思是,以前要改變核心行為,需要修改核心程式碼、編譯除錯、重新打映象、 安裝執行等等,而且還要維護自己的核心分支,現在可能寫幾行 eBPF 程式碼然後動態載入到 核心就能實現同樣的效果。
eBPF 目前主要用在兩個方向:動態跟蹤(tracing) 和網路(networking)。
有了 eBPF/XDP 之後,我們可以看到資料平面處理(dataplane processing)有一個趨勢:
- 早期基於核心協議棧處理,更多地以功能為主
- 前些年核心到達效能瓶頸,於是一些團隊嘗試將部分網路處理放到使用者態,預留專門的 、獨享的網絡卡、CPU、記憶體等資源來收發包,例如 DPDK。
- 最近幾年開始重新回到核心。比較有代表性的是 Facebook 的 L4LB Katran,用 eBPF/XDP 重新之後比原來基於 IPVS 的版本快了 10 倍,效能已經和 DPDK 一個量級, ,而且還可以複用核心已有的基礎設施和生態。而使用者態方式最大的問題之一是原有的網 絡工具幾乎都失效了,並且沒有通用的 L4-L7 協議棧支援。
Cilium 是基於 eBPF 實現的一個網路方案,主打高效能和安全。 對核心要求較高,但也不是非常高,根據我們的使用經驗,
- 4.14 能用,
- 4.19 夠用;
- 5.x 核心外做了一些優化,或者原生實現了某些高階功能。
更多關於 Cilium+BGP 的實踐,可以參考我們之前的文章 [2,3]。
5 總結
網路方案的演進是一個複雜的過程,涉及到很多因素,本文嘗試從計算規模的角度對這一問 題進行了分析。從中可以看出,每種網路方案或網路模型都不是憑空出現的,它們本質上都 是業務需求在網路層的反映;而所有業務需求中,最重要的可能就是規模。
6 關於我們
如果對我們團隊感興趣,可以關注我們的技術部落格 http://ctripcloud.github.io 。
References
- [譯] 為 K8s workload 引入的一些 BPF datapath 擴充套件(LPC, 2021)
- [譯] [論文] 可虛擬化第三代(計算機)架構的規範化條件(ACM, 1974)
- [譯] NAT 穿透是如何工作的:技術原理及企業級實踐(Tailscale, 2020)
- [譯] 寫給工程師:關於證書(certificate)和公鑰基礎設施(PKI)的一切(SmallStep, 2018)
- [譯] 基於角色的訪問控制(RBAC):演進歷史、設計理念及簡潔實現(Tailscale, 2021)
- [譯] Control Group v2(cgroupv2 權威指南)(KernelDoc, 2021)
- [譯] Linux Socket Filtering (LSF, aka BPF)(KernelDoc,2021)
- [譯] LLVM eBPF 彙編程式設計(2020)
- [譯] Cilium:BPF 和 XDP 參考指南(2021)
- BPF 進階筆記(三):BPF Map 核心實現
- BPF 進階筆記(二):BPF Map 型別詳解:使用場景、程式示例
- BPF 進階筆記(一):BPF 程式型別詳解:使用場景、函式簽名、執行位置及程式示例
- 原始碼解析:K8s 建立 pod 時,背後發生了什麼(四)(2021)
- 原始碼解析:K8s 建立 pod 時,背後發生了什麼(三)(2021)
- [譯] 邁向完全可程式設計 tc 分類器(NetdevConf,2016)
- [譯] 雲原生世界中的資料包標記(packet mark)(LPC, 2020)
- [譯] 利用 eBPF 支撐大規模 K8s Service (LPC, 2019)
- 計算規模驅動下的網路方案演進
- 邁入 Cilium BGP 的雲原生網路時代
- [譯] BeyondProd:雲原生安全的一種新方法(Google, 2019)