網絡模型深度解析:CNI、Pod通信與NetworkPolicy

目錄

專欄介紹

作者與平臺

您將學到什么?

學習特色

網絡模型深度解析:CNI、Pod通信與NetworkPolicy

第一部分:CNI 插件原理 - 網絡基礎設施的構建者

1.1 CNI 規范:標準化網絡接入的基石

1.2 Flannel:簡單高效的覆蓋網絡方案

1.3 Calico:高性能、安全、可擴展的網絡與策略方案

1.4 Flannel vs Calico:深度對比

第二部分:Pod 通信與跨節點路由 - 數據包的旅程

2.1 同節點 Pod 通信 (Intra-Node Communication)

2.2 跨節點 Pod 通信 (Inter-Node Communication) - Flannel (VXLAN)

2.3 跨節點 Pod 通信 (Inter-Node Communication) - Calico (純 BGP)

2.4 跨節點路由總結與對比

第三部分:網絡策略 (NetworkPolicy) - 微服務安全的守護者

3.1 NetworkPolicy 核心概念與模型

3.2 NetworkPolicy 實現原理 - 以 Calico 為例

3.3 NetworkPolicy 最佳實踐與常見場景

總結


專欄介紹

作者與平臺

作者:庸子

用戶ID:2401_86478612

第一發表平臺:CSDN

歡迎來到《Kubernetes架構師之路:系統化學習與實踐》專欄!在這個容器化技術主導的時代,Kubernetes已成為云原生應用編排的事實標準,掌握Kubernetes已成為每位開發者和運維工程師的必備技能。

本專欄采用系統化學習方法,從基礎概念到高級實踐,循序漸進地帶您全面掌握Kubernetes技術棧。無論您是剛接觸容器技術的初學者,還是希望深入理解Kubernetes架構的資深工程師,這里都將為您提供清晰的學習路徑和實用的實戰指導。

您將學到什么?

  • 基礎理論:深入理解容器、容器編排、Kubernetes核心概念和架構設計
  • 核心組件:掌握etcd、API Server、Controller Manager、Scheduler等核心組件的工作原理
  • 資源管理:學會Pod、Deployment、Service、Ingress等核心資源的創建與管理
  • 網絡與存儲:理解Kubernetes網絡模型和存儲方案,解決實際部署中的網絡與存儲問題
  • 高可用與擴展:構建高可用的Kubernetes集群,實現應用的自動擴展與故障恢復
  • 監控與日志:掌握集群監控、日志收集與應用性能優化方法
  • CI/CD集成:學習如何將Kubernetes與CI/CD流程結合,實現自動化部署
  • 安全實踐:了解Kubernetes安全模型,掌握RBAC、網絡策略等安全配置

學習特色

  1. 系統化知識體系:從零開始,構建完整的Kubernetes知識框架
  2. 實戰導向:每個知識點都配有實際操作案例,讓您"學以致用"
  3. 問題驅動:針對實際部署中常見的問題提供解決方案
  4. 最新版本覆蓋:基于最新穩定版Kubernetes,緊跟技術發展趨勢
  5. 架構師視角:不僅教您"如何做",更解釋"為什么這樣設計"

無論您是想提升個人競爭力,還是為企業構建高效的云原生基礎設施,本專欄都將助您成為真正的Kubernetes專家。讓我們一起開啟這段激動人心的Kubernetes學習之旅!

立即訂閱,開啟您的Kubernetes架構師成長之路!

Kubernetes 的網絡模型是其核心優勢之一,它提供了一個扁平、無 NAT、Pod 間可直接通信的環境。然而,實現這一看似簡單的模型背后,卻隱藏著復雜的架構和精心設計的組件。本文將深入剖析 Kubernetes 網絡的三大支柱:CNI 插件原理(聚焦 Flannel 與 Calico 的對比)、Pod 通信機制(特別是跨節點路由)以及 NetworkPolicy 的實現,力求在 15000 字的篇幅內,揭示其深度技術細節、設計哲學與工程實踐。

第一部分:CNI 插件原理 - 網絡基礎設施的構建者

1.1 CNI 規范:標準化網絡接入的基石

CNI (Container Network Interface) 并非 Kubernetes 獨創,而是一個由 CNCF (Cloud Native Computing Foundation) 托管的開放標準。其核心目標是解耦容器運行時與網絡實現,定義了一套通用的接口規范,讓容器運行時(如 Docker, containerd, CRI-O)能夠通過調用符合 CNI 標準的可執行文件(插件),為容器配置網絡。

核心工作流程:

  1. 觸發時機: 當 Kubelet 需要為 Pod 創建網絡命名空間(netns)時(即 Pod ADDED 事件),或刪除 Pod 網絡命名空間時(Pod DELETED 事件)。
  2. 調用插件: Kubelet 根據配置(通常位于 /etc/cni/net.d/ 目錄下的 .conf.conflist 文件)找到對應的 CNI 插件可執行文件(如 flannel, calico-ipam, calico)。
  3. 傳遞參數: Kubelet 通過環境變量和標準輸入(stdin)向插件傳遞關鍵信息:
      • 環境變量:CNI_COMMAND: ADD (創建網絡) 或 DEL (刪除網絡)。
      • CNI_CONTAINERID: 容器 ID。
      • CNI_NETNS: 容器網絡命名空間的路徑(如 /var/run/netns/<nsname>)。
      • CNI_IFNAME: 容器內要創建的虛擬網卡名稱(默認 eth0)。
      • CNI_ARGS: 額外的參數(如 K8S_POD_NAMESPACE, K8S_POD_NAME, K8S_POD_UID)。
    • 標準輸入 (stdin): 一個 JSON 格式的網絡配置對象,包含:
      • cniVersion: CNI 規范版本。
      • name: 網絡名稱。
      • type: 插件類型(如 flannel, calico, bridge)。
      • ipam: IP 地址管理配置(類型、子網、路由等)。
      • dns: DNS 配置(nameservers, domain, search)。
      • 插件特定的配置(如 Flannel 的 subnetFile, Calico 的 etcd_endpoints)。
      • 插件執行:ADD 操作:插件進入容器的 netns
      • 創建虛擬網卡對(veth pair):一端在容器內(eth0),另一端在宿主機上(如 veth<random>)。
      • 為容器內的 eth0 分配 IP 地址、設置路由(根據 IPAM 配置)。
      • 將宿主機端的 veth 設備連接到指定的網絡接口(如網橋、OVS 交換機)或進行路由配置。
      • 可選:設置 ARP、iptables 規則等。
      • 通過標準輸出(stdout)返回一個 JSON 結果,包含分配的 IP 地址、網關、DNS、路由等信息。
      • DEL 操作:插件根據傳入的參數,找到并刪除為該容器創建的網絡資源:刪除 veth pair、釋放 IP 地址、清理相關的路由/iptables 規則等。
      • 無需返回結果。
  4. 結果處理: Kubelet 接收插件返回的結果(ADD 時),將其記錄到 Pod 的狀態中(status.podIP),或執行清理(DEL 時)。

CNI 插件生態:

  • 主插件 (Main Plugin): 負責創建網絡接口、連接到網絡(如 bridge, vlan, macvlan, ipvlan, ptp, host-local, flannel, calico, weave-net, cilium)。
  • IPAM 插件 (IP Address Management): 負責分配和管理 IP 地址(如 host-local(基于本地文件/目錄)、dhcpstaticcalico-ipam(集成到 Calico 數據庫))。
  • 元插件 (Meta Plugin): 調用其他 CNI 插件組合實現更復雜功能(如 flannel 實際上是一個元插件,它調用 bridgehost-local IPAM;multus 用于多網絡)。
1.2 Flannel:簡單高效的覆蓋網絡方案

設計哲學: Flannel 的核心目標是簡單、易用、快速部署。它通過創建一個**覆蓋網絡(Overlay Network)**來解決跨節點 Pod 通信問題,將不同節點上的 Pod 置于一個邏輯上的大二層網絡中。

