【云原生】動態資源分配(DRA)深度洞察報告

1. DRA 的發展與設計靈感

Kubernetes 早期通過 Device Plugin(設備插件)機制支持 GPU、NIC 等特殊硬件,將節點上可用設備數量上報給 kubelet 和調度器。但設備插件模式存在局限:調度器只能根據節點標簽等屬性粗粒度篩選,無法精準指定某型號/屬性的設備;此外調度器與設備插件缺乏聯動,可能把 Pod 調度到尚未準備好相應設備的節點上。結果就是難以滿足復雜場景下對特定硬件的精細化需求。

為解決上述問題,Kubernetes 引入了 動態資源分配(Dynamic Resource Allocation, DRA) 新機制。DRA 借鑒了持久卷(Persistent Volume)動態供應的理念,將其泛化用于通用資源。它定義了一套類似 PVC/PV 的聲明式接口,讓外部第三方驅動負責實際資源管理,由 Kubernetes 根據資源聲明自動協調調度和分配。通過 DRA,用戶可以:在不同 Pod 或容器間共享同一個資源實例,根據自定義約束精確匹配所需資源,并在運行前按需初始化資源——這些都是傳統設備插件難以實現的功能。

DRA 的演進歷程體現了社區在探索通用設備管理方面的逐步改進。最初的 DRA 提案在 Kubernetes 1.26 引入(Alpha 特性),采用了PodScheduling(或稱 PodSchedulingContext)中介對象讓調度器和驅動通過 API 反復協調來選定資源。這種“驅動參與調度決策”的方案提供了高度靈活性(驅動可以定義任意參數決定如何選資源),但帶來了復雜的多輪交互,并使集群自動擴縮容難以預測資源需求。因此社區在后續版本引入了“結構化參數”模型,對 DRA 設計進行重構。在 Kubernetes 1.30 起增加結構化參數支持,1.32 將其提升為默認實現,并移除了早期 Alpha 實現(即所謂“經典 DRA”)相關代碼。新的 DRA 模型讓資源參數對調度器透明,由調度器直接基于參數匹配分配資源,提高了調度效率和可預見性。這一演進過程體現了 DRA 設計在靈活性與系統協調性之間尋找平衡的發展思路。


2. DRA 的設計哲學

  • 統一抽象:
    DRA 將各種類型的可配置硬件資源抽象為統一的資源聲明(ResourceClaim)來請求和使用。無論是 GPU、NPU、FPGA 還是特殊網卡,都通過類似的聲明方式提出請求,由 Kubernetes 按照聲明去滿足。正如官方所述,DRA “是持久卷 API 在通用資源上的泛化”。這種統一模型意味著不同硬件資源不再需要各自定制核心調度邏輯,而是在相同框架下處理。通過在聲明中附加結構化參數,用戶可以細粒度指定資源要求(例如 GPU 型號、性能指標),Kubernetes 調度器則能夠識別并據此篩選資源。相比設備插件時代只能通過節點標簽挑選節點,DRA 提供了標準化的接口描述資源需求和屬性,實現“一次設計,通用適配”不同設備類型。更重要的是,DRA 支持資源實例的共享和復用:例如多個 Pod 可以共享同一加速器實例,或同一 Pod 的多個容器共同使用由一個 ResourceClaim 提供的設備。這一切都在統一的抽象下完成,極大提高了靈活性。

  • 資源分層解耦:
    DRA 延續了 CSI 等架構的分層理念,將資源管理職責清晰地劃分給調度器、控制器和節點插件三個層次。首先,調度器負責全局的資源調配決策:它根據集群中公布的可用資源信息,決定 Pod 應該落在哪個節點以及使用哪個具體資源。調度器本身并不直接了解硬件細節,而是利用結構化的資源描述(如屬性、容量等)進行匹配過濾,然后預留所選資源供該 Pod 使用。其次,控制平面控制器(運行在 kube-controller-manager 中或作為獨立運營商)處理資源聲明的生命周期:當用戶部署工作負載時,控制器會根據 Pod 模板自動創建相應的 ResourceClaim,對接管理員預先配置的資源類(DeviceClass),并在適當的時候刪除不再使用的聲明對象。最后,節點插件(Node Plugin) 聚焦單節點上的實際操作:由第三方驅動提供的守護進程運行在每個節點上,負責發現本節點上的可用設備,向控制平面報告這些資源(例如創建/更新 ResourceSlice 對象),并在收到調度決定后執行設備的準備和清理。這種分層解耦確保了 Kubernetes 核心調度邏輯與具體硬件實現解耦:調度器專注于“在哪個節點用哪些資源”,節點插件專注于“如何在該節點實現資源供給”,中間通過聲明和對象狀態協作,而 PodSchedulingContext 這類中介對象在新模型中已不再需要。總的來說,各層各司其職,使系統更加模塊化和易于擴展維護。

  • 可插拔架構與可擴展性:
    DRA 設計的另一個核心理念是通過可插拔驅動實現對各種專用資源的支持,類似于 CSI 驅動之于存儲。Kubernetes 本身并不內置 GPU、FPGA 等具體資源的管理邏輯,而是定義好了通用 API 和調度流程,將“發現、分配、初始化”這些資源特定的工作下放給第三方 資源驅動(Resource Driver)。每種類型的特殊硬件只需由供應商或社區提供相應的 DRA 驅動,即可接入 Kubernetes。例如,集群管理員安裝某 GPU 廠商的 DRA 驅動后,創建對應的 DeviceClass 來定義這種設備的類別和選擇參數。之后用戶的工作負載就能通過引用該 DeviceClass 的 ResourceClaim 來申請該廠商的 GPU,加之必要的參數(比如顯存大小、計算能力等)。由于驅動的存在,Kubernetes 調度器和 kubelet 無需了解顯卡的內部細節,只需與驅動交互即可完成資源的分配與使用。這種架構極大增強了系統的可擴展性:新增硬件支持不需要修改 Kubernetes 本身,只需開發并部署一個符合 DRA 接口的驅動即可。值得一提的是,在最初的 Alpha 實現中,驅動擁有更大的自主權(可以通過自定義參數和 PodSchedulingContext 參與調度協商),而結構化參數模型則在一定程度上規范了接口形式。雖然這意味著未來若出現全新類型的硬件需求,可能需要先擴展 Kubernetes 對參數的支持,但在大多數場景下,這一可插拔框架已經能靈活滿足當前和未來的資源類型接入需求。


