參考:https://www.kubernetes.org.cn/6908.html
一、CNI 是什麼
首先我們介紹一下什麼是 CNI,它的全稱是 Container Network Interface,即容器網絡的 API 接口。
它是 K8s 中标準的一個調用網絡實作的接口。Kubelet 通過這個标準的 API 來調用不同的網絡插件以實作不同的網絡配置方式,實作了這個接口的就是 CNI 插件,它實作了一系列的 CNI API 接口。常見的 CNI 插件包括 Calico、flannel、Terway、Weave Net 以及 Contiv。
二、Kubernetes 中如何使用 CNI
K8s 通過 CNI 配置檔案來決定使用什麼 CNI。
基本的使用方法為:
具體的流程如下圖所示:
三、哪個 CNI 插件适合我
通常來說,CNI 插件可以分為三種:
Overlay
路由
Underlay
Overlay 模式的典型特征是容器獨立于主機的 IP 段,這個 IP 段進行跨主機網絡通信時是通過在主機之間建立隧道的方式,将整個容器網段的包全都封裝成底層的實體網絡中主機之間的包。該方式的好處在于它不依賴于底層網絡;
路由模式中主機和容器也分屬不同的網段,它與 Overlay 模式的主要差別在于它的跨主機通信是通過路由打通,無需在不同主機之間做一個隧道封包。但路由打通就需要部分依賴于底層網絡,比如說要求底層網絡有二層可達的一個能力;
Underlay 模式中容器和主控端位于同一層網絡,兩者擁有相同的地位。容器之間網絡的打通主要依靠于底層網絡。是以該模式是強依賴于底層能力的。
不同環境中所支援的底層能力是不同的。
虛拟化環境(例如 OpenStack)中的網絡限制較多,比如不允許機器之間直接通過二層協定通路,必須要帶有 IP 位址這種三層的才能去做轉發,限制某一個機器隻能使用某些 IP 等。在這種被做了強限制的底層網絡中,隻能去選擇 Overlay 的插件,常見的有 Flannel-vxlan, Calico-ipip, Weave 等等;
實體機環境中底層網絡的限制較少,比如說我們在同一個交換機下面直接做一個二層的通信。對于這種叢集環境,我們可以選擇 Underlay 或者路由模式的插件。Underlay 意味着我們可以直接在一個實體機上插多個網卡或者是在一些網卡上做硬體虛拟化;路由模式就是依賴于 Linux 的路由協定做一個打通。這樣就避免了像 vxlan 的封包方式導緻的性能降低。這種環境下我們可選的插件包括 clico-bgp, flannel-hostgw, sriov 等等;
公有雲環境也是虛拟化,是以底層限制也會較多。但每個公有雲都會考慮适配容器,提升容器的性能,是以每家公有雲可能都提供了一些 API 去配置一些額外的網卡或者路由這種能力。在公有雲上,我們要盡量選擇公有雲廠商提供的 CNI 插件以達到相容性和性能上的最優。比如 Aliyun 就提供了一個高性能的 Terway 插件。
環境限制考慮完之後,我們心中應該都有一些選擇了,知道哪些能用、哪些不能用。在這個基礎上,我們再去考慮功能上的需求。
首先是安全需求;
K8s 支援 NetworkPolicy,就是說我們可以通過 NetworkPolicy 的一些規則去支援“Pod 之間是否可以通路”這類政策。但不是每個 CNI 插件都支援 NetworkPolicy 的聲明,如果大家有這個需求,可以選擇支援 NetworkPolicy 的一些插件,比如 Calico, Weave 等等。
第二個是是否需要叢集外的資源與叢集内的資源互聯互通;
大家的應用最初都是在虛拟機或者實體機上,容器化之後,應用無法一下就完成遷移,是以就需要傳統的虛拟機或者實體機能跟容器的 IP 位址互通。為了實作這種互通,就需要兩者之間有一些打通的方式或者直接位于同一層。此時可以選擇 Underlay 的網絡,比如 sriov 這種就是 Pod 和以前的虛拟機或者實體機在同一層。我們也可以使用 calico-bgp,此時它們雖然不在同一網段,但可以通過它去跟原有的路由器做一些 BGP 路由的一個釋出,這樣也可以打通虛拟機與容器。
最後考慮的就是 K8s 的服務發現與負載均衡的能力。
K8s 的服務發現與負載均衡就是我們前面所介紹的 K8s 的 Service,但并不是所有的 CNI 插件都能實作這兩種能力。比如很多 Underlay 模式的插件,在 Pod 中的網卡是直接用的 Underlay 的硬體,或者通過硬體虛拟化插到容器中的,這個時候它的流量無法走到主控端所在的命名空間,是以也無法應用 kube-proxy 在主控端配置的規則。
這種情況下,插件就無法通路到 K8s 的服務發現。是以大家如果需要服務發現與負載均衡,在選擇 Underlay 的插件時就需要注意它們是否支援這兩種能力。
經過功能需求的過濾之後,能選的插件就很少了。經過環境限制和功能需求的過濾之後,如果還剩下 3、4 種插件,可以再來考慮性能需求。
我們可以從 Pod 的建立速度和 Pod 的網絡性能來衡量不同插件的性能。
Pod 的建立速度
當我們建立一組 Pod 時,比如業務高峰來了,需要緊急擴容,這時比如說我們擴容了 1000 個 Pod,就需要 CNI 插件建立并配置 1000 個網絡資源。Overlay 和路由模式在這種情況下的建立速度是很快的,因為它是在機器裡面又做了虛拟化,是以隻需要調用核心接口就可以完成這些操作。但對于 Underlay 模式,由于需要建立一些底層的網絡資源,是以整個 Pod 的建立速度相對會慢一些。是以對于經常需要緊急擴容或者建立大批量的 Pod 這些場景,我們應該盡量選擇 Overlay 或者路由模式的網絡插件。
Pod 的網絡性能
主要表現在兩個 Pod 之間的網絡轉發、網絡帶寬、PPS 延遲等這些性能名額上。Overlay 模式的性能較差,因為它在節點上又做了一層虛拟化,還需要去封包,封包又會帶來一些標頭的損失、CPU 的消耗等,如果大家對網絡性能的要求比較高,比如說機器學習、大資料這些場景就不适合使用 Overlay 模式。這種情形下我們通常選擇 Underlay 或者路由模式的 CNI 插件。