核心組件與工作原理:

  1. etcd/Consul (后端存儲): Flannel 使用 etcd 或 Consul 存儲關鍵的網絡配置信息,主要是:
    • 網絡配置:整個集群的 Overlay 網絡 CIDR(如 10.244.0.0/16)。
    • 子網分配:每個節點被分配一個唯一的子網(如 10.244.1.0/24, 10.244.2.0/24)。這個信息由 flanneld 守護進程啟動時向 etcd 注冊并獲取。
  2. flanneld 守護進程: 在每個 Kubernetes 節點上運行,是 Flannel 的核心。
    • 啟動: 讀取配置(/etc/sysconfig/flanneld 或命令行參數),連接 etcd。
    • 子網租約: 向 etcd 申請并租用一個子網(Lease)。租約信息包含子網 CIDR 和該節點的公網 IP(或用于 Overlay 通信的 IP)。
    • 后端實現選擇: Flannel 支持多種后端(Backend)數據封裝/路由方式,通過 -backend 參數指定:
      • vxlan (默認推薦): 使用 VXLAN (Virtual eXtensible LAN) 隧道技術。
        • 原理: 在宿主機內核創建一個 VXLAN 隧道設備(flannel.1)。當需要發送跨節點 Pod 流量時:
          1. 源 Pod (10.244.1.2) 發送數據包給目標 Pod (10.244.2.3)。
          2. 數據包到達源節點宿主機網絡棧。
          3. 源節點根據目標 IP (10.244.2.3) 查詢 Flannel 維護的路由表(由 flanneld 根據 etcd 中的子網信息生成)。路由表指示目標子網 10.244.2.0/24 通過 flannel.1 設備可達。
          4. 內核 VXLAN 模塊接管:
            • 將原始 Pod 數據包(源 IP: 10.244.1.2, 目標 IP: 10.244.2.3)作為 Payload。
            • 封裝一個 UDP 包:
              • 源 IP:源節點宿主機 IP(如 192.168.1.101)。
              • 目標 IP:目標節點宿主機 IP(如 192.168.1.102)。
              • 源端口:隨機端口。
              • 目標端口:8472 (VXLAN 默認端口)。
              • VXLAN Header:包含 VNI (VXLAN Network Identifier),用于標識不同的 VXLAN 網絡(Flannel 通常使用 1)。
            • 封裝一個 Ethernet II 幀(源/目標 MAC 為宿主機網卡 MAC)。
          5. 封裝后的 UDP 包通過宿主機物理網卡發送到目標節點。
          6. 目標節點收到 UDP 包,內核 VXLAN 模塊解封裝,提取出原始 Pod 數據包。
          7. 目標節點根據目標 IP (10.244.2.3) 查詢本地路由,將數據包轉發到目標 Pod 所在的 veth pair,最終到達目標 Pod。
        • 優點: 對底層網絡要求低(只需三層可達),支持大規模集群,性能相對較好(內核級封裝)。
        • 缺點: 有封裝開銷(增加 50-54 字節頭部),MTU 需調整(通常設置為 14001450),網絡路徑變長。
      • host-gw (主機網關): 利用節點作為網關。
        • 原理: flanneld 在每個節點上創建指向其他節點子網的路由條目。例如,在節點 A 上添加路由:ip route add 10.244.2.0/24 via 192.168.1.102 dev eth0
          1. 通信流程:源 Pod (10.244.1.2) 發送數據包給目標 Pod (10.244.2.3)。
          2. 數據包到達源節點宿主機。
          3. 源節點查詢路由表,發現目標子網 10.244.2.0/24 的下一跳是目標節點 IP (192.168.1.102)。
          4. 源節點直接將原始 Pod 數據包(源 IP: 10.244.1.2, 目標 IP: 10.244.2.3)通過物理網卡發送給目標節點(目標 MAC 是目標節點網卡的 MAC)。
          5. 目標節點收到數據包,查詢本地路由,將數據包轉發到目標 Pod。
        • 優點: 性能最佳(無封裝開銷,直接路由),MTU 無需調整。
        • 缺點: 要求所有節點在同一個二層網絡(L2)中,或者底層網絡支持直接路由到 Pod IP(通常需要配置靜態路由或動態路由協議如 BGP)。擴展性受限于二層網絡規模或路由表大小。
      • udp (早期/兼容): 使用用戶態的 TAP 設備和 UDP 封裝。
        • 原理: flanneld 創建一個 TAP 設備(flannel0),所有 Pod 流量都經過這個設備。flanneld 在用戶態讀取數據包,封裝成 UDP 包(源/目標端口 8285),再通過物理網卡發送。目標節點的 flanneld 接收 UDP 包,解封裝后寫入本地的 TAP 設備。
        • 優點: 兼容性好,對內核無特殊要求。
        • 缺點: 性能最差(用戶態切換開銷大),已基本被 vxlan 取代。
      • alloc (僅測試): 只分配子網,不創建網絡設備。
      • ipip (較少用): 使用 IPIP 隧道(IP in IP),類似 VXLAN 但更簡單(無 UDP 端口和 VNI),性能略好于 UDP 但差于 VXLAN,同樣有 MTU 問題。
  3. CNI 集成: Flannel 提供了一個 CNI 插件(通常是 /opt/cni/bin/flannel)。這個插件本身不創建網絡設備,它的主要作用是:
    • 讀取 flanneld 寫入的配置文件(通常是 /run/flannel/subnet.env),獲取當前節點的子網信息(FLANNEL_SUBNET)、MTU(FLANNEL_MTU)和后端類型(FLANNEL_NETWORK)。
    • 根據后端類型,調用其他 CNI 插件來完成實際的網絡配置:
      • 對于 vxlan/host-gw/udp/ipip:調用 bridge 插件(創建 cni0 網橋)和 host-local IPAM 插件(從 FLANNEL_SUBNET 中分配 Pod IP)。
      • veth 設備的一端插入 cni0 網橋。
      • 設置 Pod 內部的 IP 地址、路由(默認路由指向網橋 IP)。
      • 設置 FLANNEL_MTU 到 Pod 的 eth0 接口。
    • 返回配置結果給 Kubelet。

Flannel 架構總結:

  • 中心化存儲 (etcd): 管理全局網絡配置和子網分配。
  • 節點守護進程 (flanneld): 負責子網租約、后端網絡配置(創建隧道設備/路由)、生成 CNI 所需的配置文件。
  • CNI 插件 (flannel): 輕量級適配器,調用 bridgehost-local 完成容器網絡接入,利用 flanneld 提供的信息。
  • 后端 (vxlan/host-gw): 實現跨節點數據包的封裝或路由。
1.3 Calico:高性能、安全、可擴展的網絡與策略方案

設計哲學: Calico 的目標是提供高性能、原生三層路由、細粒度網絡策略的解決方案。它摒棄了傳統的覆蓋網絡,致力于利用標準的 BGP (Border Gateway Protocol) 和 Linux 內核網絡功能,構建一個純三層、可擴展、安全的 Pod 網絡。

核心組件與工作原理:

  1. etcd/Kubernetes API (數據存儲): Calico 可以使用獨立的 etcd 集群,或者更常見地,直接使用 Kubernetes API 作為其數據存儲后端(Datastore 模式)。存儲的信息包括:
    • IP 池(IPPool):定義可分配給 Pod 的 IP 地址范圍(如 192.168.0.0/16)。
    • 節點(Node):記錄每個節點的信息,包括其 BGP AS 號、IP 地址、隧道 IP(如果啟用 IPIP)。
    • 工作負載端點(WorkloadEndpoint):每個 Pod 的網絡端點信息,包含其 IP、MAC、所屬節點、命名空間、標簽等。
    • 網絡策略(NetworkPolicy):定義的訪問控制規則。
    • BGP 對等體(BGP Peer):配置的 BGP 鄰居信息。
  2. Felix (節點代理): 在每個 Kubernetes 節點上運行,是 Calico 的核心執行引擎。
      • 職責:接口管理: 創建和管理 Calico 使用的網絡接口(如 tunl0 用于 IPIP)。
      • 路由編程: 根據從 Datastore 獲取的信息(主要是其他節點的 Pod CIDR 和 BGP 路由信息),在 Linux 內核的路由表中動態添加/刪除路由條目。這是 Calico 實現跨節點通信的關鍵。
      • ACL 編程: 將 NetworkPolicy 規則翻譯成 Linux 內核的 iptables 或 nftables 規則,實現 Pod 間的訪問控制。
      • IP 地址管理: 配置 Pod 網絡接口的 IP 地址(通過調用 CNI 或直接操作)。
      • 狀態報告: 向 Datastore 報告節點狀態和健康信息。
  3. BIRD (BGP 守護進程): 在每個節點上運行(或作為 Felix 的子進程),是一個標準的 BGP 路由器。
      • 職責:建立 BGP 會話: 與集群內其他節點的 BIRD 建立 iBGP(內部 BGP)會話(通常使用同一個 AS 號)。
      • 路由分發: 將本節點上運行的 Pod 的 IP 地址(或整個 Pod CIDR,取決于配置)作為路由信息,通過 BGP 協議宣告(Advertise) 給集群內的其他節點。
      • 路由學習: 接收并學習其他節點宣告的 Pod IP/CIDR 路由。
      • 最佳路徑選擇: 根據 BGP 路徑屬性(如 AS_PATH)選擇到達目標 Pod IP 的最佳下一跳。
      • 外部連接: 可配置與物理網絡中的 BGP 路由器(如 ToR 交換機)建立 eBGP(外部 BGP)會話,將 Pod IP 路由宣告到物理網絡,實現 Pod IP 的外部可達性(可選)。
  4. confd (配置生成器 - 可選/舊版): 監聽 Datastore 中的變化(如 BGP Peer 配置),動態生成 BIRD 的配置文件(bird.cfg)并重載 BIRD。在新版本中,Felix 可能直接管理 BIRD 配置。
    • CNI 插件 (calico, calico-ipam):calico-ipam: Calico 的 IPAM 插件。它直接從 Datastore 中管理的 IPPool 里為 Pod 分配 IP 地址。支持多種分配模式(如順序、隨機)。
    • calico: Calico 的主 CNI 插件。當 Kubelet 調用它時:
      • 調用 calico-ipam 為 Pod 分配 IP。
      • 在 Pod 的 netns 中創建 veth pair。
      • 將宿主機端的 veth 設備連接到 Calico 的網絡接口(通常是直接路由,不依賴網橋)。
      • 為 Pod 內的 eth0 設置 IP 地址、路由(默認路由指向 Felix 配置的網關,通常是節點 IP)。
      • 關鍵點: Calico 默認不創建網橋。Pod 的 veth 設備直接連接到節點的根網絡命名空間。Felix 負責在節點上配置到所有其他 Pod IP 的直接路由。
      • 返回配置結果給 Kubelet。
  5. IPIP 模式: Calico 默認使用 純三層路由(BGP)。但在某些場景下(如節點不在同一二層網絡且無法配置物理路由),可以啟用 IPIP (IP in IP) 隧道模式。
    • 原理: 類似 Flannel 的 ipip 后端。Felix 會在每個節點創建一個 tunl0 隧道設備。當需要發送跨節點 Pod 流量時:
      1. 源節點根據 Felix 配置的路由表,發現目標 Pod IP 需要通過 tunl0 發送。
      2. 內核 IPIP 模塊將原始 Pod 數據包(源 IP: PodA_IP, 目標 IP: PodB_IP)封裝在一個新的 IP 包中:
        • 新 IP 包源 IP:源節點 IP。
        • 新 IP 包目標 IP:目標節點 IP。
        • 協議號:4 (IPIP)。
      3. 封裝后的 IP 包通過物理網絡發送到目標節點。
      4. 目標節點內核 IPIP 模塊解封裝,提取原始 Pod 數據包。
      5. 目標節點根據目標 IP (PodB_IP) 查詢本地路由(由 Felix 配置),將數據包發送到目標 Pod。
    • 啟用方式: 在 IPPool 配置中設置 ipipMode: AlwaysCrossSubnet(僅在跨子網時使用 IPIP)。
    • 影響: 啟用 IPIP 會引入封裝開銷(增加 20 字節),影響 MTU(通常設置為 1480),但解決了跨子網路由問題,性能仍優于 VXLAN(無 UDP 頭部)。
  6. BGP 路由模式: 這是 Calico 的核心優勢和默認模式。
    • 全互聯 (Full Mesh): 在集群內部,Calico 默認配置所有節點之間建立 iBGP 會話,形成一個全互聯的 BGP 拓撲。每個節點都將自己負責的 Pod CIDR(或具體 Pod IP)宣告給所有其他節點。
    • 路由反射器 (Route Reflector - RR): 當節點數量很大時(如 > 50),全互聯的 BGP 會話數量會呈 O(N2) 增長,導致管理復雜和資源消耗。Calico 支持部署 BGP Route Reflector。節點只需與 RR 建立 iBGP 會話,RR 負責在節點之間反射路由信息,大大減少會話數量(O(N))。RR 可以是專用節點,也可以復用 Kubernetes Master 節點(需注意高可用)。
    • eBGP 對接物理網絡: Calico 節點可以與物理網絡設備(如 ToR 交換機)建立 eBGP 會話。節點將 Pod IP 路由宣告給物理設備,物理設備再將這些路由宣告到更廣的網絡中。這使得:
      • Pod IP 可以被外部網絡直接路由訪問(無需 NAT)。
      • 外部流量可以直接路由到 Pod IP(無需經過 NodePort 或 LoadBalancer 的額外跳轉)。
      • 簡化了網絡架構,減少了 SNAT/DNAT 的性能損耗。
    • 無覆蓋網絡: 在純 BGP 模式下(無 IPIP),Pod 之間的通信完全依賴物理網絡的三層路由能力。數據包從源 Pod 發出,經過源節點路由,直接通過物理網絡路由到目標節點,再由目標節點路由到目標 Pod。沒有隧道封裝,性能接近物理網絡。