3. DRA 在 Kubernetes 框架側的實現

  1. 調度器中的 DRA 插件:
    DRA 引入了一款調度器插件(默認名為 DynamicResources)來擴展 kube-scheduler,使其具備感知和分配動態資源的能力。在調度流程中,該插件會在多個階段介入以確保 Pod 獲取所需的特殊資源:

    • 預過濾階段(PreFilter):調度器檢查待調度的 Pod 是否聲明了 ResourceClaim,以及這些聲明是否已綁定具體資源。如果聲明尚未分配且策略要求延遲綁定,調度器將進入動態資源處理流程。
    • 過濾階段(Filter):DRA 插件會根據每個候選節點上可用資源的情況,快速排除不滿足要求的節點。例如,若某 Pod 需要一塊具備特定屬性(如型號、顯存)的 GPU,插件將查詢集群中記錄可用設備的對象(即各節點的 ResourceSlice),判斷某節點是否有空閑設備匹配 ResourceClaim 中的選擇表達式。只有擁有滿足條件設備的節點才能通過此過濾。
    • 預留階段(Reserve):調度器從通過篩選的節點中選擇出一個最優節點(同時考慮常規資源要求,如 CPU/Mem),并在內部暫時鎖定該節點上的目標設備,以防止并發調度的其他 Pod 再次占用。
    • 預綁定階段(PreBind):調度器把挑選出的設備信息和任何供應商相關的配置寫入 ResourceClaim 的 .status 字段。例如,Claim 的狀態會注明分配到哪個節點、選中的設備標識符,以及驅動要求的配置參數數據。更新完成后,調度器正式將 Pod 綁定到目標節點(設置 Pod 的 nodeName),使調度決定生效。

    與早期 Alpha 方案不同,調度器在整個過程中無需與驅動直接通信;它依賴預先由驅動公布的結構化資源數據即可做出決策。這不僅減少了調度過程的往返,提高了效率,也讓調度器可以并行處理多個 Pod 的調度而不被外部請求阻塞。如果在最終綁定階段出現競爭條件(例如另一個 Pod 搶先占用了設備導致當前預留的設備不可用),調度器還會回滾相應的 ResourceClaim 分配并重新嘗試調度。總之,DRA 調度插件通過 Filter/Reserve/PreBind 等擴展點實現了特殊資源的感知與分配,把具體設備選擇融入了調度決策過程,實現 Pod 調度和資源分配的一體化。

  2. 控制平面 Controller 與資源聲明對象:
    為配合調度器完成上述流程,Kubernetes 在 API 層面引入了一組專門的資源對象來描述和跟蹤動態資源的請求與供給。主要包括:DeviceClass(設備類)、ResourceClaim(資源聲明)、ResourceClaimTemplate(資源聲明模板)和 ResourceSlice(資源片段)。

    • DeviceClass 類似于存儲中的 StorageClass,由集群管理員在安裝某個資源驅動時預先創建,定義了這類設備的選擇規則和默認配置。管理員可以創建一個 DeviceClass gpu.nvidia.com 來代表 NVIDIA GPU 設備,其內含的選擇器指定由哪個驅動器提供(如 device.driver == "nvidia.com")。
    • ResourceClaim 則類似于 PVC,是用戶或控制器發起的對某種資源的具體請求,包含了期望獲取的資源類型和數量,以及選擇/配置參數。
    • ResourceClaimTemplate 用于在工作負載(如 Deployment)的 PodSpec 中聲明需要某類資源時自動產生 ResourceClaim。例如用戶在 Pod 模板中引用某個 ResourceClaimTemplate,Kubernetes 控制器就會為每個 Pod 創建一個獨立的 ResourceClaim 來滿足其需求。
    • ResourceSlice(資源片段)由驅動在每個節點上發布,用于記錄節點上可用的具體設備信息,包括設備名稱、屬性、容量等,供調度器在分配時參考。

    當調度發生前,ResourceClaim 處于未分配狀態(status.allocation 為空)。調度器為 Pod 選定節點和設備后,會將設備信息寫入 ResourceClaim 的 status,標記該 Claim 已分配預留給相應的 Pod。此時 kube-controller-manager 內的一個控制器也會關注這些變化,承擔一些收尾工作,例如在 Pod 成功綁定節點后將 ResourceClaim 標記為“已預留”(Binding),或在 Pod 終止后刪除不再使用的 ResourceClaim。
    在當前的結構化參數模型下,不再使用 PodSchedulingContext 對象進行調度協調。但為了兼容或處理某些邊緣情況(例如 Pod 被靜態指定到節點而繞過了調度器),kube-controller-manager 仍包含邏輯檢查 Pod 對應的 ResourceClaim 是否已被正確分配和預留,必要時補償分配,以避免 Pod 永久處于無法運行的狀態。總體而言,控制平面的各個組件確保了 ResourceClaim 從創建、分配到釋放的完整生命周期閉環。通過 ResourceClaim 和 DeviceClass 等對象,Kubernetes 將復雜的資源請求參數、分配決定記錄在 API 對象中,這不僅讓調度器和 kubelet 等組件可以協同工作,也為管理員和用戶提供了觀察和管理資源分配狀態的窗口。

  3. Kubelet 中的 DRA Manager:
    當 Pod 經過調度器綁定到節點后,節點上的 kubelet 接過接力棒,負責最終將特殊資源交給 Pod 使用。Kubelet 啟動了一個 DRA 管理器 來處理與資源驅動的交互。每種第三方資源驅動的節點插件通常通過 kubelet 的插件注冊機制進行注冊(類似 CSI 驅動的注冊過程),注冊時會使用 DeviceClass 對應的驅動名稱。這樣 kubelet 才能識別并調用該驅動的 gRPC 服務。

    對于一個即將在本節點運行的 Pod,kubelet 會檢查其規范中的 resourceClaims 列表,找到對應的 ResourceClaim 對象。一旦發現這些 ResourceClaim 已由調度器分配了具體設備(即 ResourceClaim.status 中有了分配信息),kubelet 就會調用驅動的 NodePrepareResources gRPC 接口,請求驅動在節點上為這些資源做好準備。這個調用會將 Pod 需要的一個或多個 ResourceClaim 傳遞給驅動,并包含調度器記錄的設備標識及相關參數。節點插件驅動據此執行實際操作,包括但不限于:檢查設備是否空閑、為即將運行的容器做好設備初始化或配置工作,以及將設備暴露給容器使用。對于 GPU 設備,NodePrepareResources 可能無需太多配置即可返回成功;但對于 FPGA,驅動或許需要在這里下發比特流將 FPGA 配置成特定邏輯;又比如對于支持 SR-IOV 的智能網卡,驅動需要在這里為即將運行的 Pod 分配一個虛擬功能(VF)并掛載到容器網絡命名空間。由于各種資源的準備操作是高度設備相關的,因此由廠商驅動在此實現自定義邏輯。準備完成后,驅動會通過 gRPC 響應返回設備引用給 kubelet。Kubernetes 使用了一套行業標準的設備接口 —— CDI(Container Device Interface) 來描述容器可用的設備。驅動通常返回一個或多個 CDI 設備字符串(例如形如 "vendor.com/device=name" 的標識),kubelet 據此將設備分配寫入 Pod 的運行時配置。當 kubelet 調用容器運行時(如 containerd、CRI-O)啟動容器時,這些 CDI 設備會被掛載/注入容器,使其擁有對硬件的訪問權限。需要注意容器運行時需開啟對 CDI 的支持。

    在 Pod 終止后,kubelet 會再次通過 gRPC 調用驅動的 NodeUnprepareResources 接口,讓驅動執行清理操作。驅動應釋放該 Pod 占用的設備,例如解除對設備的占用鎖定、回收設備的臨時配置或斷開 VF 連接等,恢復設備到空閑狀態以便后續 Pod 使用。如果 ResourceClaim 是一次性使用的(比如由模板創建且 Pod 已完成),kubelet 和驅動還會協調移除與該資源相關的臨時文件或狀態,然后 kube-controller-manager 會刪除對應的 ResourceClaim 對象。通過 NodePrepare/NodeUnprepare 這一對接口,Kubernetes 完成了從調度到運行的最后閉環,確保設備的正確交接和善后。整個節點側流程對上層而言是可插拔的 —— 新硬件只需提供對應實現即可掛接到 kubelet。而 kubelet 提供的 gRPC 服務也允許查詢當前運行 Pod 的動態資源使用情況(例如外部監控系統可以通過 kubelet 提供的接口了解某 Pod 使用了哪塊設備,這對于資源審計和監控很有價值)。


