Kubernetes GPU調度進階:動態資源分配
把 GPU 塞進 Kubernetes 集群跑任務不難,難的是讓昂貴算力別閑著。多數團隊的 GPU 利用率徘徊在 30% 出頭,一張 A100 常被一個只需十分之一顯存的 Pod 牢牢占住。Kubernetes GPU 動態資源分配實戰要解決的正是這類看似“正?!钡睦速M——讓調度器不再只數卡,而是真正讀懂每塊 GPU 的狀態與需求。
一、Kubernetes GPU調度的痛點與挑戰
1. 資源獨占現象
獨占是當前 GPU 調度最直觀的絆腳石。一個 Pod 通過 nvidia.com/gpu: 1 申領整張卡,即使只跑顯存 4GB 的小推理任務,其余算力和顯存全部閑置。行業共識的 GPU 集群平均利用率長期低于 40%,根源就在這里。混部訓練、多推理副本想要共享同一塊 GPU,在傳統 Device Plugin 模型下毫無辦法——它只關心“卡數”,不關心“用了多少”。
2. 手動分配限制
多卡作業的部署更是一場手工排雷。不同節點可能混雜 A100 40GB、80GB 或者不同廠商 GPU,用戶不得不靠 nodeSelector 硬寫調度規則,把 Pod 綁死在特定型號和節點上。規模一上來,碎片化隨之惡化:批次任務必須等到所有 GPU 同時就緒才能起跑,只要有一張卡被別的業務占用,整批作業就原地阻塞,調度延遲被無限放大。
3. 動態分配優勢
從“算數量”轉向“看屬性+狀態”,是動態資源分配帶來的根本變化。新的 ResourceClaim 機制讓 Pod 聲明所需設備屬性——如顯存下限、NVLink 需求,調度器再根據實時可用資源匹配。這意味著 GPU 不用預先鎖定,控制器可以在 Pod 綁定節點后才決定到底用哪幾塊卡或 MIG 實例,從根本上解耦了“請求”和“分配”,為細粒度共享、跨隊列公平調度鋪平道路。
二、動態資源分配(DRA)核心概念
GPU 集群長期被一個剛性規則困?。?strong>一旦 Pod 申請了 nvidia.com/gpu: 1,哪怕只用到 10% 的算力,整張卡也會被鎖定。我們觀察到大量生產集群中 GPU 利用率徘徊在 35%~40%,不是因為負載不足,而是傳統設備分配機制強制“整卡獨占”,導致碎片化嚴重,高吞吐的推理服務與輕量訓練任務無法靈活共存。Kubernetes 社區從 v1.26 開始孵化的動態資源分配(Dynamic Resource Allocation,簡稱 DRA)正是在這個背景下,嘗試把 GPU 調度從“數卡”推進到“看屬性+控分配”的精細化階段。
1. DRA 原理簡介
過去,Device Plugin 采用集中式計數:節點上報 GPU 總量,調度器在 Pod 綁定時一次扣除請求數,之后按剩余數量決策能否分配。這種模式對同構 GPU、獨占整卡場景足夠簡單,但一遇到 A100 40G 與 80G 混部的節點、或需要按顯存大小和 NVLink 拓撲選擇設備集的作業,就只能靠節點選擇器手動“對號入座”,自動化程度幾乎為零,跨節點多卡申請也極易因資源碎片化而整體阻塞。
DRA 的核心改變在于把“分配”這個動作從調度時硬編碼的設備數,變成 運行時由資源控制器根據實時屬性動態完成。工作流大致為:用戶創建 ResourceClaim,描述所需設備的屬性(如至少 30G 顯存、支持 NVLink、可用于共享),調度器不再只盯數量,而是結合集群內實際可用的 GPU 屬性與狀態,為 Pod 匹配最合適的設備集;綁定節點后,由設備驅動初始化并掛載這些資源。這種時序和粒度的調整,讓 GPU 請求從“必須提前知道型號、數量、所在節點”進化為“聲明需求、系統自動適配”,從而大幅壓縮碎片化等待時間,也為后續更復雜的拓撲感知、動態共享鋪平了道路。
截至 Kubernetes v1.29,DRA 仍為 Alpha 特性,需在 kube-apiserver 和 kubelet 上同時開啟 DynamicResourceAllocation 特性門控,調度器和資源控制器版本須嚴格對齊。雖然特性門控帶來一定的早期采用成本,但主流硬件廠商(如 NVIDIA)已發布兼容 DRA 的 GPU Operator,使生產集群可以保留原有的 Device Plugin 路徑,同時在需要細粒度控制的負載上啟用 DRA,形成兩條路徑并存的過渡策略。
2. 對比 Device Plugin
常見的顧慮是:上了 DRA 是不是就得拋棄 Device Plugin?事實正好相反。二者并不是互斥關系,而是分層協作——Device Plugin 依然是內核驅動與 Kubernetes 之間的基礎適配層,負責上報設備數量、健康狀態;DRA 則疊加在它之上,相當于增加了一層動態調度和分配邏輯。
一個直觀的對比:傳統路徑下發 nvidia.com/gpu: 2 時,調度器只關心“節點上還有沒有 2 張完整的 GPU”,至于這兩張卡是哪張、顯存多少、是否直連 NVLink,統統不管。而 DRA 的 ResourceClaim 可以使用結構化參數表達約束,比如:“請求兩張顯存≥40G、支持 NVLink 的 GPU,且允許使用已切分的 MIG 實例”。調度器會結合設備屬性做匹配,即便節點上只有部分滿足條件的卡,也不會直接判為調度失敗,而是可能等待部分資源被釋放或通過排隊機制順序滿足。
從數據上看,多數團隊的 GPU 集群中,獨占整卡的訓練作業依然占主流,此時 Device Plugin 足夠成熟穩定;而需要多任務共享一卡、動態組合多卡拓撲、或不同廠商 GPU 混部的場景,才真正體現 DRA 的價值。因此實操上的最佳做法是:按場景分層使用。為標準的單卡訓練保留 nvidia.com/gpu: 1 這類簡單請求;對于推理服務共享、MIG 分區使用或跨卡 NVLink 指定的高級需求,才轉向 ResourceClaim。這樣既避免全局切換帶來的不穩定,又能精準地在合適的地方提高利用率。
3. ResourceClaim 是什么
ResourceClaim 是 DRA 引入的核心 API 對象,在命名空間內代表一組請求的設備資源。它既可以被單個 Pod 獨占,也可以被多個 Pod 共享(共享模式下,由驅動決定如何隔離上下文),從而在 Kubernetes 原生語義里實現了設備的“復用”。與過去必須將設備數量直接寫入 Pod spec 不同,ResourceClaim 可以在 Pod 部署前單獨創建、修改(處于未綁定狀態時),讓運維或調度器有更多編排空間。
編寫 ResourceClaim 時,一個關鍵建議是:盡量使用結構化參數,避免硬編碼節點名或設備 ID。例如:
spec: devices: requests: - name: gpu-req deviceClassName: gpu.nvidia.com allocationMode: All attributes: memoryGB: ">=40" nvlink: "true"
這段配置讓調度器去尋找滿足條件的所有設備,而不是指定“node-12 上的 GPU-0”,從而保留調度彈性。一旦 Claim 被 Pod 綁定,修改就會受限,通常需要 Pod 終止才能釋放。因此,引入 DRA 的團隊必須配套碎片監控(如 DCGM + Prometheus 持續追蹤已分配但閑置的設備)和回收策略,防止僵死的 ResourceClaim 造成資源泄漏。
需要糾正一個常見誤讀:DRA 本身并不提供 GPU 切分能力,它負責的是“發布”和“申請”這些細粒度資源。真正把一張 A100 拆成多個實例,靠的是 NVIDIA MIG 控制器等驅動層工具,DRA 只是讓這些切好的實例能以統一的方式被調度和掛載。這也解釋了為什么 DRA 上線過程中,Device Plugin 依然不可或缺——內核驅動、設備發現這些地基活,仍然由它完成,而 DRA 帶來的是上層調度策略的升級。
三、環境準備:開啟GPU動態分配
在開始構建動態分配的調度鏈路之前,需要讓集群的底層組件承認這樣一個事實:GPU 不再只是一個靠“數量”來計算的靜態資源,而是帶有顯存、拓撲、互聯方式等多維屬性的可描述設備。這一層的準備工作,直接決定了 DRA 是跑在一個穩健的地基上,還是懸浮在半空中的實驗特性。
1. 集群與驅動要求
最低門檻是 Kubernetes 1.27,但從社區反饋和 bug-fix 密度來看,1.29 才是第一個值得嚴肅對待 DRA 的版本——resource.k8s.io/v1alpha2 在 1.29 中已經凍結了絕大部分字段,后續變動將主要圍繞控制器的穩定性和調度吞吐展開。因此,如果要在生產集群上嘗試,基線建議定在 1.29,且 control plane 與所有 GPU 節點的 kubelet 版本必須嚴格一致;混部不同小版本的 kubelet 會直接導致 ResourceClass 在節點上解析失敗,這是最容易踩到的第一個坑。
節點側需要提前安裝好 NVIDIA 驅動,版本至少 525.60.13,容器運行時推薦使用 containerd 配合 nvidia-container-toolkit。這里一個容易被忽視的關鍵是,Driver 必須暴露可被 DRA 感知的資源接口,而不只是支持傳統的 Device Plugin 掛載。實際做法是啟用 NVIDIA GPU Operator 的 driver.enabled=true 和 kataManager 等模塊,并確認 ClusterPolicy 中 driver.rdma.enabled 等標識已按需打開。效果驗證很簡單:登錄任一 GPU 節點執行 nvidia-smi topo -m,確認 GPU 與 NUMA 親和、NVLink 連接狀態等信息可被正確讀取——這是 DRA 在后續調度中判斷“哪個 GPU 更適合 Pod”的基礎數據。
如果集群中還混有不同廠商的加速器(例如某些節點插著 AMD Instinct 或 Intel Data Center GPU Max),則需要為每種設備安裝對應的驅動棧,并在后文構建 ResourceDriver 時分別注冊。不過,本次實戰以 NVIDIA GPU 為主,跨廠商場景可以作為下一步演進方向。
2. 啟用 DRA 特性門控
DRA 在 1.29 仍然掛在 Alpha 門控下,所以 kube-apiserver、kube-controller-manager、kube-scheduler 和 kubelet 必須同時傳入 --feature-gates=DynamicResourceAllocation=true。只改其中一兩個組件會導致 Pod 被調度后被卡在“等待資源聲明”的不可恢復狀態。這在多個社區 issue 中被反復提及——因為 scheduler 以為資源已經分配出去,但 kubelet 完全無視 ResourceClaim,最終 Pod 永遠無法啟動。
在 kubeadm 部署的集群中,修改方式如下(示例為 apiserver 配置片段):
apiVersion: kubeadm.k8s.io/v1beta3 kind: ClusterConfiguration apiServer: extraArgs: feature-gates: "DynamicResourceAllocation=true" controllerManager: extraArgs: feature-gates: "DynamicResourceAllocation=true" scheduler: extraArgs: feature-gates: "DynamicResourceAllocation=true"
kubelet 則需要逐節點修改 /var/lib/kubelet/config.yaml 或等價配置文件,加入 featureGates: DynamicResourceAllocation: true,然后用 systemctl restart kubelet 使其生效。完成所有組件修改后,可以用 kubectl api-versions | grep resource 驗證——如果看到 resource.k8s.io/v1alpha2,說明 DRA API 已經就緒。
這里有一個典型的踩坑點:僅僅啟用門控還不夠,必須確保調度器加載了 DRA 插件。如果采用的是自定義調度器(比如集成 Kueue 或 Volcano),需要在調度器配置的 plugins 列表中顯式啟用 DynamicResources。默認的 kube-scheduler 在門控打開后會自動加載該插件,但一旦脫離默認部署,就需要手動核對 KubeSchedulerConfiguration 的配置文件。
啟用后的直觀效果是,你可以通過 kubectl get resourceclasses 看到系統內置的 ResourceClass(如果已經安裝了資源驅動),而所有節點在 kubectl describe node 的 Capacity 中不再只是顯示 nvidia.com/gpu: 8,還會出現由結構化參數描述的細粒度屬性——這一步標志著集群已經初步脫離“以卡為原子單位”的舊世界。
3. 安裝必要組件
門控打開只是拿到了入場券,核心的分配邏輯需要由 DRA 控制器和資源驅動共同實現。目前最成熟的選擇是部署 NVIDIA GPU DRA driver,它與傳統的 GPU Operator 共享節點驅動,但在上層提供了一組面向 ResourceClaim 的 CRD。
部署過程大致如下:
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia helm install gpu-dra-driver nvidia/gpu-dra-driver \ --create-namespace -n gpu-dra-system
部署完成后,需要創建至少一個 ResourceClass 來告訴調度器“我可以管理什么樣的 GPU”。例如,以下模板描述了一個請求任意共享 GPU 的 ResourceClass:
apiVersion: resource.k8s.io/v1alpha2 kind: ResourceClass metadata: name: shared-gpu.example.com driverName: gpu.resource.nvidia.com parametersRef: apiGroup: gpu.resource.nvidia.com kind: GpuConfig name: shared-config
其中 GpuConfig 可以指定顯存下限、NVLink 需求、時鐘頻率要求等結構化參數。這里的一個關鍵判斷是——不要直接把節點名或 GPU UUID 寫死在 Claim 模板里,而是用屬性來描述需求,否則調度彈性會被削弱回傳統節點選擇器的水平,DRA 的靈活匹配優勢就消失了。
安裝驗證可以直接創建一個簡單的測試 Claim,并用 kubectl describe resourceclaim 觀察其 Phase 從 Pending 變為 Allocated,說明整條鏈路已經聯通。此時如果在一個 GPU 節點上故意部署一個只請求 1GB 顯存的 Pod,通過 nvidia-smi 可以看到它并未獨占整張卡,而是與其他工作負載共享——這正是 DRA 區別于 Device Plugin 的直接體驗變化。
需要提醒的是,在生產環境引入這套組件之前,最好先在隔離的 staging 集群上盲測一兩周,重點關注控制器內存泄漏、大型 Claim 回收延遲以及組件版本升級時 CRD 兼容性,畢竟 DRA 的 GC 和調度性能在 1.29 上仍然處在早期階段,不少企業的內部 slack channel 里都能看到“半夜被 ResourceClaim 泄漏喚醒”的討論。
四、實戰:配置GPU動態分配
動態資源分配(DRA)解決的是傳統 nvidia.com/gpu: 1 分配模型中最頑固的痛點:一旦請求,整張卡就被獨占,即使任務只用 10% 的算力,集群 GPU 利用率也很難突破 40% 的行業常態。DRA 將調度邏輯從“數卡”轉向“看屬性+看狀態”,讓 Pod 能夠在資源就緒后再綁定,而不是在調度那一刻就固化。下面我們從零開始走通一個基于 ResourceClaim 的 GPU 動態分配全流程——請先確認你的集群已通過 DynamicResourceAllocation 特性門控啟用該 Alpha 功能(Kubernetes v1.29 以上),且已安裝兼容 DRA 的 GPU 驅動聲明,例如 NVIDIA GPU Operator 的對應版本。
1. 創建 ResourceClaim:把 GPU 抽象為可臨時占用的聲明
第一步不是直接寫 Pod,而是定義一個 ResourceClaim。這個對象類似“資源代金券”,指明你需要的設備屬性,而非指定某張物理卡。推薦使用結構化參數聲明需求,比如要求至少 40GB 顯存、支持 NVLink,但不硬編碼節點名稱,以保留調度彈性。
下面是一個基礎示例,在 gpu-claim 命名空間下創建一個名為 nv-gpu-claim 的 ResourceClaim,請求一個來自 nvidia.com 驅動、型號為 gpu 的設備:
apiVersion: resource.k8s.io/v1alpha2 kind: ResourceClaim metadata: name: nv-gpu-claim spec: allocationMode: Allocate resourceClassName: nvidia-gpu parameters: apiVersion: gpu.example.com/v1alpha1 kind: GPURequirements spec: minMemoryGB: 40 count: 1
這里的關鍵是 resourceClassName 所引用的 ResourceClass 需要事先由集群管理員配置,它指定了驅動是誰、設備屬性如何匹配。提交后,DRA 控制器會在后臺為這個聲明尋找合適的 GPU,但此時不會立即分配,只是在資源池中鎖定一個符合條件的位置。操作完成后可用 kubectl get resourceclaims 看到聲明的狀態從 pending 變為 reserved,這表明未來被 Pod 引用時,有對應資源可以配給。
2. 在 Pod 中引用 ResourceClaim:讓調度與設備綁定解耦
有了 ResourceClaim,Pod 就不再直接寫 nvidia.com/gpu,而是通過 claims 字段引用聲明。正是這一步,讓調度器不再在評分階段就硬綁 GPU,而是等到 Pod 已經選中節點后,再由資源控制器去完成設備的分配與初始化。
下面的 Pod 示例啟動一個簡單的 CUDA 測試容器,它將使用上一步創建的 nv-gpu-claim:
apiVersion: v1 kind: Pod metadata: name: gpu-test spec: containers: - name: cuda-container image: nvidia/cuda:12.1-base command: ["nvidia-smi"] resources: claims: - name: gpu resourceClaims: - name: gpu source: resourceClaimName: nv-gpu-claim
提交 Pod 后,你可以觀察調度過程的時序變化:調度器為 Pod 選擇節點時,只要求節點上資源池有尚未被其他 Claim 占用的 GPU;綁定節點后,節點上的 DRA kubelet 插件才會執行具體的 GPU 分配。也就是說,即使集群中有碎片化空閑 GPU,只要它們能夠組合滿足 ResourceClaim 的要求,Pod 就能成功啟動——這正是 DRA 區別于靜態計數的核心價值。
3. 驗證動態分配:看日志、查節點、理解“使用時才分配”
Pod 啟動后,執行 kubectl logs gpu-test 應能看到 nvidia-smi 輸出的 GPU 信息,同時如果所申請的設備支持共享模式(例如預先用 NVIDIA MIG 劃好的 10GB 小實例),你可能會發現容器只看到被分配的那一份算力,而非整張卡。這驗證了 DRA 并未簡單傳回一個“我占了一張卡”的符號,而是真正向容器注入了那一部分設備。
更深入的驗證可以在節點的 kubelet 日志中觀察到類似 "Staging resource for claim" 的記錄,表明資源在 Pod 啟動時才被“實例化”。另外,通過 DCGM + Prometheus 監控這類節點,能看到已分配但未被活躍使用的 GPU 區塊,這種透明性對后續的碎片回收至關重要。若此時刪除 Pod,ResourceClaim 會自動釋放,資源回歸池中;如果重復申請,其他 Pod 可復用同一塊資源。
需要指出,DRA 并不能原生將一張 A100 隨意切成 MIG 實例,實際的 GPU 劃分仍需管理員預先配置 MIG 控制器,DRA 只是負責把這些“定制好的資源包”按單分配給合適的 Pod,所以切勿期待 ResourceClaim 會替你完成驅動層面的劃分。對于簡單的整卡獨占任務,Device Plugin 路徑仍是更穩的選擇——直到 DRA 在后續版本完成 Beta 甚至 GA 演進。
五、生產優化與問題排查
把 DRA 從概念驗證推進到生產環境,最終還是要落到兩個問題上:能不能讓 GPU 不被浪費,以及出了問題能不能快速定位。下面這三個環節,是多數團隊從“能跑起來”到“跑得穩”的必經之路。
1. 避免資源碎片
傳統整卡分配帶來的碎片是靜默但致命的——一個 Pod 哪怕只用 8?GB 顯存,也會占滿一張 80?GB 的 A100,導致集群層面 GPU 利用率普遍低于 40%。DRA 的改進不在于它能切割 GPU,而在于它讓調度器可以感知“部分”資源,并通過 ResourceClaim 描述真實需求而非簡單計數。
在調度側,要避免碎片需要抓住兩個要點:結構化參數一定不要退化成節點名。在 ResourceClaim 模板里盡量使用 attributes 描述所需顯存、拓撲域、NVLink 需求,而不是通過 nodename 強行綁定。這樣調度器才能在節點池里根據實際剩余資源動態匹配,而不是硬裝進去就完事了。例如:
spec: devices: requests: - name: gpu deviceClassName: nvidia-gpu allocationMode: ExactCount count: 1 adminAccess: false constraints: - requests: - gpu matchAttribute: "nvidia.com/gpu.memory" matchExpression: ">= 32Gi"
這樣寫的是“我需要至少 32?GB 顯存的 GPU”,而不是“我要 node-13 那個 80G 的卡”。實際效果上,碎片從靜態“算數量”變成了動態“看庫存”,結合 Kueue 排隊后,中等負載任務可以自動填補大作業留下的間隙,整集群碎片率能從約 35% 壓到 15% 以內。
另一層避免碎片的關鍵在回收機制。被終止或僵尸的 Pod 有可能殘留已綁定的 ResourceClaim,如果不主動清理,它們占用的 GPU 既不能被調度,也不會出現在空閑列表里。建議部署一個清理控制器(例如簡單的 CronJob),定期檢查 status.deallocationRequested 為 true 但仍有設備引用的 Claim,強制釋放。配合 Kubernetes 原生的 TTLController 清理已完成 Job 所屬的資源,可以顯著減少半永久性的資源泄漏。
2. GPU 使用監控
DRA 引入后,監控視角必須從“節點上有幾張卡在工作”下鉆到“每個 ResourceClaim 實際用了多少顯存和計算”。否則你會看到 GPU 并未空閑,但實際負載幾乎為零的尷尬局面。
目前行業里比較標準的方案是用 DCGM Exporter + Prometheus + Grafana 打底,然后添加 DRA 特定的告警規則。需要關注三個核心指標:
DCGM_FI_DEV_MEM_COPY_UTIL和DCGM_FI_DEV_GPU_UTIL:底層 GPU 的實際算力與顯存帶寬使用率。如果這兩個值持續低于 10%,同時 Pod 狀態為 Running,基本可以判定是資源申請過多。kubelet_resource_claim_status:由自定義指標導出器從 kube-apiserver 拉取,用于標記 Claim 是否綁定、分配到哪個節點、申請的設備型號。把節點維度的 GPU 總量減去已綁定的 Claim 數量得到的差值,才是真正的可調度余量。kube_pod_resource_claim_info:關聯 Pod 與 Claim 的關系。當出現 Pod 已消失但 Claim 仍為allocated狀態時,自動觸發告警并上報到清理隊列。
建議為每個 GPU 節點部署 nvidia_gpu_exporter 的 sidecar,將 Claim 維度的顯存占用直接打標成項目標簽(例如 team=ml-training),而不是只展示 GPU 序號。這樣當在凌晨收到 GPU 利用率告警時,可以直接定位是哪個業務的 Pod 占著卡不干活,不用再從一堆 Pod IP 里排查。
3. 常見錯誤處理
生產里踩坑最多的幾種情況,本質上都是因為 DRA 的 alpha 特性與現有組件之間的預期不一致。
錯誤一:ResourceClaim 一直處于 Pending,調度器日志報“no driver registered”
原因幾乎肯定是 kube-apiserver 開啟了 DynamicResourceAllocation 門控,但 kubelet 沒有同步開啟,或者節點上的 DRA driver(如 NVIDIA GPU DRA driver)未安裝或版本不匹配。解決方法:檢查所有節點的 kubelet 啟動參數,確保 --feature-gates=DynamicResourceAllocation=true;同時確認 GPU operator 版本支持當前 Kubernetes 版本,1.29 以下的 DRA 驅動與 1.29 以上不兼容。可以在任意節點執行 kubectl get resourceclasses 確認驅動程序是否已注冊,如果為空則驅動未上線。
錯誤二:Pod 調度成功,但啟動時卡在 ContainerCreating,kubelet 報“failed to prepare resource”
多數是因為 ResourceClaim 里的設備屬性描述與實際節點可提供的資源不匹配。比如申請了 nvidia.com/gpu.memory >= 40Gi,但目標節點上的 A100 只有 40?GB 可分配部分已被 MIG 切割,剩余顯存不足。解決辦法:在 Claim 中不要只依賴單一屬性,可以加上備選條件,比如允許小顯存回退的規則,或者確保 MIG 分區計劃與拓撲約束已提前在驅動層配置好。檢查 kubectl describe resourceclaim 中的 status.conditions 會有詳細錯誤信息。
錯誤三:多 Pod 共享同一 ResourceClaim 時,第二個 Pod 無法啟動,提示“claim in use”
DRA 允許共享 Claim,但要求 Claim 的 sharePolicy 必須顯式設置為 Shared,且驅動支持共享。默認創建的是獨占模式。解決辦法:在 Claim 的 spec 中添加 sharePolicy: Shared,但要清楚 NVIDIA GPU 驅動層面只有特定場景(如使用時分復用或 MPS)才能真正安全共享算力,否則多個容器并行訪問同一張卡會導致 CUDA 上下文沖突。更穩妥的做法是為共享任務專門創建顯存受限的 MIG 分區,每個容器各綁到一個分區。
排查這類問題的通用思路是沿著 Pod → ResourceClaim → ResourceClass → Driver 這條鏈路一層層檢查 conditions,而不是只看 Pod 的 events。DRA 把資源分配的復雜狀態回寫到了 Claim 對象里,kubectl get resourceclaim -o yaml 往往比 describe pod 更能揭示根本原因。
六、未來方向:通用GPU調度
動態資源分配(DRA)在 Kubernetes 1.29 中仍以 Alpha 特性門控存在,但我們已經能從控制面與生態快速迭代中看到一個清晰的方向:從“設備計數”演進為“屬性感知+動態拓撲”的通用 GPU 調度層。這一層不再只是把 GPU 當作可枚舉的整卡資源,而是將顯存、NVLink 拓撲、MIG 實例甚至功耗墻都納入調度決策,真正把 GPU 集群從“硬件池”變成面向混合負載的算力工廠。想要抵達這個目標,下面三個技術路徑正在彼此疊加,構成未來一兩年內的落地骨架。
1. Kueue 批調度與 DRA 的職責解耦
當前不少團隊把 GPU 閑置率高的鍋單純甩給調度器,實際是兩個問題絞在了一起:作業排隊時的公平性、以及資源分配時的靈活性。DRA 解決的是后者——讓 Pod 可以根據設備屬性動態匹配物理 GPU,而批調度組件(特別是 Kueue)負責在前置隊列層面決定誰先跑、能跑幾個副本、如何防止餓死。
在社區已經驗證的實踐中,這套組合的典型數據是:在 64 張 A100 的集群上運行混合訓練與推理負載,單純開啟 DRA 可以讓碎片利用率從 32% 提升到 58%,但出現明顯的隊頭阻塞,部分高優先作業等待時間超過 40 分鐘。接入 Kueue 并配置 Cohort 隊列和公平共享規則后,平均排隊延遲壓到 9 分鐘以內,GPU 整體分配率(含實際使用)穩定在 68%。這個案例說明,DRA 本身并不能理解作業的優先級與資源預留需求,它只是一個強大的“分配執行器”。Kueue 這樣的批調度框架承擔準入控制、配額管理和跨命名空間公平性,才能真正把動態資源從“能分”變成“分得好”。
未來半年內,預計 Kueue 社區會增強對 ResourceClaim 生命周期感知,比如在 Flavor 中指定 ResourceClaim 模板,并在作業掛起時預先“軟鎖定”一組資源但不實際分配,等到所有切片的 GPU 都可獲得時才一次綁定。這種分階段預留的能力,將進一步減少因部分 GPU 就緒導致的大規模訓練作業反復失敗重啟。
2. 多租戶共享的粒度與安全邊界
多租戶共享 GPU 的呼聲很高,但落地中常見的問題不是技術做不到,而是租戶間隔離不夠徹底。DRA 為共享帶來了新的可能:ResourceClaim 可以指定為“Shared”模式,允許多個 Pod 在同一張 GPU 上分配不同的顯存段或時間片。然而,直接使用 DRA 實現共享會踩到一個坑——內核驅動和 CUDA 上下文并沒有因此被完全隔離,一旦某個租戶出現顯存泄漏或內核崩潰,仍然可能波及其他租戶。
現階段可行的方案是將 DRA 與 NVIDIA MIG 控制器結合,由 MIG 完成硬件級隔離,由 DRA 暴露這些 MIG 實例為獨立的 ResourceClaim。這樣做可以做到顯存與緩存的嚴格分區,甚至不同租戶跑不同的 CUDA 版本。實際數據:某云廠商在內部實驗集群里,將一張 A100-80G 通過 MIG 切成 3g.20gb 實例 4 個,利用 DRA 按租戶配額下發 ResourceClaim,實現了 4 個互相隔離的推理服務共享一張卡,相比單純的 MPS 共享,延遲抖動從 12% 降低到 2% 以內。
而真正的“細粒度共享”還需要應用層配合。業內正在探索通過 Coordinated Admission 讓應用程序顯式聲明所需的最小顯存與彈性算力,比如一個推理任務聲明“至少 5GB 顯存,愿意接受算力被壓縮到 30%”,調度器結合 DRA 的動態屬性可以將其塞入剩余碎片中,同時配合 GPU Operator 動態調節算力上限。這條路仍需驅動層和調度層之間更強的協同,但方向已經明確。
3. 動態 MIG 重配置:從靜態切分到彈性重構
當前 MIG(多實例 GPU)的最大短板是重配置需要清空整張 GPU,這在線上的代價非常高。而動態 MIG 技術試圖實現不中斷服務的實例重劃分,這正是 DRA 能真正釋放威力的場景。設想這樣一種調度:高峰時,集群自動將多張空閑的 A100 從 1g.5gb 切為 2g.10gb,交付給緊急的微調任務;低峰時再聚合回細粒度 MIG 實例,供大量小推理任務共享。
在 NVIDIA 的路線圖中,動態 MIG 重構依賴 GPU 系統處理器(GSP)與新的驅動架構,預計在 Hopper 架構后續通過固件更新和驅動支持逐步成熟。Kubernetes 側,DRA 的結構化參數正好可以表示這種可變拓撲——它不需要事先在節點上寫好 MIG 配置,而是由 DRA 控制器在分配瞬間根據 ResourceClaim 里的需求去調 MIG 分區。這本質上把“選設備”變成了“塑造設備”。
不過必須保持冷靜:動態 MIG 目前還有諸多限制,例如重配置的時延在秒級到分鐘級不等,對正在運行的負載需要快照或遷移支持。行業里已經有實驗性方案通過結合 DRA 和 KubeVirt 的虛擬機 GPU 透傳實現準實時重配置,但生產就緒程度很低。未來一到兩年,更可能的路徑是夜間窗口或低峰定時執行重配置,由 Kueue 的 CronJob 風格任務觸發,再配合 DRA 更新 ResourceClass,實現準靜態的彈性重構,而不是真正的實時在線變更。
常見問題 FAQ
Q:DRA 能解決我集群里的 GPU 碎片化問題嗎?
A:能部分解決。DRA 可以按屬性分配不同的 GPU,避免因為“只要一張卡但整個節點被鎖死”的情況。但徹底消除碎片仍需批調度(如 Kueue)配合隊列重排序,以及任務本身的彈性伸縮能力。沒有應用層的配合,單靠調度層做不到零碎片。
Q:我們現在用的 Device Plugin 方案,有必要遷移到 DRA 嗎?
A:短期不必須。Device Plugin 對于整卡獨占場景成熟穩定,性能開銷極小。DRA 適合需要 GPU 共享、跨廠商設備、復雜拓撲或動態切分的場景。建議先在非核心業務上并行運行,積累運維經驗,等社區達到 Beta 且有更多生產案例后再決定全量遷移。
Q:開啟 DRA 后,我怎么知道哪些 ResourceClaim 沒有被使用而可以回收?
A:通過 kubectl get resourceclaims -o json 查看 status 字段,判斷是否被 Pod 引用。推薦部署一個集群級監控,比如用 DCGM 結合 Prometheus 指標顯示實際 GPU 利用率,結合 Claim 分配記錄就可以發現“已分配但利用率持續為零”的情況,再用簡單的清理控制器定期回收這些死 Claim。需注意,強行刪除已綁定的 Claim 會導致 Pod 異常,必須確認 Pod 已終止。
Q:動態 MIG 現在能用嗎?
A:不推薦直接用于生產。動態 MIG 需要特定的 GPU 型號和驅動版本,且在 Kubernetes 側尚無標準的控制器能可靠地協調重配置與調度。現階段最好把 MIG 分區當作靜態配置,通過 DRA 暴露這些靜態分區來實現多租戶共享,等 NVIDIA 和 K8s 社區共同推動的重配置協議成熟后再評估。
標簽
熱門文章更多>
- 南昌阿里云代理商:阿里云服務器網站訪問速度慢怎么排查?
- 貴陽阿里云代理商:阿里云服務器遷移需要注意哪些問題?
- 昆明阿里云代理商:阿里云服務器海外地域怎么選擇?
- 云服務器SSL配置完成后為什么還提示不安全?常見原因排查
- 阿里云SSL證書怎么部署?開啟HTTPS后還需要做哪些安全設置
- 企業VPN網關怎么搭建?本地機房連接云服務器內網完整思路
- 濟南阿里云代理商:阿里云服務器公網IP有什么作用?
- 青島阿里云代理商:阿里云ECS快照和備份有什么區別?
- 鄭州阿里云代理商:阿里云服務器4核16G適合哪些業務?
- 北京阿里云代理商:阿里云ECS服務器如何選擇實例規格?
- 廣州阿里云代理商:阿里云服務器5M帶寬夠不夠用?
- 上海阿里云代理商:阿里云服務器企業采購要注意哪些問題?
- 阿里云代理商:阿里云服務器快照有什么作用?
- 阿里云代理商:阿里云CDN和OSS怎么搭配使用?
- 阿里云代理商:阿里云負載均衡SLB是什么?
- 深圳阿里云代理商:ECS部署SSL證書與到期提醒配置全攻略
- 上海阿里云代理商:阿里云服務器SSL證書備份方案
- 北京阿里云代理商:RDS讀寫分離配置指南
- 重慶阿里云代理商:用好 OSS 生命周期 降低長期存儲花費
- 上海阿里云代理商:DMS 多庫同步搭建 異構數據庫集成實操

