
GPUs used to be the domain of research labs and big tech. In 2026, an SMB with a single GPU instance runs LLM inference, fine-tuning jobs, and batch transcription — and pays per second for the privilege. That makes GPU efficiency a real budget line, not a footnote. And for years, the way Kubernetes handed out GPUs made efficiency almost impossible: the device plugin model gave every workload a whole GPU or nothing at all.
That changed with Dynamic Resource Allocation (DRA). It went stable in Kubernetes v1.35 and is enabled by default. If you run GPU workloads on Kubernetes — or you’re about to — DRA is the most important scheduler change in years. Here’s what it is, how to use it, and whether your SMB should adopt it now.
Why the Device Plugin Model Hurts SMBs
Since Kubernetes 1.8, special hardware has been exposed through device plugins. On an NVIDIA cluster that means running the NVIDIA device plugin as a DaemonSet, labeling GPU nodes, and requesting a card like this:
resources:
limits:
nvidia.com/gpu: 1 # one whole GPU, or nothing
That works, but it’s crude in exactly the ways that cost SMBs money:
- All-or-nothing allocation. A pod that needs 4 GB of VRAM to serve a small model consumes an entire 24 GB card. On a two-node GPU cluster, that’s the difference between running two workloads and six.
- Static decisions. The kubelet hands out devices at container start. The scheduler never sees GPU health, memory, or topology, so you compensate with taints, labels, and guesswork.
- Vendor lock-in at the API level. The device plugin API is effectively per-vendor. Moving from NVIDIA to AMD means rewriting how you request hardware.
- No sharing, no metadata. Nothing tells Kubernetes “any GPU with at least 16 GB of memory” or “a GPU on the same PCIe switch as this NIC.”
None of this is fatal at one GPU node. It becomes fatal at three — which is exactly where SMBs land once AI workloads stop being an experiment.
How DRA Works: DeviceClasses, ResourceClaims, and ResourceSlices
DRA replaces the device plugin model with a general, vendor-neutral device API built around four pieces:
- DeviceClass — an admin-defined category of devices, with CEL selection rules (“NVIDIA GPU with at least 16 GiB memory”).
- ResourceClaim / ResourceClaimTemplate — what a workload asks for. Claims can be per-pod or shared by several pods.
- ResourceSlice — a live inventory of devices published by the driver (“node-a has 2 A10s, node-b has 4 L4s”).
- A DRA driver — vendor software (NVIDIA’s ships in the GPU Operator) that publishes slices, allocates devices, and exposes them to containers via the Container Device Interface (CDI).
The flow is simple: the scheduler matches each claim against available slices, picks a node, the driver prepares the device, and CDI bind-mounts the right files into your container. No taints, no labels, no kubelet restarts.
Two 2026 details worth knowing: DRA went stable in v1.35 (enabled by default), and v1.36 added prioritized request lists — you can say “prefer a big GPU, fall back to two small ones.” That’s the kind of flexibility that makes GPU nodes schedulable the way CPU nodes are.
A Working Example: Requesting a GPU with DRA
Step 1 — install a DRA driver. On NVIDIA hardware, the GPU Operator enables DRA with a single flag:
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
helm repo update
helm install gpu-operator nvidia/gpu-operator \
--namespace gpu-operator --create-namespace \
--set driver.enabled=true \
--set toolkit.enabled=true \
--set dra.enabled=true
Step 2 — define a DeviceClass. This one matches any NVIDIA GPU:
apiVersion: resource.k8s.io/v1
kind: DeviceClass
metadata:
name: nvidia-gpu
spec:
selectors:
- cel:
expression: |
device.driver == "nvidia.com" &&
device.attributes["nvidia.com"].type == "gpu"
Attribute names come from your driver. Run kubectl get resourceslices -o yaml to see exactly what fields your driver publishes, then write selectors against them — for example device.attributes["nvidia.com"].memory >= 16Gi.
Step 3 — request the device. A ResourceClaimTemplate plus a Deployment that references it:
apiVersion: resource.k8s.io/v1
kind: ResourceClaimTemplate
metadata:
name: gpu-claim
spec:
spec:
devices:
requests:
- name: gpu
exactly:
deviceClassName: nvidia-gpu
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: llm-inference
spec:
replicas: 1
selector:
matchLabels:
app: llm-inference
template:
metadata:
labels:
app: llm-inference
spec:
resourceClaims:
- name: gpu
resourceClaimTemplateName: gpu-claim
containers:
- name: inference
image: nvcr.io/nvidia/pytorch:24.12-py3
resources:
claims:
- name: gpu
Kubernetes creates a claim per pod automatically. Verify with:
kubectl get resourceclaims
kubectl describe resourceclaim gpu-claim-<pod-name>
Want several pods to share one device (common for sharded inference)? Create a single claim with allocationMode: All and adminAccess: true, then reference it by name from each pod’s spec.resourceClaims.
What DRA Changes for SMBs — and When to Hold Off
It cuts GPU spend. Request 8 GiB of VRAM instead of a whole card and two jobs pack onto one device. On hourly-priced GPU instances that is real money — the same math we covered in cutting Kubernetes costs, applied at the device level.
It makes autoscaling smarter. Because claims are scheduler-aware, DRA pairs naturally with node autoscaling: Karpenter provisions the node, DRA picks the device. No more manually tainting GPU nodes to keep jobs off them.
It removes vendor-specific glue. The same YAML requests NVIDIA, AMD, or Intel accelerators — only the driver changes.
When to hold off: DRA needs a recent cluster (v1.35+), so an upgrade is a prerequisite — see our practical cluster upgrade guide. Driver maturity varies; NVIDIA’s is the most battle-tested. And if you run a single GPU node with one workload, the device plugin still works fine — keep it, and migrate when the second node arrives. During migration both models can coexist, so move inference workloads first and compare utilization before you commit.
A sensible adoption path: upgrade the cluster → install the driver with DRA enabled → define one DeviceClass → convert a single workload → watch kubectl get resourceslices and GPU utilization for a week → expand.
DRA is one of those rare infrastructure changes that simplifies rather than complicates. It replaces taints, labels, and vendor plugins with one declarative API — and for SMBs watching GPU bills grow, it’s the difference between guessing and knowing exactly what your cluster can run.
Not sure whether DRA is worth the migration for your cluster? We help SMBs make pragmatic Kubernetes and AI-infrastructure decisions — book a free 30-minute consultation and we’ll map out your path.