4. DRA 驅動層面的實現

  1. 驅動接口要點與 gRPC:
    開發一個 DRA 驅動與編寫 CSI 存儲驅動有異曲同工之處,需要實現規定的 gRPC 接口以與 kubelet 和 Kubernetes 協作。對于 DRA,驅動主要關心節點服務(Node Service) 接口,包括前述的 NodePrepareResources 和 NodeUnprepareResources。這些接口在 Kubernetes 源碼中的 proto 定義明確了調用契約:NodePrepareResources 接受一組 ResourceClaim 請求,返回對應每個請求的處理結果;NodeUnprepareResources 則用于釋放。驅動在啟動時需要監聽一個 Unix 域套接字,并使用約定的插件注冊機制向 kubelet 注冊自己的存在(通常在 /var/lib/kubelet/plugins_registry/ 下創建一個帶有驅動名的注冊文件)。注冊過程中,驅動會表明自己的名稱(必須與 DeviceClass.spec.driver 字段匹配)和所支持的接口版本,kubelet 據此建立起與驅動的 gRPC 通道。之后,當有 Pod 需要該驅動管理的資源時,kubelet 就會調用相應接口完成準備/清理。

    對于實現者來說,確保線程安全和冪等非常重要:kubelet 可能會因網絡或系統原因重試 NodePrepare,因此驅動實現需能識別重復請求并保證不產生沖突。另外,NodeListAndWatchResources 是另一個接口,用于讓驅動向 kubelet 報告節點上可用資源變化,其作用類似于傳統設備插件的 ListAndWatch。當驅動在節點上監測到新設備接入或設備失效時,可以通過這個流式接口通知 kubelet 更新資源狀態。不過在 DRA 結構化模型下,集群總體的資源可用信息主要通過 ResourceSlice 在控制平面反映,NodeListAndWatch 在當前實現中更多用于驅動內部同步和調試用途。

  2. 節點插件示例代碼解析:
    一個完整的 DRA 驅動通常由集中控制器節點插件兩部分組成,但在結構化參數模型下,其控制器邏輯相對簡化,而節點插件是核心。我們以一個支持 GPU 的示例驅動來說明實現細節:

    • 資源發現(Discovery):
      節點插件啟動時首先掃描本節點的硬件資源。例如,通過讀取 /dev 或系統接口列出所有 GPU 設備,以及它們的屬性(型號、顯存大小、GPU UUID 等)。然后,節點插件需要將這些信息報告給 Kubernetes 控制平面。通常的做法是由驅動在集群中定義并維護對應的 ResourceSlice 對象。ResourceSlice 的設計允許驅動將一個節點上的多個設備信息打包發布。驅動會創建(或更新)屬于本節點的 ResourceSlice,其中列出每個設備的名稱(一個惟一標識符,如 PCI 地址或序列號)和屬性、容量等元數據。ResourceSlice 還包含 nodeName 字段指向所屬節點,以及一個 pool 信息用于分片管理。節點插件定期或在資源變動時更新 ResourceSlice,使調度器始終能獲取最新的可用資源清單。

    • 調度適配(Allocation):
      當集群中有 Pod 提出資源請求(ResourceClaim)后,調度器會據此在 ResourceSlice 中尋找匹配的設備。如果某請求包含對 GPU 型號和顯存的要求(通過 DeviceClass 的 selectors 或 ResourceClaim.spec.devices.selectors 表達),調度器將篩選出 ResourceSlice 中滿足條件的設備列表,并挑選其中一個將其分配。調度結果寫入 ResourceClaim.status,包括設備標識符和驅動配置數據。此時,從驅動的角度看,它并未直接參與上述調度決策過程,而是通過之前提供的 ResourceSlice 信息間接地影響了調度結果——這是結構化參數模型的特點。

      對于驅動開發者來說,需要確保 ResourceSlice 中公布的信息足夠全面,能表達各種調度所需的篩選條件(比如添加恰當的 device.attributes)。同時驅動可以利用 DeviceClass 預先設定一些通用篩選規則,減少每次聲明需要重復提供的參數。例如 DeviceClass 本身也支持 selectors,Pod 的 ResourceClaim 若引用某 DeviceClass,則自動繼承其中定義的篩選條件。總之,調度適配階段驅動的主要工作是在調度前提供準確的資源視圖和篩選機制,使調度器能夠正確地匹配請求到具體設備。

    • 設備準備與掛載(Preparation & Mounting):
      當 Pod 被調度到本節點后,節點插件正式介入執行 NodePrepareResources 調用。以 ResourceClaim 已分配具體 GPU 為例:kubelet 會將該 ResourceClaim(包含設備 ID)傳給驅動的 NodePrepareResources 方法。示例驅動在收到請求后,會在其維護的設備列表中找到這個設備。如果設備當前空閑且狀態正常,驅動即可著手為容器準備它。對于 GPU,一般準備工作可能包括檢查驅動模塊已加載、為容器創建設備文件和訪問控制等。假設設備無需特殊初始化,則直接生成對應的 CDI 設備條目,比如 "vendor.com/gpu=0000:03:00.0-0x56a0" 并通過 NodePrepareResourcesResponse 返回給 kubelet。kubelet 隨后將其加入容器的 CDI 設備清單,使容器啟動時自動獲得對該 GPU 設備的訪問權限。如果驅動需要執行較復雜的初始化(如 FPGA 下發比特流),也可在此處完成。
      值得一提的是,CDI 提供了抽象設備標識的方法,驅動需要在節點預先安裝相應的 CDI 規格文件,將實際設備路徑與一個 CDI 名稱關聯。NodePrepareResources 返回的就是這個映射名,容器運行時據此查找并掛載實際的 /dev 設備進去,實現了對容器透明且標準的設備接入。

    • 資源回收(Unprepare):
      當 Pod 使用完畢(容器退出或 Pod 刪除)時,kubelet 將調用 NodeUnprepareResources。示例驅動接收到該請求后,會執行和準備階段相對應的清理操作。對于 GPU 場景下,可能需要釋放設備的獨占鎖、移除臨時的 CDI 設備文件等;在其他硬件場景下,還可能涉及撤銷之前的配置(例如將 FPGA 恢復為空閑位流,或釋放 SR-IOV 分配的 VF)。驅動在完成清理后向 kubelet 確認。隨后 kubelet 就會卸載容器,移除設備訪問。對于通過 ResourceClaimTemplate 創建的臨時 ResourceClaim,對應的對象也會被刪除,驅動應確保自身對該 Claim 的任何引用也一并清除。如果驅動需要在 ResourceClaim 刪除前執行自定義清理,可以在 ResourceClaim 上添加自己的 finalizer,實現定制的刪除處理順序。總之,正確實現 NodeUnprepareResources 可確保設備狀態良好地返回池中,不會因為上一個 Pod 的遺留設置而影響下一個 Pod。

