三張圖帶你完全理解容器網(wǎng)絡(luò)接口 CNI 和 CNI 插件間的關(guān)系
一、CNI 是什么
首先我們介紹一下什么是 CNI,它的全稱是 Container Network Interface,即容器網(wǎng)絡(luò)的 API 接口。
它是 K8s 中標(biāo)準(zhǔn)的一個(gè)調(diào)用網(wǎng)絡(luò)實(shí)現(xiàn)的接口。Kubelet 通過這個(gè)標(biāo)準(zhǔn)的 API 來調(diào)用不同的網(wǎng)絡(luò)插件以實(shí)現(xiàn)不同的網(wǎng)絡(luò)配置方式,實(shí)現(xiàn)了這個(gè)接口的就是 CNI 插件,它實(shí)現(xiàn)了一系列的 CNI API 接口。常見的 CNI 插件包括 Calico、flannel、Terway、Weave Net 以及 Contiv。
二、Kubernetes 中如何使用 CNI
K8s 通過 CNI 配置文件來決定使用什么 CNI。
基本的使用方法為:
- 首先在每個(gè)節(jié)點(diǎn)上配置 CNI 配置文件(/etc/cni/net.d/xxnet.conf),其中 xxnet.conf 是某一個(gè)網(wǎng)絡(luò)配置文件的名稱;
- 安裝 CNI 配置文件中所對(duì)應(yīng)的二進(jìn)制插件;
- 在這個(gè)節(jié)點(diǎn)上創(chuàng)建 Pod 之后,Kubelet 就會(huì)根據(jù) CNI 配置文件執(zhí)行前兩步所安裝的 CNI 插件;
- 上一步執(zhí)行完之后,Pod 的網(wǎng)絡(luò)就配置完成了。
具體的流程如下圖所示:
三、哪個(gè) CNI 插件適合我
通常來說,CNI 插件可以分為三種:
- Overlay
- 路由
- Underlay
- Overlay 模式的典型特征是容器獨(dú)立于主機(jī)的 IP 段,這個(gè) IP 段進(jìn)行跨主機(jī)網(wǎng)絡(luò)通信時(shí)是通過在主機(jī)之間創(chuàng)建隧道的方式,將整個(gè)容器網(wǎng)段的包全都封裝成底層的物理網(wǎng)絡(luò)中主機(jī)之間的包。該方式的好處在于它不依賴于底層網(wǎng)絡(luò);
- 路由模式中主機(jī)和容器也分屬不同的網(wǎng)段,它與 Overlay 模式的主要區(qū)別在于它的跨主機(jī)通信是通過路由打通,無需在不同主機(jī)之間做一個(gè)隧道封包。但路由打通就需要部分依賴于底層網(wǎng)絡(luò),比如說要求底層網(wǎng)絡(luò)有二層可達(dá)的一個(gè)能力;
- Underlay 模式中容器和宿主機(jī)位于同一層網(wǎng)絡(luò),兩者擁有相同的地位。容器之間網(wǎng)絡(luò)的打通主要依靠于底層網(wǎng)絡(luò)。因此該模式是強(qiáng)依賴于底層能力的。
1. 環(huán)境限制
不同環(huán)境中所支持的底層能力是不同的。
- 虛擬化環(huán)境(例如 OpenStack)中的網(wǎng)絡(luò)限制較多,比如不允許機(jī)器之間直接通過二層協(xié)議訪問,必須要帶有 IP 地址這種三層的才能去做轉(zhuǎn)發(fā),限制某一個(gè)機(jī)器只能使用某些 IP 等。在這種被做了強(qiáng)限制的底層網(wǎng)絡(luò)中,只能去選擇 Overlay 的插件,常見的有 Flannel-vxlan, Calico-ipip, Weave 等等;
- 物理機(jī)環(huán)境中底層網(wǎng)絡(luò)的限制較少,比如說我們?cè)谕粋€(gè)交換機(jī)下面直接做一個(gè)二層的通信。對(duì)于這種集群環(huán)境,我們可以選擇 Underlay 或者路由模式的插件。Underlay 意味著我們可以直接在一個(gè)物理機(jī)上插多個(gè)網(wǎng)卡或者是在一些網(wǎng)卡上做硬件虛擬化;路由模式就是依賴于 Linux 的路由協(xié)議做一個(gè)打通。這樣就避免了像 vxlan 的封包方式導(dǎo)致的性能降低。這種環(huán)境下我們可選的插件包括 clico-bgp, flannel-hostgw, sriov 等等;
- 公有云環(huán)境也是虛擬化,因此底層限制也會(huì)較多。但每個(gè)公有云都會(huì)考慮適配容器,提升容器的性能,因此每家公有云可能都提供了一些 API 去配置一些額外的網(wǎng)卡或者路由這種能力。在公有云上,我們要盡量選擇公有云廠商提供的 CNI 插件以達(dá)到兼容性和性能上的最優(yōu)。比如 Aliyun 就提供了一個(gè)高性能的 Terway 插件。
環(huán)境限制考慮完之后,我們心中應(yīng)該都有一些選擇了,知道哪些能用、哪些不能用。在這個(gè)基礎(chǔ)上,我們?cè)偃タ紤]功能上的需求。
2. 功能需求
- 首先是安全需求;
K8s 支持 NetworkPolicy,就是說我們可以通過 NetworkPolicy 的一些規(guī)則去支持“Pod 之間是否可以訪問”這類策略。但不是每個(gè) CNI 插件都支持 NetworkPolicy 的聲明,如果大家有這個(gè)需求,可以選擇支持 NetworkPolicy 的一些插件,比如 Calico, Weave 等等。
- 第二個(gè)是是否需要集群外的資源與集群內(nèi)的資源互聯(lián)互通;
大家的應(yīng)用最初都是在虛擬機(jī)或者物理機(jī)上,容器化之后,應(yīng)用無法一下就完成遷移,因此就需要傳統(tǒng)的虛擬機(jī)或者物理機(jī)能跟容器的 IP 地址互通。為了實(shí)現(xiàn)這種互通,就需要兩者之間有一些打通的方式或者直接位于同一層。此時(shí)可以選擇 Underlay 的網(wǎng)絡(luò),比如 sriov 這種就是 Pod 和以前的虛擬機(jī)或者物理機(jī)在同一層。我們也可以使用 calico-bgp,此時(shí)它們雖然不在同一網(wǎng)段,但可以通過它去跟原有的路由器做一些 BGP 路由的一個(gè)發(fā)布,這樣也可以打通虛擬機(jī)與容器。
- 最后考慮的就是 K8s 的服務(wù)發(fā)現(xiàn)與負(fù)載均衡的能力。
K8s 的服務(wù)發(fā)現(xiàn)與負(fù)載均衡就是我們前面所介紹的 K8s 的 Service,但并不是所有的 CNI 插件都能實(shí)現(xiàn)這兩種能力。比如很多 Underlay 模式的插件,在 Pod 中的網(wǎng)卡是直接用的 Underlay 的硬件,或者通過硬件虛擬化插到容器中的,這個(gè)時(shí)候它的流量無法走到宿主機(jī)所在的命名空間,因此也無法應(yīng)用 kube-proxy 在宿主機(jī)配置的規(guī)則。
這種情況下,插件就無法訪問到 K8s 的服務(wù)發(fā)現(xiàn)。因此大家如果需要服務(wù)發(fā)現(xiàn)與負(fù)載均衡,在選擇 Underlay 的插件時(shí)就需要注意它們是否支持這兩種能力。
經(jīng)過功能需求的過濾之后,能選的插件就很少了。經(jīng)過環(huán)境限制和功能需求的過濾之后,如果還剩下 3、4 種插件,可以再來考慮性能需求。
3. 性能需求
我們可以從 Pod 的創(chuàng)建速度和 Pod 的網(wǎng)絡(luò)性能來衡量不同插件的性能。
- Pod 的創(chuàng)建速度
當(dāng)我們創(chuàng)建一組 Pod 時(shí),比如業(yè)務(wù)高峰來了,需要緊急擴(kuò)容,這時(shí)比如說我們擴(kuò)容了 1000 個(gè) Pod,就需要 CNI 插件創(chuàng)建并配置 1000 個(gè)網(wǎng)絡(luò)資源。Overlay 和路由模式在這種情況下的創(chuàng)建速度是很快的,因?yàn)樗窃跈C(jī)器里面又做了虛擬化,所以只需要調(diào)用內(nèi)核接口就可以完成這些操作。但對(duì)于 Underlay 模式,由于需要?jiǎng)?chuàng)建一些底層的網(wǎng)絡(luò)資源,所以整個(gè) Pod 的創(chuàng)建速度相對(duì)會(huì)慢一些。因此對(duì)于經(jīng)常需要緊急擴(kuò)容或者創(chuàng)建大批量的 Pod 這些場(chǎng)景,我們應(yīng)該盡量選擇 Overlay 或者路由模式的網(wǎng)絡(luò)插件。
- Pod 的網(wǎng)絡(luò)性能
主要表現(xiàn)在兩個(gè) Pod 之間的網(wǎng)絡(luò)轉(zhuǎn)發(fā)、網(wǎng)絡(luò)帶寬、PPS 延遲等這些性能指標(biāo)上。Overlay 模式的性能較差,因?yàn)樗诠?jié)點(diǎn)上又做了一層虛擬化,還需要去封包,封包又會(huì)帶來一些包頭的損失、CPU 的消耗等,如果大家對(duì)網(wǎng)絡(luò)性能的要求比較高,比如說機(jī)器學(xué)習(xí)、大數(shù)據(jù)這些場(chǎng)景就不適合使用 Overlay 模式。這種情形下我們通常選擇 Underlay 或者路由模式的 CNI 插件。