September 6, 2026 · 9 min read · Aizhan Azhybaeva

Kubernetes Dynamic Resource Allocation (DRA): The GPU Guide for 2026

Kubernetes Dynamic Resource Allocation went GA in 1.34. What DRA changes versus device plugins, how ResourceClaim, DeviceClass and ResourceSlice fit together, and a practical migration path for GPU clusters.

Kubernetes Dynamic Resource Allocation (DRA): The GPU Guide for 2026

Kubernetes Dynamic Resource Allocation is the API that finally lets you ask for hardware by describing it rather than counting it. Instead of nvidia.com/gpu: 1 and a pile of node labels and taints to make sure that “1” means the card you actually wanted, you write a claim that says “an H100 with at least 80GB, on the same NUMA node as this NIC” and let the scheduler find a node that can satisfy it. The core resource.k8s.io APIs graduated to GA in Kubernetes v1.34 and are on by default, and every release since has added capability on top.

This guide covers what DRA changes versus the device plugin model, how the object model fits together, how to migrate a GPU cluster without rewriting every workload, and the gotchas that show up first.

The short version

  • DRA is GA. ResourceClaim, ResourceClaimTemplate, DeviceClass and ResourceSlice are stable resource.k8s.io/v1 types from Kubernetes 1.34.
  • Device plugins still work. There is no announced removal date. DRA is where new capability lands, not a forced cutover.
  • Extended resource mapping is the migration bridge. A DRA driver can advertise a classic extended resource name, so existing Pod specs keep working. This reached GA in 1.37.
  • The win is expressiveness. Attribute selection, prioritized fallback lists, dynamic partitioning, device taints and NUMA-aware matching are things the device plugin API structurally could not do.
  • The cost is a new mental model plus a driver upgrade and a manifest conversion pass.

What was actually wrong with device plugins

The device plugin API has served Kubernetes well for years, and the reason it is being superseded is not that it was badly built. It is that it exposes exactly one primitive: a node advertises a count of a named resource, and a Pod asks for some of that count.

That single primitive forces every other requirement into workarounds:

  • Attributes become node labels. Want an A100 rather than an L4? You label nodes and add a nodeSelector. Now your scheduling logic lives in two places and drifts.
  • Topology becomes guesswork. GPU-to-NIC affinity and NUMA locality matter enormously for training throughput, and the device plugin API has no vocabulary for expressing them in a request.
  • Sharing becomes static. MIG partitions have to be decided by an operator ahead of time. If your workload mix changes on Tuesday, your partitioning is wrong until someone reconfigures nodes.
  • Fallback is impossible. “Give me an H100, or an A100 if none is free” cannot be expressed. You either write two job variants or you queue.
  • Every vendor invents its own conventions. Two accelerator vendors on one cluster means two sets of labels, two taint schemes and two mental models.

DRA replaces the counter with a query. Devices publish structured attributes, claims select against those attributes, and the scheduler does the matching as a first-class part of the scheduling decision rather than as a post-hoc node filter.

The object model in plain terms

Four objects carry the whole design. Learn these and the rest follows.

ObjectWho creates itWhat it does
DeviceClassCluster admin or driverA named category of device with common selectors and config. The thing workload authors reference.
ResourceSliceThe DRA driver, per nodeThe inventory. Publishes which devices exist on a node and what attributes they have.
ResourceClaimYou, or generatedA concrete request for devices, with an allocation result once satisfied.
ResourceClaimTemplateYouA stamp that produces a per-Pod ResourceClaim automatically.

The flow is straightforward. The DRA driver on each node publishes ResourceSlices describing the hardware it manages. A cluster admin defines DeviceClasses like gpu.example.com that scope which devices are selectable and carry default config. A workload references a ResourceClaimTemplate, Kubernetes materializes a ResourceClaim per Pod, and the scheduler finds a node whose ResourceSlices can satisfy the claim before it binds the Pod. The driver then prepares the device on that node and the kubelet starts the container.

A minimal claim template looks roughly like this. Note the exactly block, which is the shape the GA API settled on:

apiVersion: resource.k8s.io/v1
kind: ResourceClaimTemplate
metadata:
  name: single-large-gpu
spec:
  spec:
    devices:
      requests:
      - name: gpu
        exactly:
          deviceClassName: gpu.example.com
          count: 1
          selectors:
          - cel:
              expression: >-
                device.attributes["gpu.example.com"].memoryGiB >= 80