值得注意的是,Kubernetes 提供了一些輔助庫來簡化 DRA 驅動的開發。例如,在最初 alpha 實現中,社區提供了樣板代碼用于集中控制器與調度器的交互,使驅動開發者只需關注具體的資源分配邏輯。隨著新模型的采用,驅動控制器主要負責 ResourceSlice 等 CR 的維護,這部分可以直接使用 Kubernetes 客戶端庫來實現 watch/update 循環;節點插件部分則可以參考 Kubernetes 項目中的示例實現(如 test/e2e/dra 路徑下的 ExamplePlugin)。在實際場景中,不同類型設備的驅動可能還需要和廠商提供的底層庫或內核接口交互,如調用英偉達的管理庫獲取 GPU 拓撲信息,或調用專用 CLI 來控制 FPGA。這些都屬于驅動的業務邏輯范疇,可以自由發揮,而 Kubernetes 只要求驅動遵守接口契約和使用定義的 CRD 來與系統集成。通過閱讀和參考社區提供的 KEP 文檔和示例代碼,新硬件資源的接入成本已大大降低。


5. 完整 DRA 工作流回顧

綜合以上組件,我們以一個實際流程梳理 DRA 從請求到分配再到釋放的全過程:

  1. 用戶提交 Pod
    開發人員在 Pod 模板中聲明需要特殊資源。例如,在 PodSpec 的 resourceClaims 字段中引用一個 ResourceClaimTemplate,描述需要“一塊 NVIDIA A100 GPU,加上20GB顯存和特定驅動配置”。集群管理員事先已創建對應的 DeviceClass(如 nvidia.com/gpu)供該模板引用。用戶提交 Deployment 或 Pod 后,控制器檢測到其中的資源聲明模板,于是自動創建了一個 ResourceClaim 對象表示該 Pod 所需的 GPU。該 ResourceClaim 指定了 deviceClassName 為 nvidia.com/gpu,以及選擇器表達了對“A100型號且顯存≥20Gi”的要求。此時 ResourceClaim 處于未分配狀態。

  2. 調度器分配資源并選定節點
    當該 Pod 排入調度隊列準備調度時,DRA 調度插件介入。它從集群中獲取所有 GPU 資源的可用情況——這些信息由 NVIDIA 驅動通過 ResourceSlice 事先發布,例如節點 node1 上有4塊不同的 GPU(包含若干A100),node2 上有2塊等。調度器首先篩選出有滿足請求條件(A100且空閑)的節點集合,然后調度器結合其它調度條件(CPU/Mem 空閑情況、拓撲約束等)選擇了其中一個最合適的節點,比如 node1。隨后,DRA 插件在調度決策中為該 Pod 預留 node1 上的一塊具體 GPU(假設序列號為 GPU-1234)給這個 ResourceClaim,并將此分配結果寫入 ResourceClaim.status。狀態中記錄了 nodeName=node1,deviceName=GPU-1234,以及相關的驅動參數(如顯存分區模式等,如有)。完成資源分配標記后,調度器將 Pod 綁定到 node1 節點。

  3. 節點驅動準備資源
    node1 上運行的 kubelet 收到新 Pod 要求啟動的通知。它看到 Pod 需要一個 GPU,并且對應的 ResourceClaim (status)已經指明應使用本節點的 GPU-1234。于是 kubelet 調用本地 NVIDIA 驅動的 NodePrepareResources gRPC 接口,傳入該 ResourceClaim 的信息。NVIDIA 驅動的節點插件查找本機設備列表確認 GPU-1234 空閑可用,然后執行準備操作:加載必要的驅動內核模塊、為容器創建設備節點以及設置訪問控制等。如果該 GPU 支持 MIG 分區且請求指定了劃分(假設 Pod 只需一半 GPU 算力),驅動還會在此刻將 GPU 劃分出一個實例。準備完成后,驅動返回一個描述這個 GPU 實例的 CDI 設備名稱,例如 "nvidia.com/gpu=GPU-1234-idx0"。kubelet 收到成功響應,便將該 CDI 設備加入容器配置,并開始創建容器。容器運行時(如 containerd)解析 CDI 名稱,在 GPU 驅動預先提供的 CDI 規格文件中找到對應的實際設備(例如 /dev/nvidia0),將其掛載到容器的 /dev 中。最終,Pod 中的應用進程啟動并擁有對所請求 GPU 資源的訪問權。至此,從用戶聲明到實際獲得硬件資源,DRA 的主要流程全部走通。

  4. 運行期監控(可選)
    Pod 運行過程中,Kubernetes 并不干涉已分配資源的使用,但提供了監控接口。kubelet 上的資源報告服務可允許管理員或監控系統查詢當前節點上哪些 Pod 占用了哪些動態資源。這對于審計和性能分析很有幫助,例如運維人員可以通過該接口確定某 GPU 正在被哪個 Pod 使用,并結合 GPU 溫度、功耗指標定位問題。DRA 驅動本身也可以上報更細粒度的狀態信息,如利用率等(未來版本中ResourceClaim Device Status特性可能允許驅動直接更新 ResourceClaim.status.devices 字段來反映設備運行狀態)。這些機制進一步完善了資源使用的可見性。

  5. Pod 結束和資源回收
    當用戶的工作負載結束,Pod 刪除或終止時,kubelet 會著手清理分配的 GPU。它調用 NVIDIA 驅動的 NodeUnprepareResources,傳入此前的 ResourceClaim 標識 GPU-1234(以及 MIG 分區信息)。驅動收到請求后,撤銷對該 GPU 的分配:如果劃分了 MIG 實例則銷毀該實例,恢復 GPU 為完整資源;清除容器環境中為該 Pod 配置的任何臨時狀態(例如釋放顯存、重置功率限制等)。完成后驅動確認釋放成功。隨后,kubelet 將容器停止并卸載。對于通過 ResourceClaimTemplate 創建的臨時 ResourceClaim,kube-controller-manager 在確認對應 Pod 已刪除后,會自動刪掉這個 ResourceClaim 對象。GPU-1234 現在重新回到資源池中,ResourceSlice 會更新顯示其空閑可用狀態,調度器即可將它分配給后續的 Pod 請求使用。通過上述工作流可以看到,DRA 將 Kubernetes 現有的調度機制、聲明式 API 與底層驅動的硬件操作有機結合,實現了從 Pod 提交到硬件就緒的全自動管理,大幅減少了人工介入和配置錯誤的可能。


