天天看點

從零開始入門 K8s:了解 CNI 和 CNI 插件

雲栖号資訊:【 點選檢視更多行業資訊

在這裡您可以找到不同行業的第一手的上雲資訊,還在等什麼,快來!

網絡架構是 K8s 中較為複雜的方面之一。K8s 網絡模型本身對某些特定的網絡功能有着一定的要求,是以,業界已經有了不少的網絡方案來滿足特定的環境和要求。CNI 意為容器網絡的 API 接口,為了讓使用者在容器建立或銷毀時都能夠更容易地配置容器網絡。在本文中,作者将帶領大家了解典型網絡插件地工作原理、掌握 CNI 插件的使用。

一、CNI 是什麼

首先我們介紹一下什麼是 CNI,它的全稱是 Container Network Interface,即容器網絡的 API 接口。

它是 K8s 中标準的一個調用網絡實作的接口。Kubelet 通過這個标準的 API 來調用不同的網絡插件以實作不同的網絡配置方式,實作了這個接口的就是 CNI 插件,它實作了一系列的 CNI API 接口。常見的 CNI 插件包括 Calico、flannel、Terway、Weave Net 以及 Contiv。

二、Kubernetes 中如何使用 CNI

K8s 通過 CNI 配置檔案來決定使用什麼 CNI。

基本的使用方法為:

1.首先在每個結點上配置 CNI 配置檔案 (/etc/cni/net.d/xxnet.conf),其中 xxnet.conf 是某一個網絡配置檔案的名稱;

2.安裝 CNI 配置檔案中所對應的二進制插件;

3.在這個節點上建立 Pod 之後,Kubelet 就會根據 CNI 配置檔案執行前兩步所安裝的 CNI 插件;

4.上步執行完之後,Pod 的網絡就配置完成了。

具體的流程如下圖所示:

從零開始入門 K8s:了解 CNI 和 CNI 插件

在叢集裡面建立一個 Pod 的時候,首先會通過 apiserver 将 Pod 的配置寫入。apiserver 的一些管控元件(比如 Scheduler)會排程到某個具體的節點上去。Kubelet 監聽到這個 Pod 的建立之後,會在本地進行一些建立的操作。當執行到建立網絡這一步驟時,它首先會讀取剛才我們所說的配置目錄中的配置檔案,配置檔案裡面會聲明所使用的是哪一個插件,然後去執行具體的 CNI 插件的二進制檔案,再由 CNI 插件進入 Pod 的網絡空間去配置 Pod 的網絡。配置完成之後,Kuberlet 也就完成了整個 Pod 的建立過程,這個 Pod 就線上了。

大家可能會覺得上述流程有很多步(比如要對 CNI 配置檔案進行配置、安裝二進制插件等等),看起來比較複雜。

但如果我們隻是作為一個使用者去使用 CNI 插件的話就比較簡單,因為很多 CNI 插件都已提供了一鍵安裝的能力。以我們常用的 Flannel 為例,如下圖所示:隻需要我們使用 kubectl apply Flannel 的一個 Deploying 模闆,它就能自動地将配置、二進制檔案安裝到每一個節點上去。

從零開始入門 K8s:了解 CNI 和 CNI 插件

安裝完之後,整個叢集的 CNI 插件就安裝完成了。

是以,如果我們隻是去使用 CNI 插件的話,那麼其實很多 CNI 插件已經提供了一鍵安裝的腳本,無需大家關心 Kubernetes 内部是如何配置的以及如何調用 API 的。

三、哪個 CNI 插件适合我

社群有很多的 CNI 插件,比如 Calico, flannel, Terway 等等。那麼在一個真正具體的生産環境中,我們要選擇哪一個 CNI 插件呢?

這就要從 CNI 的幾種實作模式說起。我們需要根據不同的場景選擇不同的實作模式,再去選擇對應的具體某一個插件。

通常來說,CNI 插件可以分為三種:Overlay、路由及 Underlay。

從零開始入門 K8s:了解 CNI 和 CNI 插件
  • Overlay 模式的典型特征是容器獨立于主機的 IP 段,這個 IP 段進行跨主機網絡通信時是通過在主機之間建立隧道的方式,将整個容器網段的包全都封裝成底層的實體網絡中主機之間的包。該方式的好處在于它不依賴于底層網絡;
  • 路由模式中主機和容器也分屬不同的網段,它與 Overlay 模式的主要差別在于它的跨主機通信是通過路由打通,無需在不同主機之間做一個隧道封包。但路由打通就需要部分依賴于底層網絡,比如說要求底層網絡有二層可達的一個能力;
  • Underlay 模式中容器和主控端位于同一層網絡,兩者擁有相同的地位。容器之間網絡的打通主要依靠于底層網絡。是以該模式是強依賴于底層能力的。