A Pod then references it under spec.resourceClaims, and containers reference the claim by name. The important shift is that memoryGiB >= 80 is a scheduling input, not a label you maintained by hand.

What landed after GA

DRA reaching GA in 1.34 was the floor, not the ceiling. The releases since have filled in the parts that make it usable at scale:

  • Prioritized list graduated to stable in 1.36. This is the “H100, else A100” fallback that the device plugin model could never express. For batch and research queues it is often the single biggest utilization win, because jobs stop sitting idle waiting for one specific SKU.
  • Partitionable devices reached beta in 1.36, giving native support for carving physical hardware into logical instances such as MIG slices on demand rather than pre-partitioning nodes.
  • Extended resource support reached beta in 1.36 and GA in 1.37. A DeviceClass can carry a classic extended resource name so unmodified Pods requesting example.com/gpu are served by the DRA driver. This is the migration lever.
  • Device taints and tolerations reached GA in 1.37, mirroring node taints at the device level. Admins can taint a specific failing GPU cluster-wide with a DeviceTaintRule without touching driver config, and Pods on that device can be evicted automatically unless their claim tolerates the taint.
  • A standard resource.kubernetes.io/numaNode attribute landed stable in 1.37, so devices from different vendors’ drivers can finally be compared on the same NUMA topology.
  • ResourceClaim device status reached beta in 1.37, letting drivers report per-device state such as interface names, MAC and IP addresses back into the claim. That matters much more for networking hardware than for GPUs.

The other structural news is governance rather than API surface: NVIDIA’s DRA driver for GPUs moved into the kubernetes-sigs organization under community governance in 2026, which makes it ordinary Kubernetes plumbing rather than a vendor-only integration path.

Migration path for an existing GPU cluster

Do not attempt a big-bang cutover. The staged path below is boring on purpose.

1. Get to 1.34 or later first. Nothing else matters until the stable APIs are available and enabled. If you are on a managed control plane, check which feature gates your provider exposes, because some later DRA features are still gated.

2. Install the DRA driver alongside your device plugin. Both can coexist during transition. Verify that ResourceSlices appear for your nodes and that the attributes you care about are actually populated. Run kubectl get resourceslices and read one in full before you design any selectors, because what a driver publishes is more limited than what the API allows.

3. Define DeviceClasses that match how your teams think. Do not create one class per SKU. Create classes that map to intent - training-gpu, inference-gpu, shared-gpu - and let attribute selectors inside claims handle the specifics. Class names leak into every workload manifest, so pick names you can live with.

4. Turn on extended resource mapping before you rewrite anything. Point a DeviceClass at your existing extended resource name so unmodified workloads are served by the DRA driver. This is the step that lets you decommission the device plugin without a coordinated rewrite across every team.

5. Convert workloads in waves, starting with batch. Training jobs and CI GPU runners are the safest first movers because they are restartable and their owners feel the queueing pain most. Long-lived inference deployments come last.

6. Retire the device plugin only when ResourceSlices cover everything. Keep the plugin installed but idle for a release or two. The rollback path is worth the small operational cost.

Gotchas worth knowing before you start

  • The v1beta1 to v1 change is not cosmetic. ResourceClaimTemplate device requests gained a required exactly block, and DeviceClass and ResourceClaim moved API groups. If you piloted DRA during 1.31 to 1.33, budget time to convert manifests properly.
  • Feature gates are version-sensitive. Dynamic MIG partitioning on 1.34 and 1.35 requires DRAPartitionableDevices on both the kube-apiserver and the kube-scheduler. Managed providers do not all expose it. Confirm before you design around it.
  • Driver quality is the real constraint. The API is stable; driver maturity varies by vendor and by hardware generation. Test your specific cards, not the vendor’s demo.
  • Autoscaling interacts with DRA. Node autoscalers need to understand unsatisfiable claims to provision the right instance type. If you run Karpenter or Cluster Autoscaler, verify how your version handles pending Pods blocked on ResourceClaims rather than on plain extended resources.
  • DRA is allocation, not queueing. It decides which device a Pod gets, not which job runs next or how fairly a team’s quota is spent. Gang scheduling and queue fairness still belong to a batch scheduler, which is why Kueue, Volcano and KAI sit above DRA rather than being replaced by it.
  • Observability lags the API. Kubelet reports DRA-allocated resources through the PodResources API, and device health reporting exists, but most dashboards were built around device plugin metrics. Expect to rebuild GPU utilization views.

Should you adopt DRA now?

