A tenant deploys a chat sidecar that runs inference for a few seconds per request. Under the device-plugin model that has ruled Kubernetes GPU scheduling for nearly a decade, that sidecar reserves an entire GPU — say, the 20 GB card in a 205-dollar-per-month Hetzner GEX44 — while using maybe a tenth of it. The rest of the card sits idle, invisible to the scheduler, billed to nobody and usable by nobody. That was tolerable when GPUs were a rare luxury. It is not tolerable when every AI-agent sandbox wants a slice of one.
Kubernetes' Working Group Device Management spent the last two release cycles replacing that model with Dynamic Resource Allocation (DRA): structured, attribute-based scheduling where workloads describe the device they need and the scheduler negotiates the match. This post is the concrete version of that story for a team running its own metal: what the group actually standardized, what coarse allocation costs a small fleet in real numbers, the exact checklist a Cluster-API-provisioned bare-metal fleet must wire up before it can offer tenants "deploy with a GPU," what is still not production-ready, and why AI-agent sandboxes — not web services — are forcing the move.
What WG Device Management actually standardized
For years the Device Plugin framework was the only way to consume accelerators: a pod requested an integer count of an opaque resource (nvidia.com/gpu: 1) and got a whole card or nothing. No fractional GPUs, no asking for a specific model or memory size, no expressing "two GPUs with an NVLink between them" — and the accelerators had to be pre-provisioned on the node before scheduling could even consider them.
DRA replaces integer counting with reasoning about devices. Its model deliberately mirrors persistent volumes: a DeviceClass (like a StorageClass) describes selectable device types, a ResourceClaim (like a PVC) states what a workload wants using CEL expression selectors over device attributes, and ResourceSlice objects published by node-local drivers advertise what hardware actually exists. Third-party vendors ship their own DRA drivers instead of bolting hacks onto the scheduler.
The maturity timeline matters because it tells you what to run today versus stage for later:
| Capability | Status | Notes |
|---|---|---|
DRA core API (resource.k8s.io/v1, structured parameters) | GA in 1.34, enabled by default since 1.35 | The baseline; safe to build on |
| NVIDIA GPU DRA driver | Donated to CNCF at KubeCon EU 2026 (Amsterdam) | Community-governed reference driver, no longer single-vendor paced |
Google TPU DRA driver (kubernetes-sigs/dra-driver-google-tpu) | Exists under kubernetes-sigs | Hardware is GCE-only, so this row is informational for bare metal |
| Device taints and tolerations | GA in 1.37 | Degraded or maintenance-mode devices excluded from scheduling like tainted nodes |
| DRA claim status with standard NIC data (KEP-4817) | Stable in 1.37 | Structured network-interface description for RDMA-hungry training jobs |
| Consumable capacity (fractional GPU requests) | Beta | Native "give me 4 GiB and 10% of a card" without annotations |
| Partitionable devices (MIG-style slicing via DRA) | Alpha | Advanced MIG management still needs the GPU Operator alongside DRA |
| KAI Scheduler (gang scheduling, topology-aware placement) | CNCF Sandbox (donated by NVIDIA from the Run:ai acquisition) | Needed for all-or-nothing multi-pod training, not yet graduated |
One honest scoping note before we go further: TPUs appear in the working group's charter and title, and the DRA driver for them is real. But you cannot buy a TPU for your own rack — that silicon only exists inside Google's datacenters. For a bare-metal fleet, the actionable surface of this whole roadmap is GPUs (and NICs via projects like DRANET). The good news is the API is vendor-neutral, so everything you build against DeviceClass and ResourceClaim transfers if your hardware mix ever changes.
What "whole GPU or nothing" costs a small fleet
Take a concrete node: a Hetzner-class GPU server with a single 20 GB RTX-class card at roughly 205 dollars per month. A platform packing tenant AI-agent sandboxes onto it has four options, and the cost per tenant diverges fast:
| Strategy | Tenants per 20 GB card | Isolation | Memory enforcement | Verdict |
|---|---|---|---|---|
| Dedicated whole GPU (device plugin) | 1 | Full (physical) | Total | Simple, wasteful: about 205 dollars per tenant per month |
| Time-slicing (device-plugin hack) | 4–8 (configured replicas) | None (shared context) | None — one tenant can OOM the rest | Cheap, unsafe for untrusted tenants |
| MIG partitions (datacenter cards only) | Up to 7 (profile-dependent) | Hardware partitions | Yes | Great isolation, but needs datacenter-class silicon plus the GPU Operator, not a single RTX-class card |
| DRA with consumable capacity | N, by requested GiB/compute share | Driver-level, improving | Yes, scheduler-enforced | The end state — but the fractional half is still beta |
The middle rows are why teams feel stuck today: time-slicing multiplies tenants per card but offers no memory fence between them, so one tenant's runaway inference job evicts everyone sharing the slice. MIG gives real partitions but demands datacenter GPUs and operator-managed lifecycle. DRA's consumable-capacity model is the first path to scheduler-enforced fractional sharing on ordinary cards — which is exactly why its beta status, not its API, is the gating question for production.
The wiring checklist: bare metal to "deploy with a GPU"
Here is the end-to-end list for a Cluster-API-managed fleet on owned machines, ordered the way you would actually build it. No cloud vendor's managed GPU node pool is coming to do any of these steps for you.
1. Split GPU nodes into their own MachineDeployment. Do not mix GPU and CPU workers in one MachineSet. A dedicated MachineDeployment (or Cluster API machine pool) for GPU nodes gives you a separate machine image, separate labels, and a taint such as nvidia.com/gpu: NoSchedule so ordinary web/worker pods never land on expensive silicon by accident. It also isolates the upgrade blast radius: driver and kubelet changes roll through the GPU pool on its own cadence.
2. Put the driver in the node image, not in a post-boot script. You have two credible options. The NVIDIA GPU Operator installs and manages drivers, container runtime hooks, and monitoring from inside the cluster — flexible, but it is another controller to operate. The alternative on immutable OSes is a Talos Linux NVIDIA system extension baked into the machine image, which matches the "snowflake-free node" discipline a CAPI fleet already wants. Either way, pin the driver version and validate it against your DRA driver version before rollout: "CUDA won't initialize" after a schedule almost always traces to a driver/plugin version skew, not to DRA itself.
3. Install the DRA driver and disable the device plugin on GPU nodes. On a fresh GPU pool this is a clean install of the CNCF-owned NVIDIA DRA driver as a DaemonSet. On a pool migrating from the old model, DRA and device plugins can coexist cluster-wide during the transition, but enable only one per GPU pool — set the GPU Operator's devicePlugin.enabled=false (or the equivalent node label your tooling uses) so the DRA driver's kubelet plugin owns allocation on those nodes. Managed Kubernetes makes the same choice mutually exclusive per pool; bare metal should too.
4. Label nodes so DeviceClass selectors have something to match. DRA's power is attribute-based selection ("H100 with 80 GB" versus "any GPU"), but attributes come from somewhere. Apply consistent node labels for accelerator presence, model, memory, and interconnect (nvidia.com/gpu.present=true, model and memory labels via Node Feature Discovery or your CAPI bootstrap data), then write DeviceClass resources with CEL selectors over those attributes. Your DeviceClass is now the tenant-facing menu: gpu-shared-small, gpu-whole-card, and later gpu-fractional map to different selectors and different prices.
5. Publish slices and teach tenants the claim flow. The DRA driver's node plugin publishes ResourceSlice objects advertising each node's devices; the scheduler matches them against ResourceClaim (or inline claim templates in the pod spec) referencing your DeviceClass. Tenant-facing, this means documenting one new pattern: instead of resources.limits: {nvidia.com/gpu: 1}, workloads carry a claim against a DeviceClass your platform defines. Keep one extended-resource-compatible path (DRAExtendedResource auto-creates claims for legacy nvidia.com/gpu requests) so existing manifests keep working during migration.
6. Plan maintenance with device taints and pool-aware scale-down. With device taints GA in 1.37, a degraded GPU or a node entering maintenance can be excluded from scheduling without cordoning the whole machine — taint the device, let the driver report it, and the scheduler routes around it. Pair this with Cluster Autoscaler (or your CAPI autoscaling setup) configured to respect GPU-pool scale-down delays: evicting a node mid-training-run because CPU looked idle is the classic autoscaler-meets-GPU footgun.
7. Watch claims, not just pods. DRA failures surface as ResourceClaims stuck in Pending with node-level driver reasons, not as unschedulable pods with familiar events. Add alerting on claims pending beyond a few minutes and log the driver reason per node — operators migrating from device plugins consistently report this as the observability gap that bites first.
What is still not ready
An honest maturity read, because adopting DRA's GA core does not mean every GPU problem is solved:
- DRA does not create fractional GPUs by itself. It represents device attributes and matches claims; actually carving a card into safe shares is the driver's job, and the consumable-capacity path that makes it native is still beta. Production fractional sharing today still leans on time-slicing or MIG with their known tradeoffs.
- Multi-tenant safety is not automatic. DRA gives drivers precise control over how resources are shared between containers and pods, but safe sharing on one card still needs driver and runtime enforcement — DRA-aware drivers that are not yet mature are exactly where production-readiness analyses say to keep the device plugin for now.
- Gang scheduling is Sandbox-grade. All-or-nothing placement for distributed training (every pod in the gang lands or none does) lives in the KAI Scheduler, which only entered CNCF Sandbox at KubeCon EU 2026. Single-pod topology-aware scheduling works through DRA itself; multi-node training orchestration wants Kueue/JobSet/LeaderWorkerSet patterns staged carefully.
- The ecosystem is mid-migration. HAMi — the heterogeneous-accelerator scheduler behind several large pooling deployments — only moved to CNCF Incubating in July 2026 and is rebuilding its core on DRA rather than annotations. Expect churn in third-party schedulers for another cycle or two.
The pragmatic posture for a small fleet: run DRA's GA core now for attribute-based whole-GPU scheduling (it is strictly better than integer counting the day you have two GPU models in one fleet), keep fractional and gang-scheduled workloads in staging until consumable capacity and KAI graduate further, and keep the GPU Operator around for MIG lifecycle regardless.
Why AI-agent sandboxes drive this, not web services
None of the above matters much if your tenants only deploy stateless web services. A web/worker pod wants CPU and RAM in predictable amounts for a long lifetime — the scheduler's oldest, most-solved problem. AI-agent sandboxes invert every one of those assumptions:
| Dimension | Web service | AI-agent sandbox |
|---|---|---|
| Accelerator need | None | Bursty: idle for minutes, then wants inference now |
| Sharing pattern | Bin-pack by CPU/RAM | Bin-pack by VRAM/compute share, with isolation between untrusted tenants |
| Placement sensitivity | Low (any node with headroom) | High (model locality, topology, NVLink/RDMA for multi-GPU) |
| Lifetime | Hours to months | Minutes to hours, then release the slice |
That table is the whole business case. Time-slicing without memory enforcement is disqualifying for untrusted tenants; whole-card dedication at 205 dollars per tenant per month prices the sandbox tier out of existence; and "any node with headroom" placement wastes the topology awareness that makes multi-GPU inference fast. DRA's claim model — request what you need, hold it briefly, release it — matches the sandbox lifecycle the way integer GPU counts never could. The moment a self-hosted PaaS wants agent sandboxes with optional GPU access rather than a hypothetical someday feature, this roadmap stops being upstream trivia and becomes a launch dependency.
The shift from counting GPUs to reasoning about them is the most consequential scheduler change since the device plugin itself — and unlike most Kubernetes features, its value concentrates in exactly the fleets with the least room to waste silicon. Wire up the GA core on a dedicated GPU pool now, and the beta half of the table becomes an upgrade, not a re-architecture.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. Star the repo on GitHub or deploy your first app today.