Calico 架構總結:

  • 數據存儲 (etcd/K8s API): 集中管理所有網絡狀態、策略和配置。
  • 節點代理 (Felix): 核心大腦,負責路由編程(Linux 路由表)、策略編程(iptables/nftables)、接口管理、狀態報告。
  • BGP 路由器 (BIRD): 路由引擎,負責通過 BGP 協議在節點間(iBGP)或與物理網絡(eBGP)分發和學習 Pod IP 路由。
  • CNI 插件 (calico/calico-ipam): 負責 Pod 網絡接入和 IP 地址分配,利用 Felix 和 BGP 提供的路由基礎設施。
  • 路由模式: 純 BGP(高性能,要求底層路由) 或 BGP + IPIP(兼容性更好,有封裝開銷)。
  • 策略引擎: Felix 將 NetworkPolicy 轉化為高效的內核級 ACL。
1.4 Flannel vs Calico:深度對比

特性維度

Flannel

Calico

深度解析與權衡

核心原理

覆蓋網絡 (Overlay)

純三層路由 (BGP) / IPIP 隧道

Flannel 通過隧道(VXLAN/UDP/IPIP)或主機網關(host-gw)在現有網絡上構建一個邏輯二層網絡,隔離了 Pod 網絡和物理網絡。Calico 則致力于將 Pod 網絡融入物理網絡的三層路由體系,利用 BGP 實現高效路由。

性能

中等 (vxlan/udp/ipip) / 優秀 (host-gw)

優秀 (純 BGP) / 良好 (IPIP)

Flannel host-gw 和 Calico 純 BGP 性能最佳,無封裝開銷,接近物理網絡性能。Flannel vxlan/udp/ipip 和 Calico IPIP 因隧道封裝(增加 20-54 字節頭部)和內核/用戶態處理開銷,性能有損耗(通常 10%-30%)。Calico 純 BGP 在大規模下性能優勢更明顯。

網絡模型

二層 Overlay (vxlan/udp/ipip) / 三層直連 (host-gw)

純三層 (BGP/IPIP)

Flannel 在 Overlay 模式下,Pod 通信邏輯上是二層廣播域,物理上是三層封裝。host-gw 模式下是純三層,但依賴底層 L2 或靜態路由。Calico 始終是三層模型,Pod IP 就是路由表中的目標地址。

復雜度

中高

Flannel 部署配置極其簡單(kubectl apply -f kube-flannel.yml),概念少(etcd, 子網, 后端),故障排查相對直觀(看路由、抓包)。Calico 涉及 BGP 概念(AS, Peer, RR)、Felix 狀態、iptables 規則、IPPool 管理等,部署(尤其 RR)、配置和故障排查(calicoctl, BGP 狀態)復雜度顯著更高。

擴展性

良好 (vxlan) / 受限 (host-gw)**

優秀 (BGP + RR)

Flannel vxlan 基于 L3 Overlay,擴展性很好,支持大規模集群。host-gw 受限于 L2 域大小或靜態路由維護能力。Calico 基于 BGP,天然具備互聯網級的擴展能力,通過 Route Reflector 可輕松支持數千節點規模。

對底層網絡要求

低 (vxlan/udp/ipip - 只需 L3 可達) / 高 (host-gw - 需 L2 或靜態路由)

高 (純 BGP - 需 L3 路由支持或 eBGP 對接) / 中 (IPIP - 只需 L3 可達)

Flannel Overlay 模式對底層網絡要求最低,只要節點間 IP 可通即可。host-gw 要求苛刻。Calico 純 BGP 要求底層網絡能夠路由 Pod IP 流量(要么節點在同一 L2,要么物理設備支持動態路由或配置靜態路由到節點)。IPIP 模式降低了對底層的要求,只需 L3 可達。

網絡策略 (NetworkPolicy)

不支持原生 (需集成 Canal/Cilium 等)

原生支持,功能強大且高效

Flannel 本身不實現 NetworkPolicy。若需策略,需部署其他 CNI(如 Canal = Flannel + Calico Felix,或 Cilium)。Calico 原生、深度集成 NetworkPolicy,由 Felix 直接翻譯為內核 iptables/nftables 規則,性能高,支持豐富的規則(基于標簽、命名空間、端口、協議、IP 段等)。

IP 地址管理 (IPAM)

簡單 (host-local)

強大 (calico-ipam)

Flannel 通常使用 host-local IPAM,基于節點本地文件管理子網分配,簡單但功能有限(如無 IP 池復用、固定 IP 分配復雜)。Calico 的 calico-ipam 集成到 Datastore,支持復雜的 IPPool 管理(多池、選擇器、固定 IP、IP 池復用、地址回收策略等),功能遠超 Flannel。

外部網絡集成

困難 (通常需要 SNAT/DNAT)

優秀 (通過 eBGP 宣告 Pod IP 路由)

Flannel 的 Pod IP 是私有 Overlay 地址,外部無法直接訪問。暴露服務需依賴 Kubernetes Service (NodePort/LoadBalancer) 或 Ingress,涉及 SNAT/DNAT。Calico 通過 eBGP 將 Pod IP 路由宣告到物理網絡,Pod IP 可被外部網絡直接路由訪問,無需 NAT,簡化架構,提升性能(尤其對東西向流量)。

MTU 處理

需手動調整 (通常 1400/1450 for vxlan, 1480 for ipip)

需手動調整 (純 BGP 無需, IPIP 需 1480)

所有隧道方案(Flannel vxlan/udp/ipip, Calico IPIP)都因封裝頭導致有效 MTU 減小,必須在 CNI 配置或網絡插件中設置正確的 MTU(通常比物理網絡 MTU 小 20-50 字節),否則可能導致分片或連接問題。Flannel host-gw 和 Calico 純 BGP 無此問題。

適用場景

中小規模集群、開發測試環境、對網絡策略要求不高、追求簡單快速部署

大規模生產環境、對性能要求高、需要細粒度網絡策略、需要外部直接路由 Pod IP、網絡架構復雜

Flannel 是入門和中小型集群的理想選擇,開箱即用,滿足基本需求。Calico 是企業級生產環境的首選方案之一,尤其適合性能敏感、安全要求高、網絡規模大或需要深度網絡集成的場景。其復雜度帶來的管理成本在大型環境中是值得的。

選擇建議:

  • 選 Flannel: 集群規模小(< 50 節點)、團隊網絡經驗有限、追求極致部署簡便性、當前或可預見的未來不需要 NetworkPolicy、對性能要求不是極端苛刻、底層網絡環境簡單(如公有云 VPC 內同一子網)。
  • 選 Calico: 集群規模大(> 50 節點或有擴展計劃)、對網絡性能有高要求(尤其東西向流量)、必須使用 NetworkPolicy 實現安全隔離、需要 Pod IP 被外部網絡直接路由訪問(避免 NAT 性能損耗和復雜性)、底層網絡支持 BGP 或愿意配置 IPIP、團隊具備一定的 BGP 和網絡排錯能力。
  • 折中方案 (Canal): 如果既想要 Flannel 的簡單部署(Overlay),又需要 Calico 的 NetworkPolicy,可以選擇 Canal 項目。它將 Flannel 作為網絡數據平面,同時部署 Calico 的 Felix 來提供 NetworkPolicy 功能。但性能和擴展性受限于 Flannel 的 Overlay 后端。

第二部分:Pod 通信與跨節點路由 - 數據包的旅程

理解了 CNI 如何構建網絡基礎設施后,我們深入探究 Pod 之間是如何通信的,特別是跨越不同物理節點時,數據包是如何被正確路由的。我們將結合 Flannel (VXLAN) 和 Calico (純 BGP) 兩種典型模式進行剖析。

2.1 同節點 Pod 通信 (Intra-Node Communication)

無論使用哪種 CNI 插件,同節點上的 Pod 通信機制是相似的,且相對簡單直接。

核心組件:

    • cni0 網橋 (Flannel) / 直接路由 (Calico):Flannel: Flannel CNI 調用 bridge 插件在節點上創建一個 Linux 網橋(通常叫 cni0)。每個 Pod 的 veth pair 的宿主機端(vethxxx)都會被插入到這個網橋中。網橋擁有一個 IP 地址(如 10.244.0.1),作為該節點子網的網關。
    • Calico: Calico 默認不創建網橋。Pod 的 veth pair 的宿主機端(calixxx)直接存在于節點的根網絡命名空間。Felix 會在節點上配置一條到該 Pod IP 的直連路由(ip route add <Pod_IP>/32 dev <veth_device>)。
  1. veth pair (Virtual Ethernet Pair): 連接 Pod 網絡命名空間和節點根命名空間的虛擬以太網對。一端在 Pod 內(eth0),另一端在節點上(vethxxxcalixxx)。它們像一根虛擬網線,數據包從一端進入,必從另一端出去。
  2. Pod 路由表: Pod 內部通常只有一條默認路由,指向其網關:
    • Flannel: default via 10.244.0.1 dev eth0 (網橋 IP)。
    • Calico: default via 169.254.1.1 dev eth0 (Calico 使用一個特殊的 link-local 地址 169.254.1.1 作為網關,Felix 會確保這個地址在節點上可達,通常指向節點自身的 IP 或一個虛擬接口)。