6. 總結與展望

動態資源分配(DRA)的引入,標志著 Kubernetes 在管理通用硬件資源方面邁出了重要一步。通過借鑒持久卷的模式并結合結構化參數,DRA 實現了對 GPU、FPGA、專用網卡等設備資源的通用化、聲明式管理,不僅解決了傳統設備插件無法精細選取和缺乏調度協同的問題,還帶來了資源共享、延遲綁定、初始化配置等能力。在當前(v1.32)實現中,DRA 已作為 Beta 特性提供,用戶可開啟 DynamicResourceAllocation 特性后體驗其功能。得益于結構化參數模型,Kubernetes 調度器能夠更好地預測和掌控資源分配,這對集群自動擴容等上層決策尤為關鍵——調度器透明地了解資源供需,Cluster Autoscaler 也就能基于 ResourceClaim 的需求判斷是否需要增減節點,而不像早期方案那樣因邏輯隱藏在驅動中而無法判斷。可以預見,隨著 DRA 走向 GA,更多的云廠商和硬件供應商會提供與之兼容的驅動,將各式各樣的新硬件納入 Kubernetes 的調度管理范疇。

事實上,目前社區已經在討論將 DRA 擴展到管理網絡和拓撲資源、實現組合型資源調度等更復雜的場景。例如,有提案探討通過“代理”驅動將網絡拓撲信息引入調度決策,同時仍利用原廠設備驅動的初始化能力;又比如,未來可能支持可分割設備(Partitionable Device)的動態分配,當單塊加速器可按比例劃分給多個 Pod 時,如何通過 DRA 接口控制和匯報(目前 v1.31 尚未完全支持動態劃分,如 GPU SR-IOV)。這些都是 DRA 潛在的發展方向。

