讓容器通訊變得簡單:深度解析 Containerd 中的 CNI 外掛

kubesphere發表於2024-07-23

作者:尹珉,KubeSphere Ambassador & contributor,KubeSphere 社群使用者委員會杭州站站長。

引言

在上一篇文章中,我們詳細討論了 Kubernetes 中 Containerd 的使用方法和一些核心概念。今天,我們將繼續深入,探索 containerd 中的 CNI 外掛。作為容器網路的關鍵組成部分,CNI 外掛在實現容器之間的網路通訊中扮演了重要角色。瞭解 CNI 外掛不僅可以幫助我們更好地管理 Kubernetes 叢集,還能提升我們的整體運維效率。

探索 CNI 外掛的奧秘

1. 什麼是 CNI 外掛?

CNI(Container Network Interface)外掛是獨立的可執行檔案,遵循 CNI 規範。Kubernetes 透過 kubelet 呼叫這些外掛來建立和管理容器的網路介面。CNI 外掛的主要職責包括網路介面的建立和刪除、IP 地址的分配和回收、以及相關網路資源的配置和清理。

2. CNI 外掛的工作流程簡述

2.1 Pod 建立

當一個新的 Pod 被建立時,kubelet 會呼叫 CNI 外掛的 ADD 命令。CNI 外掛會為 Pod 分配一個網路介面,並設定相關的網路配置,如 IP 地址和路由。這包括配置 Pod 的網路名稱空間,使其能夠與其他 Pod 進行通訊。

2.2 Pod 刪除

當 Pod 被刪除時,kubelet 會呼叫 CNI 外掛的 DEL 命令。CNI 外掛會清理之前為該 Pod 分配的網路資源,如回收 IP 地址和刪除網路介面。這一過程確保資源不會被浪費,並且系統能夠持續高效地執行。

3. CNI 外掛的功能

3.1 自動網路配置

CNI 外掛的一個主要功能是自動為新建立的容器分配 IP 地址並配置網路。這包括以下步驟:

  • IP 地址分配:CNI 外掛藉助 IPAM(IP Address Management)模組為每個容器分配唯一的 IP 地址。
  • 網路配置:設定路由和防火牆規則,確保容器能夠與外部網路及其他容器進行通訊。

3.2 保證網路連線

CNI 外掛確保容器能夠與同一 Pod 內的其他容器、同一 Node 上的其他 Pod 以及不同 Node 上的 Pod 進行通訊。這包括以下方面:

  • Pod 內通訊:在同一個 Pod 內,CNI 外掛透過建立共享網路名稱空間,使得同一 Pod 內的所有容器可以直接進行通訊。
  • 節點間通訊:透過 Overlay 網路或直接路由,確保不同節點上的 Pod 可以無縫通訊。
  • 網路策略:實現安全性和隔離,透過網路策略控制不同 Pod 之間的訪問許可權。

3.3 靈活的網路管理

CNI 外掛提供了靈活的網路管理功能,使網路管理員可以靈活地選擇和更換網路實現,而不需要對容器進行任何改動。這包括:

  • 外掛可插拔性:管理員可以根據需求選擇不同的 CNI 外掛(如 Flannel、Calico 等)來實現不同的網路功能。
  • 動態配置:無需重啟容器即可應用新的網路配置,支援動態擴充套件和調整網路結構。

透過這些功能,CNI 外掛不僅簡化了容器網路的配置和管理,還提供了靈活性和可擴充套件性,使 Kubernetes 叢集的網路架構更加高效和安全。

CNI 的主要功能是在容器啟動時,為其分配網路資源,並在容器停止時釋放這些資源。透過標準化介面,CNI 可以與不同的網路外掛配合使用,實現靈活的網路配置

4. 常見 CNI 外掛的介紹

4.1 Calico 外掛

Calico 是一種高效能的 CNI 外掛,提供安全的 L3 網路,並支援豐富的網路策略。它使用 BGP 協議在叢集中分發路由資訊,實現高效的網路連線。

  • 高效能:由於直接在 L3 層進行路由,Calico 效能優異。
  • 網路安全:Calico 支援網路策略,可以精細控制 Pod 之間的通訊。

詳見:https://www.tigera.io/project-calico/

4.2 Bridge 外掛

Bridge 外掛是 CNI 中最基本的外掛之一,通常用於本地主機網路。它透過建立 Linux 橋接(bridge)裝置來連線容器和宿主機網路。

  • 簡單可靠:適合小型叢集或單節點部署。
  • 配置靈活:可以根據需要配置橋接裝置的各種引數。

詳見:https://www.bookstack.cn/read/feiskyer-kubernetes-handbook-202005/network-cni-cni.md

4.3 IPVlan 外掛

IPVlan 外掛是一種高效能的網路解決方案,允許容器直接使用主機的網路介面。它有兩種模式:L2 模式和 L3 模式。

  • 效能優越:由於直接使用主機網路介面,效能非常高。
  • 簡化網路管理:不需要複雜的網路配置,適合高效能場景

詳見:https://www.bookstack.cn/read/feiskyer-kubernetes-handbook-202005/network-cni-cni.md

5. 如何選擇適合的 CNI 外掛?

選擇 CNI 外掛時,需要考慮以下幾個因素:

  • 叢集規模
    對於小型叢集,Flannel 是一個簡單易用的選擇;對於大型叢集,Calico 提供了強大的網路策略和隔離功能。
  • 網路需求
    如果需要複雜的網路功能和安全策略,Calico 和 Cilium 是不錯的選擇;如果注重簡單和快速部署,Weave 和 Flannel 可能更適合。
  • 效能要求
    對於高效能需求的場景,IPVlan 和 MACVlan 提供了更高效的網路通訊方式。

