# **用 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
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.