通信流程 (以 Pod A -> Pod B 為例,同節點):

  1. Pod A 發送數據包: Pod A (10.244.0.2) 的應用想發送數據給 Pod B (10.244.0.3)。
  2. Pod A 路由決策: Pod A 查詢自己的路由表。目標 IP 10.244.0.310.244.0.2 在同一子網(10.244.0.0/24),因此無需經過網關。Pod A 直接通過 ARP 解析目標 IP 10.244.0.3 對應的 MAC 地址。
    • ARP 解析:Flannel: Pod A 發送 ARP 請求(Who has 10.244.0.3? Tell 10.244.0.2)。這個請求通過 veth pair 到達 cni0 網橋。網橋會泛洪這個 ARP 請求到所有連接的端口(包括所有其他 Pod 的 veth 端)。Pod B 收到 ARP 請求后,回復自己的 MAC 地址。網橋學習到 10.244.0.3 對應的 MAC 地址在哪個端口(Pod B 的 veth 端)。
    • Calico: Pod A 發送 ARP 請求。請求通過 veth pair 到達節點根命名空間。節點內核(或由 Felix 代理的 ARP 響應)會直接回復 10.244.0.3 的 MAC 地址(即 Pod B 的 eth0 MAC)。Calico 通常會配置 proxy_arp 或使用 Felix 主動響應 ARP,避免泛洪。
  3. 數據包發送: Pod A 構造二層幀:源 MAC = Pod A eth0 MAC, 目標 MAC = Pod B eth0 MAC, 源 IP = 10.244.0.2, 目標 IP = 10.244.0.3。數據包通過 veth pair 發送到節點。
    • 節點內轉發:Flannel: 數據包到達 cni0 網橋。網橋查詢其 MAC 地址表(通過之前的 ARP 學習),知道目標 MAC 地址對應的端口是 Pod B 的 veth 端。網橋直接將數據幀轉發到該端口。
    • Calico: 數據包到達節點根命名空間。節點內核查詢路由表,發現有一條到 10.244.0.3/32 的直連路由,下一跳是 caliyyy 設備(Pod B 的 veth 端)。內核直接將數據包發送到該設備。
  4. 到達 Pod B: 數據包通過 Pod B 的 veth pair 進入 Pod B 的網絡命名空間,最終被 Pod B 的應用接收。

關鍵點: 同節點通信主要依賴 Linux 網橋(Flannel)或直連路由(Calico)和 veth pair,數據包始終在節點內核空間完成轉發,不涉及物理網絡,延遲極低,帶寬接近內存帶寬。

2.2 跨節點 Pod 通信 (Inter-Node Communication) - Flannel (VXLAN)

這是 Flannel 解決的核心問題。假設 Pod A (10.244.1.2) 在 Node 1 上,Pod B (10.244.2.3) 在 Node 2 上。Flannel 使用 VXLAN 后端。

核心組件 (Node 1 & Node 2):

  1. flanneld: 運行在每個節點,負責:
    • 向 etcd 注冊/獲取子網(Node 1: 10.244.1.0/24, Node 2: 10.244.2.0/24)。
    • 創建并管理 VXLAN 隧道設備 flannel.1
    • 根據 etcd 中的信息,在節點上維護路由表。
  2. VXLAN 隧道設備 (flannel.1): 一個虛擬網絡接口,由內核 VXLAN 模塊管理。它有自己的 MAC 地址和 IP 地址(通常是一個 169.254.x.x10.244.x.x 地址,但主要用于封裝/解封裝)。
節點路由表 (由 flanneld 維護):Node 1 路由表關鍵條目:
10.244.0.0/16 dev flannel.1 scope link
10.244.1.0/24 dev cni0 scope link  # 本節點子網
10.244.2.0/24 via 10.244.2.0 dev flannel.1 onlink  # Node 2 子網,下一跳是 Node 2 的隧道 IP
... (其他節點子網類似)
Node 2 路由表關鍵條目:
10.244.0.0/16 dev flannel.1 scope link
10.244.2.0/24 dev cni0 scope link  # 本節點子網
10.244.1.0/24 via 10.244.1.0 dev flannel.1 onlink  # Node 1 子網,下一跳是 Node 1 的隧道 IP
... (其他節點子網類似)
    • 注意: via <IP> dev flannel.1 表示目標子網 10.244.2.0/24 的流量需要通過 flannel.1 設備發送,并且下一跳(VXLAN VTEP IP)是 10.244.2.0(這個地址是 flanneld 為 Node 2 分配的隧道端點 IP,通常存儲在 etcd 中,Node 1 的 flanneld 會讀取它)。
  1. ARP 表 (由 flanneld/FDB 維護): 內核需要知道目標 VTEP IP (10.244.2.0) 對應的物理 MAC 地址(即 Node 2 物理網卡 eth0 的 MAC)。flanneld 會通過 etcd 獲取 Node 2 的物理 IP (192.168.1.102),然后 Node 1 內核會通過 ARP 解析 192.168.1.102 得到其 MAC。內核會將這個映射(VTEP IP -> 物理 MAC)存儲在 Forwarding Database (FDB) 中,用于 VXLAN 封裝。

通信流程 (Pod A -> Pod B):

  1. Pod A 發送數據包: Pod A (10.244.1.2) 發送數據包給 Pod B (10.244.2.3)。數據包:源 IP=10.244.1.2, 目標 IP=10.244.2.3
  2. Pod A 路由決策: Pod A 查詢路由表,目標 IP 10.244.2.3 不在本地子網 (10.244.1.0/24),因此走默認路由,發送到網關 (10.244.1.1,即 cni0 網橋 IP)。
  3. 到達 Node 1 網橋: 數據包通過 veth pair 到達 Node 1 的 cni0 網橋。
  4. Node 1 路由決策 (關鍵): Node 1 內核收到數據包(目標 IP=10.244.2.3),查詢節點路由表。找到最長匹配的路由:10.244.2.0/24 via 10.244.2.0 dev flannel.1。這表示:
    • 該數據包需要從 flannel.1 設備發出。
    • 下一跳(VTEP IP)是 10.244.2.0
  5. VXLAN 封裝 (Node 1 內核): 內核 VXLAN 模塊接管數據包:
    • 原始數據包 (Inner Packet): 源 IP=10.244.1.2, 目標 IP=10.244.2.3 (以及 L4 頭部)。
      • VXLAN 封裝:VXLAN Header: 添加 VXLAN 頭部,包含 VNI (通常為 1)。
      • UDP 頭部: 源端口(內核隨機選擇),目標端口=8472 (VXLAN 標準端口)。
      • Outer IP Header: 源 IP = Node 1 物理 IP (192.168.1.101),目標 IP = Node 2 物理 IP (192.168.1.102)。注意: 目標 IP 192.168.1.102 是如何得到的?內核根據下一跳 VTEP IP (10.244.2.0) 查詢 FDB 表,找到對應的物理 MAC 地址(Node 2 eth0 MAC),然后根據 Node 1 的路由表(目標 192.168.1.102 的路由,通常是直連或默認路由)確定 Outer IP 的目標 IP。
      • Outer Ethernet Header: 源 MAC = Node 1 eth0 MAC, 目標 MAC = Node 2 eth0 MAC (通過 ARP 解析 192.168.1.102 得到)。
    • 封裝后的數據包: [Eth(Node1MAC->Node2MAC)] [IP(192.168.1.101->192.168.1.102)] [UDP(SrcPort->8472)] [VXLAN(VNI=1)] [IP(10.244.1.2->10.244.2.3)] [L4...]
  6. 物理網絡傳輸: 封裝后的數據包通過 Node 1 的物理網卡 eth0 發送到物理網絡(交換機、路由器)。物理網絡設備只看到 Outer IP Header (192.168.1.101 -> 192.168.1.102),像處理普通 IP 包一樣將其路由到 Node 2。
  7. 到達 Node 2: 數據包到達 Node 2 的物理網卡 eth0
  8. VXLAN 解封裝 (Node 2 內核): Node 2 內核收到數據包:
    • 識別目標 UDP 端口是 8472,交給 VXLAN 模塊處理。
    • VXLAN 模塊檢查 VNI (1),確認是自己的隧道。
    • 剝離 Outer Ethernet, Outer IP, UDP, VXLAN Header。
    • 提取 出原始數據包:源 IP=10.244.1.2, 目標 IP=10.244.2.3
  9. Node 2 路由決策: Node 2 內核得到原始數據包(目標 IP=10.244.2.3),查詢節點路由表。找到最長匹配的路由:10.244.2.0/24 dev cni0 scope link。這表示目標 IP 在本節點子網內,需要通過 cni0 網橋發送。
  10. Node 2 內轉發: 數據包被發送到 cni0 網橋。網橋查詢 MAC 地址表(或通過 ARP),找到目標 IP 10.244.2.3 對應的 MAC 地址(Pod B eth0 MAC)所在的端口(Pod B 的 veth 端),將數據幀轉發到該端口。
  11. 到達 Pod B: 數據包通過 Pod B 的 veth pair 進入 Pod B 的網絡命名空間,被 Pod B 的應用接收。

關鍵點: Flannel VXLAN 通過隧道封裝,將 Pod IP 包裹在宿主機 IP 包中傳輸。核心在于:

  • 路由表: flanneld 維護的到其他節點子網的路由,指向 flannel.1 設備和下一跳 VTEP IP。
  • FDB 表: 內核維護的 VTEP IP 到物理 MAC 的映射,用于確定 Outer IP 的目標 IP。
  • 封裝/解封裝: 由內核 VXLAN 模塊高效完成,用戶態 flanneld 不參與數據平面轉發。
  • 性能影響: 封裝開銷(50+ 字節)、MTU 問題、內核處理開銷(相對較小)。
2.3 跨節點 Pod 通信 (Inter-Node Communication) - Calico (純 BGP)

Calico 純 BGP 模式展現了其設計的高效性。假設 Pod A (192.168.1.2) 在 Node 1 上,Pod B (192.168.2.3) 在 Node 2 上。Calico 使用 BGP 全互聯模式。

核心組件 (Node 1 & Node 2):

  1. Felix: 運行在每個節點,負責:
    • 配置 Pod 網絡接口(veth)。
    • 編程路由表: 根據從 Datastore (K8s API) 獲取的信息(其他節點的 Pod CIDR 和 BGP 學習到的路由),在 Linux 內核路由表中動態添加/刪除路由條目。
    • 編程 iptables/nftables 規則(用于 NetworkPolicy)。
  2. BIRD: 運行在每個節點,作為 BGP 路由器:
    • 與集群內所有其他節點建立 iBGP 會話(AS 號相同)。
    • 宣告路由: 將本節點上運行的 Pod 的 IP 地址(或整個 Pod CIDR,取決于配置 ipInIP: DisabledadvertiseClusterIPs: true/false)作為路由信息,通過 BGP 協議宣告給其他節點。例如,Node 1 宣告 192.168.1.0/24
    • 學習路由: 接收并學習其他節點宣告的 Pod IP/CIDR 路由。例如,Node 1 學習到 Node 2 宣告的 192.168.2.0/24
    • 安裝路由: BIRD 將學習到的最佳 BGP 路由安裝到 Linux 內核的路由表中。