隨著容器運行時對 CDI 等標準的支持逐漸完善,以及 Kubernetes 對硬件異構資源需求的不斷提升,DRA 有望成為連接云原生調度和底層硬件的新干線。在不久的將來,我們或許會看到基于 DRA 的更豐富應用場景:例如 AI/ML 作業通過 DRA 精確選擇具備特定算力的 GPU,電信網絡工作負載使用 DRA 來調度專用加速卡,甚至用戶通過 Kubernetes API 就能完成對裸機設備的動態配置和調度。總之,DRA 正將 Kubernetes 的調度疆界從傳統的 CPU/內存擴展到整個數據中心的各種特殊硬件資源。在保持 Kubernetes 一貫的聲明式和自動化優勢的同時,DRA 仍有持續優化的空間,但其設計理念和框架已為未來打下堅實基礎。從設備插件到 DRA,我們見證了 Kubernetes 資源管理的演進;展望未來,DRA 將在社區的推動下不斷成熟,進一步釋放云原生對異構硬件的潛力。

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

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

相關文章

嵌入式八股ARM篇

前言 ARM篇主要介紹一下寄存器和中斷機制,至于匯編這一塊…還請大家感興趣自行學習 1.寄存器 R0 - R3 R4 - R11 寄存器 R0 - R3一般用作函數傳參 R4 - R11用來保存程序運算的中間結果或函數的局部變量 在函數調用過程中 注意在發生異常的時候 cortex-M0架構會自動將R0-R3壓入…

