從零開始入門 K8s | 理解 CNI 和 CNI 插件

0.png

做者 | 溪恆 阿里巴巴高級技術專家api

本文整理自《CNCF x Alibaba 雲原生技術公開課》第 26 講,點擊直達課程頁面安全

關注「阿里巴巴雲原生」公衆號,回覆關鍵詞「入門」,便可下載從零入門 K8s 系列文章 PPT。網絡

導讀:網絡架構是 K8s 中較爲複雜的方面之一。K8s 網絡模型自己對某些特定的網絡功能有着必定的要求,所以,業界已經有了很多的網絡方案來知足特定的環境和要求。CNI 意爲容器網絡的 API 接口,爲了讓用戶在容器建立或銷燬時都可以更容易地配置容器網絡。在本文中,做者將帶領你們理解典型網絡插件地工做原理、掌握 CNI 插件的使用。架構

1、CNI 是什麼

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

它是 K8s 中標準的一個調用網絡實現的接口。Kubelet 經過這個標準的 API 來調用不一樣的網絡插件以實現不一樣的網絡配置方式,實現了這個接口的就是 CNI 插件,它實現了一系列的 CNI API 接口。常見的 CNI 插件包括 Calico、flannel、Terway、Weave Net 以及 Contiv。負載均衡

2、Kubernetes 中如何使用 CNI

K8s 經過 CNI 配置文件來決定使用什麼 CNI。less

基本的使用方法爲:機器學習

  1. 首先在每一個結點上配置 CNI 配置文件(/etc/cni/net.d/xxnet.conf),其中 xxnet.conf 是某一個網絡配置文件的名稱;
  2. 安裝 CNI 配置文件中所對應的二進制插件;
  3. 在這個節點上建立 Pod 以後,Kubelet 就會根據 CNI 配置文件執行前兩步所安裝的 CNI 插件;
  4. 上步執行完以後,Pod 的網絡就配置完成了。

具體的流程以下圖所示:ide

1.png

在集羣裏面建立一個 Pod 的時候,首先會經過 apiserver 將 Pod 的配置寫入。apiserver 的一些管控組件(好比 Scheduler)會調度到某個具體的節點上去。Kubelet 監聽到這個 Pod 的建立以後,會在本地進行一些建立的操做。當執行到建立網絡這一步驟時,它首先會讀取剛纔咱們所說的配置目錄中的配置文件,配置文件裏面會聲明所使用的是哪個插件,而後去執行具體的 CNI 插件的二進制文件,再由 CNI 插件進入 Pod 的網絡空間去配置 Pod 的網絡。配置完成以後,Kuberlet 也就完成了整個 Pod 的建立過程,這個 Pod 就在線了。微服務

你們可能會以爲上述流程有不少步(好比要對 CNI 配置文件進行配置、安裝二進制插件等等),看起來比較複雜。

但若是咱們只是做爲一個用戶去使用 CNI 插件的話就比較簡單,由於不少 CNI 插件都已提供了一鍵安裝的能力。以咱們經常使用的 Flannel 爲例,以下圖所示:只須要咱們使用 kubectl apply Flannel 的一個 Deploying 模板,它就能自動地將配置、二進制文件安裝到每個節點上去。

2.png

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

所以,若是咱們只是去使用 CNI 插件的話,那麼其實不少 CNI 插件已經提供了一鍵安裝的腳本,無需你們關心 Kubernetes 內部是如何配置的以及如何調用 API 的。

3、哪一個 CNI 插件適合我

社區有不少的 CNI 插件,好比 Calico, flannel, Terway 等等。那麼在一個真正具體的生產環境中,咱們要選擇哪個 CNI 插件呢?<br /> <br />這就要從 CNI 的幾種實現模式提及。咱們須要根據不一樣的場景選擇不一樣的實現模式,再去選擇對應的具體某一個插件。

一般來講,CNI 插件能夠分爲三種:Overlay、路由及 Underlay。

3.png

  • Overlay 模式的典型特徵是容器獨立於主機的 IP 段,這個 IP 段進行跨主機網絡通訊時是經過在主機之間建立隧道的方式,將整個容器網段的包全都封裝成底層的物理網絡中主機之間的包。該方式的好處在於它不依賴於底層網絡;

  • 路由模式中主機和容器也分屬不一樣的網段,它與 Overlay 模式的主要區別在於它的跨主機通訊是經過路由打通,無需在不一樣主機之間作一個隧道封包。但路由打通就須要部分依賴於底層網絡,好比說要求底層網絡有二層可達的一個能力;

  • Underlay 模式中容器和宿主機位於同一層網絡,二者擁有相同的地位。容器之間網絡的打通主要依靠於底層網絡。所以該模式是強依賴於底層能力的。