節點路由表 (由 Felix + BIRD 維護):Node 1 路由表關鍵條目:
192.168.1.0/24 dev cali123 scope link  # 本節點 Pod CIDR,直連路由 (Felix)
192.168.2.0/24 via 192.168.1.102 dev eth0 proto bird  # Node 2 Pod CIDR,BIRD 學習并安裝,下一跳是 Node 2 IP
... (其他節點 Pod CIDR 類似)
Node 2 路由表關鍵條目:
192.168.2.0/24 dev cali456 scope link  # 本節點 Pod CIDR,直連路由 (Felix)
192.168.1.0/24 via 192.168.1.101 dev eth0 proto bird  # Node 1 Pod CIDR,BIRD 學習并安裝,下一跳是 Node 1 IP
... (其他節點 Pod CIDR 類似)
    • 關鍵: 路由條目 via <Node_IP> dev eth0 proto bird 表明目標 Pod CIDR 的流量需要通過物理網卡 eth0 發送,下一跳直接是目標節點的物理 IP 地址。沒有隧道設備!
  1. 物理網絡: 必須能夠支持路由 Pod IP 流量。這意味著:
    • 所有節點在同一個 L2 廣播域(如同一交換機下),或者
    • 物理網絡設備(路由器、三層交換機)配置了到達各個節點 Pod CIDR 的路由(靜態路由或通過 BGP/OSPF 等動態路由協議學習)。在純 BGP 模式下,Calico 依賴物理網絡的三層可達性。

通信流程 (Pod A -> Pod B):

  1. Pod A 發送數據包: Pod A (192.168.1.2) 發送數據包給 Pod B (192.168.2.3)。數據包:源 IP=192.168.1.2, 目標 IP=192.168.2.3
  2. Pod A 路由決策: Pod A 查詢路由表,目標 IP 192.168.2.3 不在本地網絡(通常 Pod 網關是 169.254.1.1),走默認路由,發送到網關。
  3. 到達 Node 1 根命名空間: 數據包通過 veth pair (cali123) 到達 Node 1 的根網絡命名空間。
  4. Node 1 路由決策 (關鍵): Node 1 內核收到數據包(目標 IP=192.168.2.3),查詢節點路由表。找到最長匹配的路由:192.168.2.0/24 via 192.168.1.102 dev eth0 proto bird。這表示:
    • 該數據包需要從物理網卡 eth0 發出。
    • 下一跳直接是 Node 2 的物理 IP 地址 (192.168.1.102)。
  5. Node 1 發送數據包: Node 1 內核構造二層幀:
    • 源 MAC = Node 1 eth0 MAC。
    • 目標 MAC = 下一跳 (192.168.1.102) 的 MAC 地址。Node 1 內核通過 ARP 解析 192.168.1.102 得到其 MAC 地址(Node 2 eth0 MAC)。
    • 源 IP = 192.168.1.2 (Pod A IP)。
    • 目標 IP = 192.168.2.3 (Pod B IP)。
    • 注意: 數據包沒有被封裝!它就是一個標準的 IP 包,源和目標 IP 都是 Pod IP。
  6. 物理網絡傳輸: Node 1 將這個原始 IP 包通過 eth0 發送到物理網絡。
    • 場景一 (L2 網絡): 如果節點在同一個 L2 域,交換機根據目標 MAC (Node 2 eth0 MAC) 直接將幀轉發到 Node 2。
    • 場景二 (L3 網絡): 如果節點在不同 L3 子網,物理路由器收到包:
      • 查看目標 IP (192.168.2.3)。
      • 查詢自己的路由表。假設路由器通過 BGP 從 Node 2 學習到了 192.168.2.0/24 的路由,下一跳是 Node 2 (192.168.1.102)。
      • 路由器將包轉發給下一跳(Node 2)。在轉發過程中,路由器會重寫二層幀頭:源 MAC 改為路由器出口 MAC,目標 MAC 改為 Node 2 eth0 MAC。但IP 包頭保持不變(源 IP=192.168.1.2, 目標 IP=192.168.2.3)。
  7. 到達 Node 2: 數據包(原始 IP 包)到達 Node 2 的物理網卡 eth0
  8. Node 2 路由決策: Node 2 內核收到數據包(目標 IP=192.168.2.3),查詢節點路由表。找到最長匹配的路由:192.168.2.0/24 dev cali456 scope link。這表示目標 IP 在本節點 Pod CIDR 內,需要通過 cali456 設備(Pod B 的 veth 端)發送。
  9. Node 2 內轉發: Node 2 內核直接將數據包發送到 cali456 設備。
  10. 到達 Pod B: 數據包通過 Pod B 的 veth pair 進入 Pod B 的網絡命名空間,被 Pod B 的應用接收。

關鍵點: Calico 純 BGP 模式實現了真正的三層路由:

  • 無封裝: Pod IP 包在物理網絡中裸奔,沒有額外的隧道頭部,性能最優,MTU 無需調整。
  • 路由驅動: BGP 協議負責在節點間分發 Pod CIDR 路由信息。BIRD 將這些路由安裝到內核路由表。
  • 直接路由: 節點路由表中的條目直接指向目標節點的物理 IP 作為下一跳。數據包的 IP 頭在整個傳輸過程中(除了最后一跳的 ARP 解析)保持不變。
  • 依賴物理網絡: 這是該模式最大的前提和潛在限制。物理網絡必須能夠正確路由 Pod IP 流量。在公有云環境中,通常需要配合云平臺的路由表(如 AWS Route Table, GCP Custom Route)或使用 IPIP 模式。在私有數據中心,需要網絡設備支持 BGP 或配置靜態路由。
  • eBGP 集成: 通過與物理網絡設備建立 eBGP 會話,Calico 可以將 Pod IP 路由宣告到整個物理網絡,實現 Pod IP 的全局可達性,這是其區別于 Overlay 方案的重大優勢。
2.4 跨節點路由總結與對比

特性

Flannel (VXLAN)

Calico (純 BGP)

深度解析

數據包路徑

Pod -> Node1 (veth/bridge) -> VXLAN Encap -> Physical Network -> Node2 -> VXLAN Decap -> Node2 (bridge/veth) -> Pod

Pod -> Node1 (veth) -> Physical Network (L3 Routing) -> Node2 (veth) -> Pod

Flannel 數據包在 Node1 和 Node2 經歷了封裝/解封裝過程,路徑更長。Calico 數據包在物理網絡中以原始 Pod IP 形式被路由,路徑最短,效率最高。

封裝開銷

有 (50+ 字節:VXLAN+UDP+Outer IP+Outer Eth)

Flannel 的封裝開銷增加了網絡負載,降低了有效帶寬,并可能導致分片(需調整 MTU)。Calico 無此開銷,帶寬利用率最高。

MTU

需調整 (通常 1400/1450)

無需調整 (使用物理網絡 MTU)

Flannel 必須在 CNI 配置或網絡插件中設置小于物理 MTU 的值,否則可能導致 TCP 性能下降或連接問題。Calico 直接使用物理網絡 MTU,無此煩惱。

路由表維護

集中式 (etcd) + 節點 (flanneld 寫路由)

分布式 (BGP 協議) + 節點 (Felix/BIRD)

Flannel 路由信息由 flanneld 從 etcd 讀取后寫入節點路由表,相對靜態。Calico 路由信息通過 BGP 協議在節點間動態分發和學習,更適應網絡變化,擴展性更好。

下一跳

VTEP IP (如 10.244.2.0) -> 隧道設備 (flannel.1)

目標節點物理 IP (如 192.168.1.102) -> 物理網卡 (eth0)

Flannel 的下一跳是邏輯隧道端點,需要額外的 FDB 表解析到物理地址。Calico 的下一跳直接是物理地址,路由決策更直接高效。

對物理網絡依賴

低 (只需 L3 可達)

高 (需 L3 路由支持 Pod IP)

Flannel VXLAN 對底層網絡要求最低,只要節點 IP 能通即可工作。Calico 純 BGP 要求物理網絡能路由 Pod IP 流量,部署限制更多,但網絡架構更扁平、高效。

性能

中等 (封裝/解封裝開銷)

優秀 (接近物理網絡極限)

在同等硬件條件下,Calico 純 BGP 的吞吐量和延遲通常顯著優于 Flannel VXLAN,尤其在大包傳輸和高并發場景下。

外部訪問

困難 (需 NAT)

容易 (通過 eBGP 宣告路由)

Flannel 的 Pod IP 是私有地址,外部無法直接訪問。Calico 通過 eBGP 將 Pod IP 路由宣告到物理網絡,Pod IP 可被外部直接路由訪問,無需 NAT,簡化架構。

結論: 跨節點路由是 Kubernetes 網絡的核心挑戰。Flannel 通過 VXLAN 等隧道技術提供了一種通用、易部署的解決方案,犧牲了一定的性能換取了對底層網絡的低依賴。Calico 則通過 BGP 和純三層路由,追求極致性能和網絡集成度,但要求更高的網絡規劃和管理能力。選擇哪種方案,取決于集群規模、性能要求、網絡環境復雜度和團隊運維能力。理解數據包在兩種模式下的完整旅程,是進行網絡優化和故障排查的基礎。

第三部分:網絡策略 (NetworkPolicy) - 微服務安全的守護者

在微服務架構中,服務間通信是常態,但并非所有服務都應該能夠相互訪問。NetworkPolicy 是 Kubernetes 提供的原生網絡策略 API,用于定義 Pod 組之間如何通信以及哪些通信是被允許的。它實現了命名空間級別的微分段(Micro-segmentation),是構建零信任網絡(Zero Trust Network)的關鍵組件。

3.1 NetworkPolicy 核心概念與模型

設計目標: 提供一種聲明式、基于標簽選擇器的方式,定義 Pod 之間的入站(Ingress)和出站(Egress)網絡訪問規則。

核心資源: NetworkPolicy (屬于 networking.k8s.io/v1 API Group)。

關鍵字段解析:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: <policy-name>  # 策略名稱namespace: <namespace> # 策略所屬命名空間
spec:podSelector: {} # **核心:選擇此策略應用到的目標 Pod 組**# matchLabels: {key: value}  # 基于標簽選擇# matchExpressions:          # 基于標簽表達式選擇policyTypes: # 指定策略類型(Ingress, Egress 或兩者)- Ingress- Egressingress: # **入站規則列表**:允許哪些流量訪問目標 Pod- from: # 流量來源列表(OR 關系)- podSelector: {} # 來源 Pod 選擇器(當前命名空間)# matchLabels: {key: value}- namespaceSelector: {} # 來源命名空間選擇器# matchLabels: {key: value}- namespaceSelector: {} # 可組合:來源是特定命名空間中符合標簽的 PodmatchLabels: {project: myproject}podSelector:matchLabels: {role: frontend}- ipBlock: # 來源 IP 段(CIDR)cidr: 192.168.1.0/24except: # 排除的 IP 段- 192.168.1.1/32ports: # 允許的目標端口列表(AND 關系,需與 from 匹配)- protocol: TCPport: 80- protocol: UDPport: 53egress: # **出站規則列表**:允許目標 Pod 訪問哪些外部資源- to: # 流量目標列表(OR 關系)- podSelector: {} # 目標 Pod 選擇器(當前命名空間)- namespaceSelector: {} # 目標命名空間選擇器- namespaceSelector: {} # 可組合:目標是特定命名空間中符合標簽的 Pod- ipBlock: # 目標 IP 段(CIDR)cidr: 10.0.0.0/8ports: # 允許的目標端口列表(AND 關系,需與 to 匹配)- protocol: TCPport: 443