Python 實現的采集諸葛靈簽

Python 實現的采集諸葛靈簽 項目介紹 這是一個基于 Python 開發的諸葛靈簽數據采集和展示項目。通過爬蟲技術獲取諸葛神簽的簽文和解簽內容,并提供數據存儲和查詢功能。 項目結構 zhuge/├── zhuge_scraper.py # 爬蟲主程序├── zhuge_pages/ # 數據存儲目錄…

【C++項目實戰】校園公告搜索引擎:完整實現與優化指南

🎬 個人主頁:誰在夜里看海. 📖 個人專欄:《C系列》《Linux系列》《算法系列》 ?? 道阻且長,行則將至 目錄 📚一、項目概述 📖1.項目背景 📖2.主要功能 📖3.界面展…

代理(Delegate)、閉包(Closure)、Notification(通知中心) 和 swift_event_bus適用場景和工作方式

在 Swift 開發中,在 Swift 開發中,代理(Delegate)、閉包(Closure)、Notification(通知中心) 和 swift_event_bus 主要用于 組件之間的通信,但它們的適用場景和工作方式有…

設計模式--單例模式(Singleton)【Go】

引言 在設計模式中,單例模式(Singleton Pattern)是一種非常常見且實用的模式。它的核心思想是確保一個類只有一個實例,并提供一個全局訪問點。這種模式在需要全局唯一對象的場景中非常有用,比如配置管理、日志記錄、數…

MySQL數據庫復制

文章目錄 MySQL數據庫復制一、復制的原理二、復制的搭建1.編輯配置文件2.在主庫上創建復制的用戶3.獲取主庫的備份4.基于從庫的恢復5.建立主從復制6.開啟主從復制7.查看主從復制狀態 MySQL數據庫復制 MySQL作為非常流行的數據庫,支撐它如此出彩的因素主要有兩個&am…

Sourcetree——使用.gitignore忽略文件或者文件夾

一、為何需要文件忽略機制? 1.1 為什么要會略? 對于開發者而言,明智地選擇忽略某些文件類型,能帶來三大核心優勢: 倉庫純凈性:避免二進制文件、編譯產物等污染代碼庫 安全防護:防止敏感信息&…