瞭解了以上三種經常使用的實現模式以後,再根據本身的環境、需求判斷可由哪種模式進行實現,再在對應的模式中去找 CNI 插件。不過社區中有那麼多插件,它們又都屬於哪一種模式?如何進行選擇呢?怎麼挑選適合本身的呢?咱們能夠從如下 3 個方面來考慮。

4.png

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 的插件時就須要注意它們是否支持這兩種能力。

通過功能需求的過濾以後,能選的插件就不多了。通過環境限制和功能需求的過濾以後,若是還剩下 三、4 種插件,能夠再來考慮性能需求。

3. 性能需求

咱們能夠從 Pod 的建立速度和 Pod 的網絡性能來衡量不一樣插件的性能。

  • Pod 的建立速度

當咱們建立一組 Pod 時,好比業務高峯來了,須要緊急擴容,這時好比說咱們擴容了 1000 個 Pod,就須要 CNI 插件建立並配置 1000 個網絡資源。Overlay 和路由模式在這種狀況下的建立速度是很快的,由於它是在機器裏面又作了虛擬化,因此只須要調用內核接口就能夠完成這些操做。但對於 Underlay 模式,因爲須要建立一些底層的網絡資源,因此整個 Pod 的建立速度相對會慢一些。所以對於常常須要緊急擴容或者建立大批量的 Pod 這些場景,咱們應該儘可能選擇 Overlay 或者路由模式的網絡插件。

  • Pod 的網絡性能

主要表如今兩個 Pod 之間的網絡轉發、網絡帶寬、PPS 延遲等這些性能指標上。Overlay 模式的性能較差,由於它在節點上又作了一層虛擬化,還須要去封包,封包又會帶來一些包頭的損失、CPU 的消耗等,若是你們對網絡性能的要求比較高,好比說機器學習、大數據這些場景就不適合使用 Overlay 模式。這種情形下咱們一般選擇 Underlay 或者路由模式的 CNI 插件。

相信你們經過這三步的挑選以後都能找到適合本身的網絡插件。

4、如何開發本身的 CNI 插件

有時社區的插件沒法知足本身的需求,好比在阿里雲上只能使用 vxlan 這種 Overlay 的插件,而 Overlay 插件的性能相對較差,沒法知足阿里雲上的一些業務需求,因此阿里雲上開發了一個 Terway 的插件。

若是咱們本身的環境比較特殊,在社區裏面又找不到合適的網絡插件,此時能夠開發一個本身的 CNI 插件。

CNI 插件的實現一般包含兩個部分:

  1. 一個二進制的 CNI 插件去配置 Pod 網卡和 IP 地址。這一步配置完成以後至關於給 Pod 上插上了一條網線,就是說它已經有本身的 IP、有本身的網卡了;

  2. 一個 Daemon 進程去管理 Pod 之間的網絡打通。這一步至關於說將 Pod 真正連上網絡,讓 Pod 之間可以互相通訊。

給 Pod 插上網線

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

5.png

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 的相關信息以後,再去配置網絡進行打通。

    • 首先 Daemon 會建立到整個集羣全部節點的通道。這裏的通道是個抽象概念,具體實現通常是經過 Overlay 隧道、阿里雲上的 VPC 路由表、或者是本身機房裏的 BGP 路由完成的;

    • 第二步是將全部 Pod 的 IP 地址跟上一步建立的通道關聯起來。關聯也是個抽象概念,具體的實現一般是經過 Linux 路由、fdb 轉發表或者OVS 流表等完成的。Linux 路由能夠設定某一個 IP 地址路由到哪一個節點上去。fdb 轉發表是 forwarding database 的縮寫,就是把某個 Pod 的 IP 轉發到某一個節點的隧道端點上去(Overlay 網絡)。OVS 流表是由 Open vSwitch 實現的,它能夠把 Pod 的 IP 轉發到對應的節點上。

6、本文總結

本文的主要內容就到此爲止了,這裏爲你們簡單總結一下:

  1. 在咱們本身的環境中搭建一個 K8s 集羣,應當如何選擇最適合本身的網絡插件?
  2. 當社區網絡插件不能知足時,如何開發本身的網絡插件?

2羣直播海報.png

阿里巴巴雲原生關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,作最懂雲原生開發者的技術圈。」

相關文章
相關標籤/搜索