核心語義與行為:

  1. 默認行為 (Deny All): 這是 NetworkPolicy 最重要也最容易被誤解的規則!
    • 如果一個 Pod 沒有被任何 NetworkPolicy 的 podSelector 選中,那么它不受任何 NetworkPolicy 限制,可以自由訪問任何地方,也可以被任何地方訪問(相當于網絡完全開放)。
      • 一旦一個 Pod 被至少一個 NetworkPolicy 的 podSelector 選中,那么:入站 (Ingress): 只有 明確匹配該 Pod 關聯的 NetworkPolicy 中 ingress 規則的流量才被允許。所有其他入站流量都被拒絕! (Deny All Ingress)
      • 出站 (Egress): 只有 明確匹配該 Pod 關聯的 NetworkPolicy 中 egress 規則的流量才被允許。所有其他出站流量都被拒絕! (Deny All Egress)
    • 關鍵點: NetworkPolicy 是疊加性的。一個 Pod 可以被多個 NetworkPolicy 選中。最終生效的規則是所有選中該 Pod 的 NetworkPolicy 規則的并集。但默認拒絕的語義始終存在:未被任何策略明確允許的流量,一律拒絕。
  2. podSelector (目標選擇): 定義策略保護誰。它選擇當前命名空間中的一組 Pod 作為策略的應用對象。只有被選中的 Pod 才會遵循此策略的規則(并受默認拒絕約束)。
  3. policyTypes (策略類型): 明確指定策略是用于控制入站 (Ingress)、出站 (Egress) 還是兩者。如果省略,Kubernetes 會根據 spec.ingressspec.egress 字段是否存在來推斷,但顯式指定是最佳實踐。
  4. ingress (入站規則):
    • from (來源): 定義允許訪問目標 Pod 的流量來源。from 下的多個子項(podSelector, namespaceSelector, ipBlock)是 OR 關系。例如,from: [podSelector: {app: db}, namespaceSelector: {env: dev}] 表示允許來自 app=db 的 Pod 或者 來自 env=dev 命名空間中任何 Pod 的訪問。
    • ports (端口): 定義允許訪問的目標端口。ports 下的多個端口規則是 OR 關系。例如,ports: [{protocol: TCP, port: 80}, {protocol: TCP, port: 443}] 表示允許訪問 TCP 80 或者 TCP 443。
    • from + ports: 一條完整的 ingress 規則(- from: ... ports: ...)表示:允許來自 from 定義的來源,訪問 ports 定義的端口。多個 ingress 規則是 OR 關系。
  5. egress (出站規則):
    • to (目標): 定義允許目標 Pod 訪問的外部資源。to 下的多個子項(podSelector, namespaceSelector, ipBlock)是 OR 關系。
    • ports (端口): 定義允許訪問的目標端口。ports 下的多個端口規則是 OR 關系。
    • to + ports: 一條完整的 egress 規則(- to: ... ports: ...)表示:允許目標 Pod 訪問 to 定義的資源的 ports 定義的端口。多個 egress 規則是 OR 關系。
  6. namespaceSelectorpodSelector 組合: 這是實現跨命名空間策略的關鍵。例如:
ingress:
- from:- namespaceSelector:matchLabels:project: myprojectpodSelector:matchLabels:role: frontend
  1. 表示:允許來自標簽為 project=myproject 的命名空間中,標簽為 role=frontend 的 Pod 的訪問。注意:podSelector 在這里選擇的是源命名空間中的 Pod,而不是目標命名空間中的 Pod。
  2. ipBlock: 用于基于 IP 段(CIDR)控制流量,常用于:
    • 允許/拒絕來自特定外部 IP 段的訪問(如辦公網 IP)。
    • 允許 Pod 訪問特定的外部服務 IP(如數據庫 IP)。
    • 注意: ipBlock 規則只適用于 IP 層,它不感知 Pod 的標簽或命名空間。當 ipBlockpodSelector/namespaceSelector 混用時,需要小心理解其語義(通常是 OR 關系)。except 字段用于排除 CIDR 中的特定 IP。
3.2 NetworkPolicy 實現原理 - 以 Calico 為例

NetworkPolicy 是一個 API 資源,其本身不執行任何網絡控制。它的實現完全依賴于底層的 CNI 網絡插件。不同的 CNI 插件(Calico, Cilium, Kube-router, Canal 等)有不同的實現機制,但核心思想都是將聲明式的 NetworkPolicy 規則翻譯成底層的網絡訪問控制列表(ACL)。我們以功能強大且廣泛使用的 Calico 為例,深入剖析其實現原理。

Calico 實現架構:

  1. Kubernetes API Server: 用戶創建 NetworkPolicy 資源。
  2. Calico Controller (Kube-controllers): 一個獨立的控制器(通常以 Deployment 運行),監聽 Kubernetes API Server 中的 NetworkPolicy, Pod, Namespace, Service 等資源變化。
  3. Calico Datastore (etcd/K8s API): Controller 將監聽到的 Kubernetes 資源狀態轉換并同步到 Calico 的 Datastore 中。例如,一個 Kubernetes NetworkPolicy 會被轉換為一個或多個 Calico 原生的 NetworkPolicyProfile 資源。
  4. Felix (節點代理): 運行在每個節點上,監聽 Calico Datastore 的變化。當它檢測到 NetworkPolicy 相關的資源(如 NetworkPolicy, WorkloadEndpoint, Profile)發生變化時:
    • 計算策略: Felix 結合當前節點上運行的 Pod 信息(WorkloadEndpoint)和 Datastore 中的策略規則,計算出需要應用到每個 Pod(更準確地說是每個 veth 接口)上的具體訪問控制規則。
    • 編程 ACL: Felix 將計算出的規則翻譯成 Linux 內核的 iptables (或可選的 nftables) 規則,并動態地加載到節點的內核網絡棧中。這些規則直接作用于 Pod 的 veth 接口或節點上的 chain
  5. Linux Kernel (iptables/nftables): 最終執行者。當網絡數據包流經 Pod 的 veth 接口或節點網絡棧時,內核會按照 Felix 編程的 iptables/nftables 規則進行匹配和決策(允許 ACCEPT 或拒絕 DROP)。

iptables 實現深度解析:

Calico 主要利用 Linux iptables 的 filter 表來實現 NetworkPolicy。它精心設計了一系列的 chain 和 規則。

核心 Chain 結構 (簡化版):

  1. FORWARD 鏈 (節點根命名空間): 所有跨節點或從節點發往 Pod 的流量(即非本機進程發起且非發往本機進程的流量)都會經過此鏈。Calico 在此鏈的開頭插入規則,將流量跳轉到 Calico 專門處理 Pod 流量的鏈。
    • 規則示例:-A FORWARD -m comment --comment "cali:..." -j cali-FORWARD
  2. cali-FORWARD 鏈: Calico 的主入口鏈。它根據數據包的方向(入站到 Pod 還是出站自 Pod)進行分流:
    • 入站流量 (到 Pod): 數據包目標 IP 是某個 Pod IP。規則:-A cali-FORWARD -m set --match-set cali40:some-pod-ip-hash dst -j cali-from-wl-dispatch (跳轉到 cali-from-wl-dispatch)。
    • 出站流量 (從 Pod): 數據包源 IP 是某個 Pod IP。規則:-A cali-FORWARD -m set --match-set cali40:some-pod-ip-hash src -j cali-to-wl-dispatch (跳轉到 cali-to-wl-dispatch)。
    • 其他流量: 通常直接 ACCEPT 或返回 FORWARD 鏈繼續處理。
  3. cali-from-wl-dispatch 鏈 (入站分發): 根據目標 Pod IP,將流量精確分發到處理該特定 Pod 入站策略的鏈。
    • 規則示例:-A cali-from-wl-dispatch -m set --match-set cali40:some-pod-ip-hash dst -j cali-fw-some-pod-name (跳轉到 cali-fw-some-pod-name)。
  4. cali-fw-<pod-name> 鏈 (特定 Pod 入站策略): 這是真正執行該 Pod 入站 NetworkPolicy 規則的地方。Felix 根據應用于該 Pod 的所有 NetworkPolicy 的 ingress 規則,在此鏈中生成對應的 iptables 規則。
    • 默認拒絕 (Deny All): 鏈的最后一條規則通常是 -j DROP。這實現了“未被明確允許即拒絕”的核心語義。
    • 允許規則: 在 DROP 規則之前,Felix 會插入匹配 NetworkPolicy ingress 規則的 ACCEPT 規則。例如:
      • 允許來自 app=frontend Pod 的 TCP 80 流量:
-A cali-fw-pod-x -m set --match-set cali40:frontend-pod-ips src -p tcp --dport 80 -j ACCEPT
    • (這里 cali40:frontend-pod-ips 是一個 ipset,包含了所有 app=frontend Pod 的 IP)。
      • 允許來自 namespace=dev 中任何 Pod 的流量:
-A cali-fw-pod-x -m set --match-set cali40:dev-namespace-pod-ips src -j ACCEPT
    • (ipset 包含 dev 命名空間中所有 Pod IP)。
      • 允許來自 IP 段 192.168.1.0/24 的流量:
-A cali-fw-pod-x -s 192.168.1.0/24 -j ACCEPT
  1. cali-to-wl-dispatch 鏈 (出站分發): 類似入站分發,根據源 Pod IP,將流量分發到處理該特定 Pod 出站策略的鏈。
    • 規則示例:-A cali-to-wl-dispatch -m set --match-set cali40:some-pod-ip-hash src -j cali-tw-some-pod-name
  2. cali-tw-<pod-name> 鏈 (特定 Pod 出站策略): 執行該 Pod 出站 NetworkPolicy 規則。
    • 默認拒絕 (Deny All): 鏈末尾 -j DROP
    • 允許規則: 在 DROP 之前插入匹配 egress 規則的 ACCEPT 規則。例如:
      • 允許訪問 app=database Pod 的 TCP 3306 流量:
