# **用 DRA 重新定義 Kubernetes 網路:深度解析 CNI 的下一步與 KubeCon Japan 2025 實戰分享** > 本文成果承蒙陽明交大「高等教育深耕計畫」113 學年度第 2 學期「職涯學習助學金-校外職訓」計畫支持 嘿,各位 K8s 的好夥伴們,大家好! 在 Kubernetes 的世界裡,網路一直是個既核心又充滿挑戰的議題。長久以來,我們習慣使用 CNI (Container Network Interface) 來處理 Pod 的網路設定。而當需要為 Pod 掛載多張網卡時,Multus 幾乎是大家不約而同的選擇,它透過 CRD 和 Annotations 的方式,簡單有效地解決了多網卡問題。但你是否曾想過,這種依賴 Annotation 中夾帶 JSON 設定字串的方式,總感覺不夠「原生」?當叢集環境變得複雜,例如混合了不同硬體規格的節點時,靜態的網路設定檔就顯得捉襟見肘。 在日前的 KubeCon Japan 大會上,來自 Ericsson 的軟體工程師 Lionel Jouin 和 IBM Research 的研究科學家 Sunyanan Choochotkaew (Fan) 帶來了一場名為〈Reimagining Cloud Native Networks: The Critical Role of DRA〉的精彩演講。他們提出了一個極具前瞻性的觀點:利用 **Dynamic Resource Allocation (DRA)** 來徹底革新 Kubernetes 的網路管理模式。 這篇文章將為您深度拆解這場演講的精華,從 CNI 的現有瓶頸,到 DRA 帶來的全新思維,再到兩大關鍵 KEP 的技術細節與 Live Demo 的實戰展示,帶您一窺 Kubernetes 網路的未來樣貌。 #### **一、問題的起點:當前 CNI 框架的限制** 首先,我們來回顧一下 CNI 的基本運作模式。CNI 是一個 CNCF 專案,它定義了一套標準規範和函式庫,用來為 Linux 容器配置網路介面。在 Kubernetes 中,管理者或使用者需要預先定義好網路設定檔(通常是 JSON 格式),告訴 CNI 插件要如何為 Pod 設定網路,例如 IP 位址、路由等等。這個設定檔會被原封不動地傳遞給 CNI 插件去執行。 *圖說:傳統 CNI 模式下,設定檔 (config) 被直接傳遞給 CNI 插件,缺乏彈性。* 這個模式在同質化的單純環境中運作良好。但當場景變得複雜,問題就浮現了: 1. **缺乏彈性**:使用者必須預先知道所有網路細節。但在一個異質叢集(heterogeneous cluster)中,你無法預知 Pod 會被調度到哪個節點上,而不同節點的網路介面卡名稱、硬體特性可能完全不同。 2. **無法感知拓撲**:當你需要高效能運算,希望將 Pod 的 CPU 和網路卡(NIC)分配在同一個 NUMA 節點上以降低延遲時,現有的 CNI 框架很難滿足這種拓撲感知的需求。 3. **無法動態宣告**:使用者可能只想表達「我需要一張目前可用的、沒被佔用的高速網卡」,而不是指定具體的設定。目前的 CNI 框架無法處理這種模糊但合理的請求。 #### **二、思維轉變:從「網路管理」到「網路即設備」** 為了解決上述困境,講者提出了一個核心的思維轉變,這也是 DRA 發揮作用的關鍵: * **傳統視角**:網路設定是**管理員**的任務,CNI 是設定網路的**工具**。 * **DRA 新視角**:網卡是一種**使用者**可請求的**設備 (Device)**,而 CNI 則是用來**準備 (prepare)** 這個設備的工具。 *圖說:DRA 將網卡視為使用者可請求的設備,徹底改變了互動模式。* **什麼是 DRA (Dynamic Resource Allocation)?** 在 DRA 出現之前,Kubernetes 使用 Device Plugin 機制來管理 GPU 這類設備。Scheduler 只關心節點上「有沒有」以及「有幾個」可用的資源,它將 Pod 調度到滿足數量需求的節點後,剩下的分配工作就交給節點上的 Kubelet 和 Device Plugin 處理。 但 DRA 更進一步。它允許使用者提出更複雜、更具描述性的資源請求,例如「我需要一個由 foo-driver 管理的設備,且它必須和另一個由 bar-driver 管理的設備在拓撲上對齊」。DRA 引入了一個控制器模型,讓專門的 DRA Driver 可以向 Scheduler 公布節點上所有可用資源的詳細屬性(Attributes)和容量(Capacities),Scheduler 則根據使用者的宣告(Claim)來進行精準的、帶有預留(Reservation)性質的調度。 *圖說:DRA 透過 ResourceClaim、ResourceSlice 與 DRA-Driver 實現了更智慧的資源調度。* 基於這個強大的框架,講者提出了 **CNI-DRA-Driver** 的核心概念: 1. **使用 DRA 進行網路設備選擇**:允許對網路設備進行細粒度(fine-grained)和拓撲感知(topology-aware)的選擇。 2. **實現 CNI-DRA-Driver**:打造一個橋樑,讓 DRA 框架能夠呼叫並復用現有的 CNI 插件生態系。 3. **增強 DRA 以適應網路情境**:為 DRA 增加對網路至關重要的特性,如狀態回報和頻寬等可消耗資源的管理。 #### **三、技術核心:CNI-DRA-Driver 的三步工作流** `CNI-DRA-Driver` 的實現遵循一個統一的宣告式方法(Unified Declarative Approach),整個生命週期可以拆解成三個步驟: *圖說:CNI-DRA-Driver 的 Publish、Schedule、Configure 三步工作流。* 1. **Publish (發布)** 節點上的 `CNI-DRA-Driver`(通常以 Node Resource Interface (NRI) 插件形式運行)會偵測本機的所有網路介面,並將它們的詳細資訊,包括屬性(如 `vendor: "15b3"`)和容量(如頻寬),發布成一個名為 `ResourceSlice` 的 Kubernetes 物件。 2. **Schedule (調度)** 使用者在 Pod 的 spec 中定義 `resourceClaims`,指向一個 `ResourceClaimTemplate`。這個 Claim 描述了所需的網路資源規格。Kubernetes Scheduler 會檢視這些 Claim,尋找能夠滿足其需求的 `ResourceSlice`。一旦找到合適的節點,Scheduler 就在 `ResourceClaim` 物件中完成資源的預留,並將 Pod 調度到該節點上。 3. **Configure (設定)** 當 Pod 被調度到目標節點上後,Container Runtime 會觸發 `CNI-DRA-Driver`。Driver 讀取已經被 Scheduler 分配好的 `ResourceClaim`,從中獲取配置資訊(例如,使用 `macvlan` CNI 插件並橋接到 `enp0s10` 介面上),呼叫對應的 CNI 插件來完成 Pod 網路的實際設定。完成後,Driver 會將最終的資源狀態,如分配到的 IP、MAC 位址等,回寫到 `ResourceClaim` 的 `.status` 欄位中。 #### **四、賦能網路:兩大關鍵 KEP 深度解析** 為了讓 DRA 真正適用於網路場景,社群推動了兩個關鍵的 Kubernetes Enhancement Proposal (KEP)。  ##### **KEP-4817: Resource Claim Status for Network** * **痛點**:當我們動態附加了一個網路介面後,要如何得知它的運行狀態?例如它的 IP 位址、MAC 位址、是否準備就緒? * **解決方案**:KEP-4817 在 `ResourceClaim.status` 中增加了一個 `devices` 欄位。DRA Driver 可以在資源配置完成後,將詳細的設備狀態填充進去。對於網路設備,這裡面可以包含一個標準化的 `networkData` 結構,存放 `IPs`、`hardwareAddress` 和 `interfaceName` 等資訊。 * **價值**: * **實現原生網路服務**:`EndpointSlice-Controller` 可以直接從 `ResourceClaim.status` 中讀取 IP 位址來提供服務,而不再局限於 `Pod.Status` 裡的 PodIP。 * **增強可觀測性與除錯**:我們可以從 `conditions` 欄位中清晰地看到網路配置是否成功,以及失敗的原因。 *\ 見上圖:利用 `ResourceClaim.status`,`EndpointSlice-Controller` 可以為動態附加的網卡提供服務。* ##### **KEP-5075: DRA with Consumable Capacity** * **痛點**:在 Kubernetes 中,透過 annotation 設定的頻寬限制(如 `kubernetes.io/ingress-bandwidth`)並沒有保證性。你可以在兩個 Pod 上都宣告需要 10Gbps,而 Scheduler 依然可能把它們調度到同一張 10Gbps 的網卡上,導致資源競爭與超賣。 * **解決方案**:KEP-5075 引入了「可消耗容量 (Consumable Capacity)」的概念。 * 在 `ResourceSlice` 中,DRA Driver 可以標記一個設備是 `shared: true`,並定義其可被消耗的容量,例如 `bandwidth: 10Gi`。 * 在 `ResourceClaim` 中,使用者可以明確請求需要消耗多少容量,例如 `capacities: { bandwidth: 5Gi }`。 * **價值**:Scheduler 在調度時會真正計算並扣除這些被消耗的容量。這意味著你可以為 Pod 申請到**有保證的 (guaranteed)** 網路頻寬,從而實現真正的網路 QoS。 *\ 見上圖:KEP-5075 讓頻寬成為可被調度器計算和保證的「可消耗容量」。* ### Live Demo 實戰拆解 為了證明這套機制的可行性,講者現場進行了一場精彩的 Demo。我們來一步步拆解: 1. **環境準備**: * 一個有 3 個 worker node 的 Kind 叢集。 * `kind-worker` 和 `kind-worker2` 節點上各有一張名為 `enp0s10` 的網卡,而 `kind-worker3` 沒有。 * `CNI-DRA-Driver` 已部署並在運行。 2. **資源發布**: `CNI-DRA-Driver` 偵測到 `enp0s10` 網卡後,為 `kind-worker` 和 `kind-worker2` 各自生成了一個 `ResourceSlice`,其中宣告了 `enp0s10` 設備擁有 10Gi 的 bandwidth 容量。 3. **發起請求**: * 部署一個 `Pod-A`,它透過 `ResourceClaim` 請求 **10Gbps** 的頻寬,並指定要在 `enp0s10` 這個介面上建立 `macvlan` 網路。 * 部署一個 `Deployment-B`,它包含 3 個副本(replicas),每個副本請求 **5Gbps** 的頻寬,同樣是在 `enp0s10` 介面上。 4. **調度結果**: * `Pod-A` 被成功調度到 `kind-worker2` 上,並**獨佔**了該節點 `enp0s10` 網卡的全部 10Gbps 頻寬。 * 另外**兩個** `Pod-B` 被成功調度到 `kind-worker` 上。它們**共享**了該節點的 `enp0s10` 網卡,各自分配到 5Gbps 頻寬,合計用滿了 10Gbps。 * **第三個** `Pod-B` 處於 `Pending` 狀態。因為兩個 worker 節點的 `enp0s10` 頻寬都已被佔滿,叢集中已沒有任何節點能提供剩餘的 5Gbps 頻寬,調度失敗。 > 反正 Demo 結果完美展示了 DRA 如何實現帶有保證的頻寬分配與共享。 5. **狀態驗證**: 檢查 `Pod-A` 對應的 `ResourceClaim`,我們可以在 `.status.allocation.results` 中看到 `consumedCapacities: { bandwidth: 10Gi }`,證明容量確實被記錄。同時,在 `.status.devices` 中可以看到 `networkData` 裡包含了分配到的 IP (`10.10.1.2/24`) 和 MAC 位址。`exec` 進入 Pod 內部執行 `ip a`,可以看到一張名為 `net1` 的網卡,其 IP 和 MAC 與 `ResourceClaim` 中的狀態完全一致,證明端到端的流程全部打通。 ## 前方的挑戰與討論:CNI 2.0 要來了嗎? 這項技術雖然前景光明,但前方的路並非一片坦途。講者也坦誠地提出了幾個待解的挑戰: 1. **如何整合龐大的 CNI 生態系?** * **方案一:一個 CNI 插件對應一個 DRA Driver。** 這會導致互通性極差,且不同 Driver 可能會重複宣告相同的底層資源(如 `macvlan` 和 `vlan` driver 都看上了 `eth0`),造成混亂。 * **方案二:通用的 CNI-DRA-Driver。** 這是 Demo 中採用的方法。由一個通用 Driver 負責暴露所有網路資源屬性和容量。但當遇到像 OVS、VPP 這種擁有複雜 Data Plane 的 CNI 時,通用 Driver 可能難以處理其特殊性。 * **方案三:帶有 CNI 操作的通用 Driver (CNI 2.0)。** 這是最理想的「架構完美」狀態。讓 CNI 規範升級,賦予 CNI 插件自行發布其資源和能力的能力。但推動一個被數十個組織廣泛使用的標準升級到 2.0,其難度可想而知,Q\&A 環節中甚至有聽眾開玩笑說「不知道我的孫子輩能不能用上」。 2. **如何從 Multus 遷移?** Multus 作為當前的事實標準,其簡單性是巨大優勢。DRA 方法雖然功能強大,但也更複雜。如何提供一個平滑的遷移路徑,是未來需要解決的重要問題。在 Q\&A 中,講者也提到,與其依賴各雲端廠商格式可能不同的 annotation,不如擁有一個原生的、標準化的 API 來獲取 IP 等狀態,這對上層基礎設施控制器更為友好。 3. **如何處理異質節點的介面名稱問題?** Q\&A 中有聽眾提出了非常實際的問題:Demo 中寫死了 `enp0s10`,但在真實世界中,不同節點的網卡名稱可能不同。講者的思路是,在 `ResourceClaim` 中不應直接指定介面名稱,而是透過**選擇器 (selector)** 去匹配介面的屬性,例如 `device.attributes["..."].vendor == "15b3"` 或是一個自定義的標籤。然後,CNI 的設定本身需要支持**模板化**,在運行時將 Scheduler 分配的實際介面名稱動態替換進去。 #### **結論與展望** DRA 為 Kubernetes 的網路管理帶來了一場深刻的變革。透過將網路資源「設備化」,我們得以用一種更原生、更宣告式、更具彈性的方式來請求和管理網路。 ResourceClaim Status (KEP-4817) 和 Consumable Capacity (KEP-5075) 等提案的推進,為實現這一願景鋪平了道路。這不僅僅是技術上的演進,更是 Kubernetes **Multi-Network** SIG 努力多年的目標——在 Kubernetes 中提供原生網路附加(Native Network Attachment)功能的關鍵第一步。 至於我們是否需要一個全新的 **CNI 2.0**?這是一個開放性的問題。或許我們不需要等待一個完美的 2.0 橫空出世,而是可以透過對 1.0 的擴展(例如增加 gRPC 模型、補全驗證能力等),以一種向後兼容的超集(superset)方式,漸進地走向未來。 這趟旅程才剛剛開始,如果你對此感興趣,強烈建議關注並參與以下社群的討論: * **CNI (Container Network Interface)** * **WG Device Management** (主要討論 DRA) * **Multi-Network SIG** * **K8s Network Plumbing WG** (主要討論 Multus) 感謝 Lionel Jouin 與 Sunyanan Choochotkaew 的精彩分享,他們為我們揭示了 Kubernetes 網路令人興奮的未來。讓我們一起期待並參與這場變革吧!
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up