計算規模驅動下的網絡方案演進
本文其實是前一篇文章 邁入 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)