了解了以上三種常用的實作模式之後,再根據自己的環境、需求判斷可由哪一種模式進行實作,再在對應的模式中去找 CNI 插件。不過社群中有那麼多插件,它們又都屬于哪種模式?如何進行選擇呢?怎麼挑選适合自己的呢?我們可以從以下 3 個方面來考慮。

從零開始入門 K8s:了解 CNI 和 CNI 插件

1.環境限制

不同環境中所支援的底層能力是不同的。

  • 虛拟化環境(例如 OpenStack)中的網絡限制較多,比如不允許機器之間直接通過二層協定通路,必須要帶有 IP 位址這種三層的才能去做轉發,限制某一個機器隻能使用某些 IP 等。在這種被做了強限制的底層網絡中,隻能去選擇 Overlay 的插件,常見的有 Flannel-vxlan, Calico-ipip, Weave 等等;
  • 實體機環境中底層網絡的限制較少,比如說我們在同一個交換機下面直接做一個二層的通信。對于這種叢集環境,我們可以選擇 Underlay 或者路由模式的插件。Underlay 意味着我們可以直接在一個實體機上插多個網卡或者是在一些網卡上做硬體虛拟化;路由模式就是依賴于 Linux 的路由協定做一個打通。這樣就避免了像 vxlan 的封包方式導緻的性能降低。這種環境下我們可選的插件包括 clico-bgp, flannel-hostgw, sriov 等等;
  • 公有雲環境也是虛拟化,是以底層限制也會較多。但每個公有雲都會考慮适配容器,提升容器的性能,是以每家公有雲可能都提供了一些 API 去配置一些額外的網卡或者路由這種能力。在公有雲上,我們要盡量選擇公有雲廠商提供的 CNI 插件以達到相容性和性能上的最優。比如 Aliyun 就提供了一個高性能的 Terway 插件。

環境限制考慮完之後,我們心中應該都有一些選擇了,知道哪些能用、哪些不能用。在這個基礎上,我們再去考慮功能上的需求。

2.功能需求

  • 安全需求;

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 種插件,可以再來考慮性能需求。

3.性能需求

我們可以從 Pod 的建立速度和 Pod 的網絡性能來衡量不同插件的性能。

  • Pod 的建立速度

當我們建立一組 Pod 時,比如業務高峰來了,需要緊急擴容,這時比如說我們擴容了 1000 個 Pod,就需要 CNI 插件建立并配置 1000 個網絡資源。Overlay 和路由模式在這種情況下的建立速度是很快的,因為它是在機器裡面又做了虛拟化,是以隻需要調用核心接口就可以完成這些操作。但對于 Underlay 模式,由于需要建立一些底層的網絡資源,是以整個 Pod 的建立速度相對會慢一些。是以對于經常需要緊急擴容或者建立大批量的 Pod 這些場景,我們應該盡量選擇 Overlay 或者路由模式的網絡插件。

  • Pod 的網絡性能

主要表現在兩個 Pod 之間的網絡轉發、網絡帶寬、PPS 延遲等這些性能名額上。Overlay 模式的性能較差,因為它在節點上又做了一層虛拟化,還需要去封包,封包又會帶來一些標頭的損失、CPU 的消耗等,如果大家對網絡性能的要求比較高,比如說機器學習、大資料這些場景就不适合使用 Overlay 模式。這種情形下我們通常選擇 Underlay 或者路由模式的 CNI 插件。

相信大家通過這三步的挑選之後都能找到适合自己的網絡插件。

四、如何開發自己的 CNI 插件

有時社群的插件無法滿足自己的需求,比如在阿裡雲上隻能使用 vxlan 這種 Overlay 的插件,而 Overlay 插件的性能相對較差,無法滿足阿裡雲上的一些業務需求,是以阿裡雲上開發了一個 Terway 的插件。

如果我們自己的環境比較特殊,在社群裡面又找不到合适的網絡插件,此時可以開發一個自己的 CNI 插件。

CNI 插件的實作通常包含兩個部分:

1.一個二進制的 CNI 插件去配置 Pod 網卡和 IP 位址。這一步配置完成之後相當于給 Pod 上插上了一條網線,就是說它已經有自己的 IP、有自己的網卡了;

2.一個 Daemon 程序去管理 Pod 之間的網絡打通。這一步相當于說将 Pod 真正連上網絡,讓 Pod 之間能夠互相通信。