-A cali-tw-pod-y -m set --match-set cali40:database-pod-ips dst -p tcp --dport 3306 -j ACCEPT
      • 允許訪問外部 IP 10.0.0.5 的 TCP 443 流量:
-A cali-tw-pod-y -d 10.0.0.5/32 -p tcp --dport 443 -j ACCEPT

關鍵技術點:

  • ipset 高效匹配: Calico 大量使用 ipset 來存儲和匹配 IP 地址集合(如某個標簽選擇器選中的所有 Pod IP,某個命名空間的所有 Pod IP)。ipset 是基于哈希的高效數據結構,匹配速度遠快于在 iptables 中寫多條 -s <ip>/32 規則,尤其當規則涉及大量 Pod 時,性能優勢巨大。Felix 會動態維護這些 ipset。
  • 規則順序與性能: iptables 規則是順序匹配的。Calico Felix 在生成規則時,會盡量優化規則順序,將匹配頻率高或范圍小的規則放在前面,以提高整體匹配效率。默認拒絕的 DROP 規則始終在最后。
  • 狀態檢測 (Connection Tracking): 對于 TCP 等有狀態的協議,Calico 依賴 Linux 內核的 連接跟蹤(conntrack) 機制。一旦一個連接被 ACCEPT 規則允許,其后續的返回包通常會被 conntrack 自動識別為 ESTABLISHED/RELATED 狀態,并被允許通過,無需再次匹配完整的策略規則。這大大提高了性能。Calico 會在策略鏈中插入類似 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 的規則(通常在靠前位置)。
  • 多策略疊加: 當一個 Pod 被多個 NetworkPolicy 選中時,Felix 會將所有策略的規則合并到該 Pod 對應的 cali-fw-<pod-name>cali-tw-<pod-name> 鏈中。由于規則是 OR 關系,只要匹配任意一條 ACCEPT 規則,流量就會被允許。最終的 DROP 規則保證了未被任何策略允許的流量被拒絕。
  • Service 訪問: NetworkPolicy 默認不感知 Kubernetes Service 的 ClusterIP。Pod 訪問 Service 的 ClusterIP 流量,會被 kube-proxy 的 iptables/IPVS 規則DNAT 成具體的 Pod IP。因此,在 NetworkPolicy 看來,流量是直接發往目標 Pod IP 的。策略需要允許訪問目標 Pod IP(或標簽) 才能生效。策略中不能直接寫 Service 的 ClusterIP 或名稱。這是一個常見的陷阱。解決方法是在策略中通過 podSelector 選擇后端 Pod,或者如果后端 Pod 標簽一致,直接使用該標簽。

其他 CNI 插件實現簡述:

  • Cilium: 基于 eBPF 技術。它在內核層面(XDP 或 TC hook 點)實現高性能的網絡策略。eBPF 程序直接在數據包進入內核網絡棧的早期階段執行,無需經過 iptables,性能極高,尤其適合高吞吐、低延遲場景。Cilium 還支持基于 HTTP/7 層的策略(如 HTTP 方法、路徑、頭),這是傳統 iptables 難以高效實現的。
  • Kube-router: 主要使用 iptables 實現 NetworkPolicy,同時提供 IPVS 服務代理和 BGP 路由功能。其實現原理與 Calico 的 iptables 模式類似,但架構更輕量(將 Felix、BIRD、IPVS 等功能集成在一個 DaemonSet 中)。
  • Canal: 結合 Flannel(網絡數據平面)和 Calico Felix(策略引擎)。其 NetworkPolicy 實現原理與 Calico 的 iptables 模式完全相同,因為策略部分就是用的 Calico Felix。
3.3 NetworkPolicy 最佳實踐與常見場景

1. 遵循最小權限原則:

  • 默認拒絕: 在生產環境中,強烈建議為關鍵命名空間(如 production, payment)或所有命名空間配置默認拒絕所有的 NetworkPolicy。這是零信任的基礎。
 ```yamlapiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:name: default-deny-allnamespace: productionspec:podSelector: {} # 選擇該命名空間所有 PodpolicyTypes:- Ingress- Egress```
  • 按需開放: 只為必要的通信添加明確的允許規則。避免使用過于寬泛的規則(如允許所有 TCP 流量)。

2. 合理使用標簽和命名空間:

  • 標簽 (Labels): 是 NetworkPolicy 選擇 Pod 的核心。為 Pod 打上清晰、有意義、穩定的標簽(如 app, component, tier, version)。避免使用易變或無意義的標簽。
  • 命名空間 (Namespaces): 是邏輯隔離和環境劃分的天然邊界。利用 namespaceSelector 實現跨命名空間的訪問控制。例如,只允許 testing 命名空間的 Pod 訪問 staging 命名空間的特定服務。
  • 組合選擇器: 靈活運用 podSelectornamespaceSelector 的組合,實現精細的跨命名空間策略。

3. 常見場景示例:

  • 場景一:允許前端 Pod 訪問后端 Pod 的特定端口。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: frontend-to-backendnamespace: default
spec:podSelector:matchLabels:app: backend # 保護后端 PodpolicyTypes:- Ingressingress:- from:- podSelector:matchLabels:app: frontend # 允許來自前端 Podports:- protocol: TCPport: 8080 # 允許訪問后端 8080 端口
  • 場景二:允許命名空間 A 中的 Pod 訪問命名空間 B 中的 Pod。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: ns-a-to-ns-bnamespace: ns-b # 保護 ns-b 中的 Pod
spec:podSelector: {} # ns-b 中所有 PodpolicyTypes:- Ingressingress:- from:- namespaceSelector:matchLabels:name: ns-a # 允許來自 ns-a 命名空間中任何 Pod
  • 場景三:允許 Pod 訪問外部數據庫 IP (Egress)。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: pod-to-dbnamespace: default
spec:podSelector:matchLabels:app: myapp # 限制 myapp Pod 的出站policyTypes:- Egressegress:- to:- ipBlock:cidr: 10.10.20.30/32 # 數據庫 IPports:- protocol: TCPport: 3306 # 數據庫端口# 通常還需要允許 DNS 查詢- to: []ports:- protocol: UDPport: 53
  • 場景四:允許 Pod 訪問 Kubernetes API Server (Egress)。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: allow-api-servernamespace: default
spec:podSelector:matchLabels:app: needs-api # 需要訪問 API 的 PodpolicyTypes:- Egressegress:- to:- ipBlock:cidr: <KUBERNETES_SERVICE_IP>/32 # API Server ClusterIP (如 10.96.0.1)ports:- protocol: TCPport: 443 # API Server 端口# 或者直接允許訪問 API Server 的 Pod IP(如果知道且穩定)# - to:#   - ipBlock:#       cidr: <API_SERVER_POD_IP>/32#   ports:#   - protocol: TCP#     port: 6443
  • 場景五:隔離命名空間,僅允許特定入站。
# 1. 默認拒絕所有入站和出站
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: default-deny-allnamespace: secure-ns
spec:podSelector: {}policyTypes:- Ingress- Egress# 2. 允許來自 Ingress Controller 的流量 (假設 Ingress Controller 在 ingress-ns 命名空間)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: allow-ingressnamespace: secure-ns
spec:podSelector: {} # 所有 PodpolicyTypes:- Ingressingress:- from:- namespaceSelector:matchLabels:name: ingress-nspodSelector:matchLabels:app: ingress-controller # 假設 Ingress Controller 有此標簽ports:- protocol: TCPport: 80 # HTTP- protocol: TCPport: 443 # HTTPS# 3. 允許 DNS 和 API Server 訪問 (Egress)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: allow-dns-apinamespace: secure-ns
spec:podSelector: {}policyTypes:- Egressegress:- to: [] # 允許訪問任何 IP 的 DNS (UDP 53)ports:- protocol: UDPport: 53- to:- ipBlock:cidr: <KUBERNETES_SERVICE_IP>/32ports:- protocol: TCPport: 443

4. 調試與排錯:

    • 確認策略生效:檢查 Pod 是否被策略選中:kubectl describe pod <pod-name> -n <ns>,查看是否有 NetworkPolicy 相關的 Annotation(如 k8s.v1.cni.cncf.io/networks-status)或使用 kubectl get networkpolicy 查看策略的 podSelector
    • 檢查 CNI 插件日志:查看 Calico Felix (kubectl logs -n calico-system <felix-pod>)、Cilium Agent (kubectl logs -n kube-system <cilium-agent>) 等日志,看策略是否被正確加載和翻譯。
    • 檢查節點上的 ACL:對于 Calico iptables 模式,登錄節點執行 sudo iptables -L -v -n | grep cali 查看規則和計數器。計數器 (pkts, bytes) 增長表示規則被匹配。sudo ipset list 查看 ipset 內容。
    • 測試連通性:使用 kubectl exec 進入源 Pod,ping/curl/telnet 目標 Pod IP/端口。
    • 使用 kubectl port-forward 暴露服務進行測試。
    • 使用 tcpdump 在源 Pod、目標 Pod、節點 veth 接口上抓包,觀察數據包是否被發送、是否到達、是否被丟棄(無響應或 ICMP Port Unreachable)。
    • 常見問題:策略未生效: Pod 未被任何策略選中(檢查 podSelector 和 Pod 標簽);CNI 插件未正確安裝或配置;策略語法錯誤。
    • 允許的流量被拒絕: 規則寫錯(端口、協議、IP、標簽);Service 訪問未轉換為后端 Pod IP 訪問(策略需允許目標 Pod IP);conntrack 表滿或狀態異常;MTU 問題導致分片被丟棄;底層網絡問題。
    • 默認拒絕過于嚴格: 忘記允許 DNS 查詢(UDP 53)、訪問 Kubernetes API Server、節點本地服務(如 kubelet metrics)等必要出站流量。

5. 性能考慮:

  • 規則數量: 過于復雜或數量龐大的 NetworkPolicy 規則會增加 iptables/nftables/eBPF 規則集的規模,可能影響數據包處理性能。盡量保持策略簡潔。
  • ipset 效率: Calico/Cilium 等使用 ipset 的插件在處理大量 Pod IP 時性能較好。避免在策略中直接寫大量單個 IP。
  • eBPF 優勢: 對于對網絡性能要求極高的場景,Cilium 的 eBPF 實現通常比 iptables 有顯著性能優勢。
  • 監控: 監控節點上的 CPU 使用率(特別是軟中斷 si)、網絡吞吐量、延遲。監控 CNI 插件自身的指標(如 Calico Felix 的 Prometheus 指標)。

總結