Adopt it now if you run a heterogeneous accelerator fleet, if you are hand-maintaining node labels and taints to steer GPU workloads, if you are statically partitioning MIG and losing utilization to a shifting workload mix, or if topology alignment between GPUs and NICs materially affects your training throughput. Those are the cases where the device plugin model costs you real money every week.

Wait if you have a single homogeneous GPU pool with healthy utilization and a stable workload mix. DRA will still be there next year, drivers will be more mature, and more of the interesting features will be GA rather than beta. The migration is not harder for waiting.

The one thing worth doing regardless of which camp you are in: get to a DRA-capable Kubernetes version and install the driver in a non-production cluster now. Reading real ResourceSlices from your own hardware tells you more in an afternoon than any amount of documentation, and it makes the eventual migration a scheduling exercise rather than a research project. If you are also building out model serving on the same fleet, the serving layer choices in our vLLM vs TGI vs Triton benchmark interact directly with how you carve up devices.

Need help planning a GPU scheduling migration or sizing an AI infrastructure platform on Kubernetes? Talk to us.

Frequently Asked Questions

What is Kubernetes Dynamic Resource Allocation (DRA)?

Dynamic Resource Allocation is the Kubernetes API for requesting specialized hardware such as GPUs, NICs and FPGAs by describing what you need rather than counting units. Instead of asking for nvidia.com/gpu: 1 and hoping the node you land on has the right card, you write a ResourceClaim that selects devices by attribute - model, memory size, driver version, NUMA node - and the scheduler picks a node that can actually satisfy it. The core APIs in the resource.k8s.io group graduated to GA in Kubernetes v1.34 and are enabled by default.

Does DRA replace device plugins in Kubernetes?

Not immediately, and there is no announced removal date for the device plugin API. DRA is the strategic direction and the place new capability is landing, but device plugins still work and many clusters will run both during transition. The bridge is extended resource mapping: a DRA driver can advertise a classic extended resource name like example.com/gpu on its DeviceClass, so existing Pod specs that request extended resources keep working while the DRA driver does the allocation underneath. That feature reached GA in Kubernetes 1.37, which makes a cutover possible without editing every workload.

What is the difference between a ResourceClaim and a ResourceClaimTemplate?

A ResourceClaim is a single, named request for devices that you create yourself and that one or more Pods can reference. A ResourceClaimTemplate is a stamp: reference it from a Deployment or Job and Kubernetes creates a fresh ResourceClaim per Pod, with a lifecycle tied to that Pod. Use a shared ResourceClaim when several Pods must land on the same physical device. Use a ResourceClaimTemplate for normal replicated workloads, which is the majority of cases. Note that the GA API changed shape here: ResourceClaimTemplate device requests now use an exactly block containing count, so v1beta1 manifests need rewriting.

Do I need DRA to share a GPU between pods?

No, but DRA gives you better tools for it. Time-slicing and MPS have been available through the NVIDIA device plugin for years and still work. What DRA adds is partitionable devices, which lets the scheduler create MIG partitions dynamically to match demand rather than requiring an operator to pre-partition every card, plus consumable capacity for finer-grained sharing across claims and namespaces with driver-enforced limits. If your GPU fleet is statically partitioned today and utilization is fine, there is no urgency. If you are hand-tuning MIG profiles to chase changing workload mixes, that is exactly the pain DRA is designed to remove.

Which Kubernetes version do I need for DRA in production?

Kubernetes v1.34 or later for the stable resource.k8s.io/v1 APIs, which are enabled by default from that release. If you want dynamic MIG partitioning on 1.34 or 1.35 you also need the DRAPartitionableDevices feature gate enabled on the kube-apiserver and kube-scheduler, since that feature only reached beta in 1.36. Managed control planes vary in which gates they expose, so confirm with your provider before designing around an alpha or beta feature. On managed services where you cannot set gates, stick to what is GA in your control plane version.

What breaks when upgrading DRA manifests from v1beta1 to v1?

GA came with real API changes, not just a version bump. DeviceClass and ResourceClaim moved from resource.k8s.io/v1beta1 to resource.k8s.io/v1, and ResourceClaimTemplate device requests gained a required exactly block wrapping the device count and selectors. Anything you wrote against the beta API during 1.31 to 1.33 needs review rather than a search and replace. Treat the upgrade as a small migration project: re-apply your DeviceClasses first, then convert templates, then run a canary workload before touching production job queues.

Get Started for Free

We would be happy to speak with you and arrange a free consultation with our Kubernetes Expert in Dubai, UAE. 30-minute call, actionable results in days.

Talk to an Expert