給 Pod 插上網線

那麼如何實作第一步,給 Pod 插上網線呢?通常是這樣一個步驟:

從零開始入門 K8s:了解 CNI 和 CNI 插件

1.給 Pod 準備一個網卡

通常我們會用一個 “veth” 這種虛拟網卡,一端放到 Pod 的網絡空間,一端放到主機的網絡空間,這樣就實作了 Pod 與主機這兩個命名空間的打通。

2.給 Pod 配置設定 IP 位址

這個 IP 位址有一個要求,我們在之前介紹網絡的時候也有提到,就是說這個 IP 位址在叢集裡需要是唯一的。如何保障叢集裡面給 Pod 配置設定的是個唯一的 IP 位址呢?

一般來說我們在建立整個叢集的時候會指定 Pod 的一個大網段,按照每個節點去配置設定一個 Node 網段。比如說上圖右側建立的是一個 172.16 的網段,我們再按照每個節點去配置設定一個 /24 的段,這樣就能保障每個節點上的位址是互不沖突的。然後每個 Pod 再從一個具體的節點上的網段中再去順序配置設定具體的 IP 位址,比如 Pod1 配置設定到了 172.16.0.1,Pod2 配置設定到了 172.16.0.2,這樣就實作了在節點裡面 IP 位址配置設定的不沖突,并且不同的 Node 又分屬不同的網段,是以不會沖突。

這樣就給 Pod 配置設定了叢集裡面一個唯一的 IP 位址。

3.配置 Pod 的 IP 和路由

  • 第一步,将配置設定到的 IP 位址配置給 Pod 的虛拟網卡;
  • 第二步,在 Pod 的網卡上配置叢集網段的路由,令通路的流量都走到對應的 Pod 網卡上去,并且也會配置預設路由的網段到這個網卡上,也就是說走公網的流量也會走到這個網卡上進行路由;
  • 最後在主控端上配置到 Pod 的 IP 位址的路由,指向到主控端對端 veth1 這個虛拟網卡上。這樣實作的是從 Pod 能夠到主控端上進行路由出去的,同時也實作了在主控端上通路到 Pod 的 IP 位址也能路由到對應的 Pod 的網卡所對應的對端上去。

給 Pod 連上網絡

剛才我們是給 Pod 插上網線,也就是給它配了 IP 位址以及路由表。那怎麼打通 Pod 之間的通信呢?也就是讓每一個 Pod 的 IP 位址在叢集裡面都能被通路到。

一般我們是在 CNI Daemon 程序中去做這些網絡打通的事情。通常來說是這樣一個步驟:

  • 首先 CNI 在每個節點上運作的 Daemon 程序會學習到叢集所有 Pod 的 IP 位址及其所在節點資訊。學習的方式通常是通過監聽 K8s APIServer,拿到現有 Pod 的 IP 位址以及節點,并且新的節點和新的 Pod 的建立的時候也能通知到每個 Daemon;
  • 拿到 Pod 以及 Node 的相關資訊之後,再去配置網絡進行打通。

(1).首先 Daemon 會建立到整個叢集所有節點的通道。這裡的通道是個抽象概念,具體實作一般是通過 Overlay 隧道、阿裡雲上的 VPC 路由表、或者是自己機房裡的 BGP 路由完成的;

(2).第二步是将所有 Pod 的 IP 位址跟上一步建立的通道關聯起來。關聯也是個抽象概念,具體的實作通常是通過 Linux 路由、fdb 轉發表或者 OVS 流表等完成的。Linux 路由可以設定某一個 IP 位址路由到哪個節點上去。fdb 轉發表是 forwarding database 的縮寫,就是把某個 Pod 的 IP 轉發到某一個節點的隧道端點上去(Overlay 網絡)。OVS 流表是由 Open vSwitch 實作的,它可以把 Pod 的 IP 轉發到對應的節點上。

六、本文總結

本文的主要内容就到此為止了,這裡為大家簡單總結一下:

1.在我們自己的環境中搭建一個 K8s 叢集,應當如何選擇最适合自己的網絡插件?

2.當社群網絡插件不能滿足時,如何開發自己的網絡插件?

【雲栖号線上課堂】每天都有産品技術專家分享!

課程位址:

https://yqh.aliyun.com/zhibo

立即加入社群,與專家面對面,及時了解課程最新動态!

【雲栖号線上課堂 社群】

https://c.tb.cn/F3.Z8gvnK

原文釋出時間:2020-03-26

本文作者:溪恒

本文來自:“

InfoQ

”,了解相關資訊可以關注“

繼續閱讀