6. CNI 網路外掛實現模式

容器網路介面(CNI)外掛是容器網路架構的核心元件之一。它們的主要作用是管理容器的網路介面,為容器分配 IP 地址,並配置網路。CNI 外掛有多種實現模式,每種模式都適用於不同的場景和需求。主要的實現模式包括 Overlay 模式和 Underlay 模式。

6.1 Overlay 模式

Overlay 模式是一種虛擬化網路的實現方式,透過在現有的物理網路上構建邏輯網路隧道來實現容器之間的通訊。以下是 Overlay 模式的核心特點:

  • 邏輯隔離:Overlay 網路在物理網路之上建立邏輯網路,使不同的容器能夠在同一物理網路上執行而不會相互干擾。這種邏輯隔離有助於提高網路的安全性和管理性。
  • 靈活性:Overlay 網路可以在不改變物理網路架構的情況下輕鬆擴充套件和縮減。這使得在需要動態調整網路拓撲的場景中,Overlay 模式非常適用。
  • 常見實現:常見的 Overlay 網路實現包括 VXLAN 和 GRE。這些技術透過封裝原始資料包,並在物理網路上傳輸封裝後的資料包,來實現跨節點的容器通訊。

6.2 Underlay 模式

與 Overlay 模式不同,Underlay 模式直接利用底層物理網路來實現容器之間的通訊。這種模式通常用於對網路效能要求較高的場景。以下是 Underlay 模式的核心特點:

  • 高效能:由於 Underlay 模式直接利用物理網路,因此減少了封裝和解封裝的開銷,能夠提供更高的網路效能。
  • 直接互通:在 Underlay 模式下,容器的網路介面可以直接與物理網路裝置通訊,實現容器與物理網路資源的無縫互通。這對於需要與外部系統進行大量資料交換的應用非常重要。
  • 常見實現:常見的 Underlay 網路實現包括 MAC VLAN、IP VLAN 和直接路由等。這些技術利用物理網路的能力,直接配置容器的網路介面,使其能夠與底層網路進行通訊。

6.3 路由模式

除了 Overlay 和 Underlay 模式外,CNI 網路外掛的實現模式還包括一種路由模式。路由模式的主要特點是利用現有的物理網路裝置和路由協議來實現容器之間的通訊。

  • 高效能:減少了封裝和解封裝的開銷,提供更高的網路效能。
  • 可擴充套件性:利用現有的路由協議和網路裝置,容易擴充套件到大型叢集。
  • 簡單性:網路拓撲較為簡單,無需額外的 Overlay 網路配置。

6.4 選擇合適的 CNI 外掛模式

在選擇 CNI 外掛模式時,需要根據具體的應用場景和需求進行權衡:

  • Overlay 模式適合:需要靈活調整網路拓撲、對網路隔離要求高的場景,如多租戶環境或開發測試環境。
  • Underlay 模式適合:對網路效能要求高、需要與外部系統進行大量資料交換的生產環境。
  • 路由模式適合:追求高效能網路通訊、需要精細的網路策略控制和可擴充套件性的大型企業級生產環境,特別是在多叢集間需要一致的網路策略和高階路由功能的場景。

實戰練習

1. 配置 containerd 使用 CNI 外掛

1.1 選用 Calico 外掛作為演示

下載 Calico 安裝清單。

kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
kubectl get pod -A

1.2 驗證叢集是否正確配置 Caclico

cat /etc/cni/net.d/0-calico.conflist


完成上述步驟後,Kubernetes 叢集應該已經安裝並配置好 Calico 網路外掛 , 以實現高效的網路管理

2. 開發自定義 CNI 外掛

然而,不同企業的網路需求各不相同,有時標準的 CNI 外掛,如 Calico、Flannel 等,可能無法滿足特定的網路策略或效能要求。因此,開發自定義 CNI 外掛成為了擴充套件和定製 Kubernetes 網路能力的重要途徑。

開發自定義 CNI 外掛需要以下步驟:

  • 編寫外掛程式碼:使用 Go 語言編寫外掛程式碼,定義外掛的初始化、配置和刪除邏輯。
  • 實現 CNI 介面:實現 CNI 規範定義的介面,包括ADDDEL等操作。
  • 編譯外掛**:將外掛程式碼編譯成可執行檔案。
  • 配置 CNI 外掛:在 CNI 配置檔案中新增自定義外掛的配置,指定外掛路徑和引數。
  • 測試和除錯:透過建立和刪除容器來測試外掛功能,使用日誌和除錯工具排查問題。

例如,以下是一個簡單的 CNI 外掛示例:

package main

import (
    "fmt"
    "os"
    "github.com/containernetworking/cni/pkg/skel"
    "github.com/containernetworking/cni/pkg/types/current"
    "github.com/containernetworking/cni/pkg/types"
)

func main() {
    skel.PluginMain(cmdAdd, cmdCheck, cmdDel, version.All, bv.BuildString("example"))
}

func cmdAdd(args *skel.CmdArgs) error {
    // 實現ADD邏輯
    result := &current.Result{}
    return types.PrintResult(result, "0.3.1")
}

func cmdCheck(args *skel.CmdArgs) error {
    // 實現CHECK邏輯
    return nil
}

func cmdDel(args *skel.CmdArgs) error {
    // 實現DEL邏輯
    return nil
}

簡化容器通訊,讓 Kubernetes 網路更高效

透過本文,我們深入瞭解了 CNI 外掛在 containerd 中的重要作用,並透過實際案例展示瞭如何在 Kubernetes 中配置和使用 CNI 外掛。CNI 外掛不僅簡化了容器的網路配置,還提供了靈活的網路管理和安全隔離功能。

本文由部落格一文多發平臺 OpenWrite 釋出!

相關文章