基于yolov8+streamlit實現目標檢測系統帶漂亮登錄界面

【項目介紹】 基于YOLOv8和Streamlit實現的目標檢測系統,結合了YOLOv8先進的目標檢測能力與Streamlit快速構建交互式Web應用的優勢,為用戶提供了一個功能強大且操作簡便的目標檢測平臺。該系統不僅具備高精度的目標檢測功能,還擁有一個漂亮且…

分享vue好用的pdf 工具實測

vue3-pdf-app: 帶大綱,帶分頁,帶縮放,帶全屏,帶打印,帶下載,帶旋轉 下載依賴: yarn add vue3-pdf-appornpm install vue3-pdf-app 配置類: 創建文件 pdfConfig.ts /…

基于微信小程序開發的寵物領養平臺——代碼解讀

項目前端 一、項目的技術架構概況 一句話概括:該項目是基于微信小程序開發的寵物領養平臺,采用原生小程序框架進行用戶界面的構建,使用 wx.request 進行 API 請求,并通過 getApp() 和本地存儲來管理全局狀態和用戶信息。 一&am…

最完美的WPF無邊框設計!

常規的無邊框方法設計 常規的WPF無邊框設計方法都是通過AllowsTransparency="True"和WindowStyle=“None”,并且使用WindowChrome樣式來實現,但是這樣會有問題就是,窗體最大化的時候將底部任務欄給擋住了,另外最大化的時候不能拖動窗體。參考這個大佬的設計@ 若…

【區塊鏈】btc

學習視頻源鏈接: https://www.bilibili.com/video/BV1Vt411X7JF/ 本文是根據肖老師的視頻進行的筆記記錄 一、 cryptographic hash function 1.1. collision resistance抗碰撞性 : collision 指的是hash碰撞 抗碰撞性 (Collision Resistance) 是密碼…

C語言【數據結構】:時間復雜度和空間復雜度.詳解

引言 詳細介紹什么是時間復雜度和空間復雜度。 前言:為什么要學習時間復雜度和空間復雜度 算法在編寫成可執行程序后,運行時需要耗費時間資源和空間(內存)資源。因此衡量一個算法的好壞,一般是從時間和空間兩個維度來衡量的,即時…

QT:文件讀取

問題: 在文件讀取,判斷md5值時,遇到py文件讀取轉String后,再轉byte,md5前后不一致問題。 解決方法: python文件讀取要使用QTextStream,避免\t 、\r、\n的換行符跨平臺問題(window…

32單片機——LED

LED原理圖如圖所示: 代碼 DS0和DS1每過500ms一次交替閃爍,實現類似跑馬燈的效果 GPIO輸出配置步驟 (1)使能對應GPIO時鐘 STM32在使用任何外設之前,我們都要先使能其時鐘(下同)。本實驗用到…

貪心算法和遺傳算法優劣對比——c#

項目背景:某鋼管廠的鋼筋原材料為 55米,工作需要需切割 40 米(1段)、11 米(15 段)等 4 種規格 ,現用貪心算法和遺傳算法兩種算法進行計算: 第一局:{ 40, 1 }, { 11, 15…

【Java篇】一法不變,萬象歸一:方法封裝與遞歸的思想之道

文章目錄 Java 方法的使用:從基礎到遞歸的全面解析一、方法的概念及使用1.1 什么是方法 (method)?1.2 方法定義1.3 方法調用的執行過程1.4 實參和形參的關系1.5 沒有返回值的方法 二、方法重載2.1 為什么需要方法重載2.2 方法重載的概念2.2.4 C 和 Java 的比較&…

深入理解 HTML 中的<div>和元素:構建網頁結構與樣式的基石

一、引言 在 HTML 的世界里&#xff0c;<div>和元素雖看似普通&#xff0c;卻扮演著極為關鍵的角色。它們就像網頁搭建過程中的萬能積木&#xff0c;能夠將各種 HTML 元素巧妙地組合起來&#xff0c;無論是構建頁面布局&#xff0c;還是對局部內容進行樣式調整&#xff…

《大語言模型》學習筆記(一)

一、什么是大語言模型 大語言模型是指在海量無標注文本數據上進行預訓練得到的大型預訓練語言模型&#xff0c;例如GPT-3&#xff0c;PaLM和LLaMA。大語言模型&#xff08;Large Language Model&#xff0c;LLM&#xff09;是一種基于深度學習的自然語言處理模型&#xff0c;能…

電力行業中分布式能源管理(Distributed Energy Management System, DEMS)的實現

以下是電力行業中分布式能源管理(Distributed Energy Management System, DEMS)的實現方案,涵蓋系統架構、關鍵技術、核心功能及實施路徑,結合典型場景與代碼示例: 一、系統架構設計 采用云-邊-端三層架構,實現分布式能源的高效協同管理: 1. 終端層(感知層) 設備組…