Kubernetes 的網絡模型是其強大生命力的關鍵支撐。通過本文的深度解析,我們揭示了其核心組件的精妙設計與復雜交互:

  1. CNI 插件: 作為網絡基礎設施的構建者,Flannel 以其簡單易用、覆蓋網絡的特性成為入門和中小規模集群的理想選擇,而 Calico 則憑借純三層 BGP 路由、原生高性能策略、靈活的外部集成能力,成為大規模、高性能、高安全要求生產環境的標桿。理解它們的架構差異(Overlay vs Routing)、性能權衡(封裝開銷 vs 路由依賴)和適用場景,是進行技術選型和網絡優化的基礎。
  2. Pod 通信與跨節點路由: 從同節點的高效網橋/直連路由,到跨節點的復雜路徑,我們追蹤了數據包的完整旅程。Flannel VXLAN 通過隧道封裝跨越了底層網絡的限制,而 Calico 純 BGP 則利用標準路由協議將 Pod 網絡無縫融入物理網絡,實現了接近物理極限的性能。掌握不同模式下的路由表維護、封裝/解封裝過程、MTU 處理和對物理網絡的依賴,是進行網絡規劃和故障排查的核心技能。
  3. NetworkPolicy: 作為微服務安全的守護者,NetworkPolicy 提供了聲明式、基于標簽的網絡微分段能力。其“默認拒絕”的核心語義是實現零信任網絡的基石。通過 Calico 等插件的實現,我們看到策略如何被翻譯成高效的內核級 ACL(如 iptables/nftables 或 eBPF)。遵循最小權限原則、合理運用標簽與命名空間、掌握常見場景的配置方法以及有效的調試手段,是構建安全、合規、可運維的 Kubernetes 網絡環境的關鍵。

Kubernetes 網絡的深度和廣度遠超本文所及,涉及 SDN、內核網絡、服務網格、云原生網絡等更廣闊的領域。然而,深入理解 CNI、Pod 通信和 NetworkPolicy 這三大支柱,就如同掌握了 Kubernetes 網絡世界的“牛頓定律”,為探索更高級的主題、解決復雜的網絡問題、構建高性能高可用的云原生應用奠定了堅實的基礎。隨著云原生技術的持續演進,Kubernetes 網絡模型也將在性能、安全性、可觀測性和易用性上不斷突破,持續為分布式系統的繁榮發展提供強大的網絡動力。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/94373.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/94373.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/94373.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數據結構青銅到王者第二話---數據結構基本常識(2)

續接上一話 一、包裝類 在Java中&#xff0c;由于基本類型不是繼承自Object&#xff0c;為了在泛型代碼中可以支持基本類型&#xff0c;Java給每個基本類型都對應了一個包裝類型。 1、基本數據類型和對應的包裝類 除了 Integer 和 Character&#xff0c; 其余基本類型的包裝類…

fastdds qos:DeadlineQosPolicy

1含義DeadlineQosPolicy這種qos使用在DataWriter、DataReader、Topic。該qos用來監督數據是不是按照預期的頻率進行收發。假如數據是周期性發送和接收&#xff0c;周期是固定的100ms&#xff0c;我們如果想要監督數據收發是不是按照預期的周期進行的&#xff0c;那么就可以配置…

QT-窗口類部件

Qt窗口類部件 一、窗口類部件 窗口就是沒有父部件的部件&#xff0c;所以又稱頂級部件。窗口類主要包括基本窗口類QWidget、對話框類QDialog和主窗口類QMainWindow三種。QObject是Qt框架中的一個核心基類&#xff0c;它提供了對象模型和信號槽機制。而QPaintDevice及其子類則提…

【CSP初賽】程序閱讀3

文章目錄前置知識閱讀程序判斷選擇答案解析判斷選擇總結前置知識 埃氏篩素數、C 基礎。 閱讀程序 #include <bits/stdc.h> using namespace std; int main(){int a1[51] {0};int i,j,t,t2,n 50;for(i 2;i<sqrt(n);i){if(a1[i] 0){t2 n/i;for(j 2;j<t2;j) …

【ESP32-IDF】高級外設開發4:SPI

系列文章目錄 持續更新中… 文章目錄系列文章目錄前言一、SPI概述1.主要功能2.SPI控制器架構3.SPI通信模式4.SPI數據幀與事務5.DMA與傳輸性能6.中斷與驅動事件二、SPI類型定義及相關API三、SPI示例程序總結前言 在嵌入式開發中&#xff0c;SPI&#xff08;串行外設接口&#…

遙感機器學習入門實戰教程|Sklearn案例⑧:評估指標(metrics)全解析

很多同學問&#xff1a;“模型好不好&#xff0c;怎么量化&#xff1f;” 本篇系統梳理 sklearn.metrics 中常用且“夠用”的多分類指標&#xff0c;并給出一段可直接運行的示例代碼&#xff0c;覆蓋&#xff1a;準確率、宏/微/加權 F1、Kappa、MCC、混淆矩陣&#xff08;計數/…

【Bluedroid】深入解析A2DP SBC編碼器初始化(a2dp_sbc_encoder_init)

SBC(Subband Coding)作為藍牙 A2DP 協議的標準編解碼器,其編碼器的初始化與參數配置直接影響音頻傳輸的音質、效率與兼容性。本文基于Andoird A2DP 協議棧源碼,系統剖析 SBC 編碼器的初始化流程,包括核心參數(比特池、采樣率、聲道模式等)的解析、計算與動態調整邏輯,以…

linux shell測試函數

在 C 語言中&#xff0c;int main(int argc, char *argv[])是程序的入口函數&#xff0c;而??在 main函數中調用專門的測試邏輯&#xff08;如測試函數&#xff09;??的程序結構&#xff0c;通常被稱為??測試程序&#xff08;Test Program&#xff09;??或??測試驅動…

【Java SE】抽象類、接口與Object類

文章目錄一、 抽象類&#xff08;Abstract Class&#xff09;1.1 什么是抽象類&#xff1f;1.2 抽象類的語法1.2.1 定義抽象類1.2.2 繼承抽象類1.3 抽象類的特性1.3.1 不能直接實例化1.3.2 抽象方法的限制1.3.3 抽象類可以包含構造方法1.3.4 抽象類不一定包含抽象方法1.3.5 抽象…

Autodl 創建新虛擬環境 python3.9

問題&#xff1a;本人在autodl上保存的環境因為很長時間沒有開機&#xff0c;autodl竟然給我刪除了。后來看了官網的介紹我才發現&#xff0c;原來15天不開機&#xff0c;autodl就會自動釋放實例。 因此&#xff0c;我就自己重新選了一個虛擬環境&#xff0c;從頭開始配置。 GP…

應急響應靶機-WindowsServer2022挖礦事件

依舊手癢開局&#xff0c;知攻善防實驗室的原創靶機 https://mp.weixin.qq.com/s/URrNHvQSnFKOyefHKXKjQQ 相關賬戶密碼&#xff1a; Administrator/zgsf123 注意&#xff1a;做個原始快照&#xff08;方便日后復習&#xff09;&#xff0c;安裝VMware tool&#xff08;安裝后圖…

PCB電路設計學習3 電路原理圖設計 元件PCB封裝設計與添加

目錄PCB電路設計學習3五、電路原理圖設計5.1 32個發光二極管電路5.2 單片機外圍電路5.3 供電與程序下載電路5.4 連接各部分網絡&#xff0c;繪制邊框和說明六、元件PCB封裝設計與添加6.1 名詞解釋6.2 繪制PCB附學習參考網址歡迎大家有問題評論交流 (* ^ ω ^)PCB電路設計學習3 …

redis---常用數據類型及內部編碼

Redis 中每種常用數據類型都對應多種內部編碼&#xff0c;這些編碼會根據數據特征&#xff08;如大小、數量&#xff09;自動切換&#xff0c;以平衡存儲效率和操作性能。1.字符串&#xff08;String&#xff09;用途&#xff1a;存儲文本、數字或二進制數據&#xff0c;是最基…

crypto.randomUUID is not a function

在本地運行時 crypto.randomUUID 好使&#xff0c;build 后放到服務器上用域名訪問就不好使。原因&#xff1a;瀏覽器策略&#xff0c;瀏覽器在非https、localhost的環境中訪問時&#xff0c;crypto.randomUUID 是不可用的開發時使用的是localhost正常訪問 生產臨時使用的是htt…

【思考】什么是服務器?什么是服務?什么是部署?

文章目錄1 什么是服務器&#xff1f;什么是服務&#xff1f;端口是什么意思&#xff1f;2 什么是部署&#xff1f;1 什么是服務器&#xff1f;什么是服務&#xff1f;端口是什么意思&#xff1f; 服務器本質是一臺運行著程序的電腦&#xff0c;它可以運行著很多程序&#xff0c…

自動駕駛導航信號使用方式調研

1 總結 本文調研在給定導航信號后&#xff0c;如何在端到端架構下&#xff0c;利用導航信息引導軌跡生成。 目前主流的方案可以分為2種。一種是將導航作為“前置引導”深度融入軌跡生成過程&#xff08;導航前置型&#xff09;&#xff1b;另一種則是將導航作為“后置評價”標準…

玳瑁的嵌入式日記D21-08020(數據結構)

雙向鏈表double link listtypedef struct dou_node { DATATYPE data; struct dou_node *prev; struct dou_node *next; }DouLinkNode;雙向鏈表&#xff1a;節點 數據 NEXT PREV . 手撕代碼(增加刪除) 增加&#xff0c;刪除的操作&#xff0c; 需要 tmp 停止待操作節點的前一…

Uipath查找元素 查找子元素 獲取屬性活動組合使用示例

Uipath 查找元素 查找子元素 獲取屬性組合使用示例使用場景案例介紹項目流程圖附加瀏覽器查找元素查找子元素遍歷循環獲取屬性點擊元素使用場景 在實際場景中&#xff0c;有時需RPA自動點擊某組范圍元素或獲取某組范圍元素的值&#xff0c;如需獲取指定的父元素&#xff0c;再…

【MongoDB與MySQL對比】

MongoDB 與 MySQL 全方位對比分析在現代軟件開發中&#xff0c;數據庫的選擇直接影響系統性能、擴展性和開發效率。MongoDB 和 MySQL 作為兩種主流數據庫&#xff0c;分別代表了 NoSQL 和關系型數據庫的典型&#xff0c;各自在不同場景中發揮著重要作用。本文將拋開代碼示例&am…

Spring AI開發指導-對話模型

對話模型接口描述Spring AI基于Spring Cloud的架構體系&#xff0c;定義了一系列可擴展的API接口&#xff0c;支持對接不同類型的AI大模型的核心功能&#xff0c;這些API接口支持同步編程模式或者異步編程模式&#xff1a;接口ModelModel是同步編程模式接口&#xff0c;其參數支…