Hitesh Sahu
Hitesh SahuHitesh Sahu
  1. Home
  2. ›
  3. posts
  4. ›
  5. …

  6. ›
  7. 3 2 DRA

Loading ⏳
Fetching content, this won’t take long…


💡 Did you know?

🦈 Sharks existed before trees 🌳.

🍪 This website uses cookies

No personal data is stored on our servers however third party tools Google Analytics cookies to measure traffic and improve your website experience. Learn more

Loading ⏳
Fetching content, this won’t take long…


💡 Did you know?

🍯 Honey never spoils — archaeologists found 3,000-year-old jars still edible.
kubernetes

    AI-AgenticAI

    AI-DeepLearning

    AI-GenAI

    AI-Infrastructure

    AI-Machine-Learning

    AI-Math

    AWS

    Azure

    Hobbies

    kubernetes
    • Kubernetes and Cloud Native Certification Path

    • Kubernetes: Control Loops, Scheduling, and GPUs

    • Kubernetes API Server Internals

    • etcd Architecture Explained

    • Kubernetes Scheduler Internals

    • Kubernetes Informers & Controllers Explained

    • Kubernetes Networking: Pods, Services, Ingress, and CNI

    • Kubernetes Storage: PV, PVC, StorageClass, and CSI

    • Helm: Kubernetes Package Manager

    • Cloud Native Observability: Prometheus, Grafana, OpenTelemetry, and Tracing

    • GPU Scheduling in Kubernetes: Device Plugins, GPU Operator & MIG

    • NVIDIA Network Operator: InfiniBand, SR-IOV, RDMA, and Multus

    • Dynamic Resource Allocation: The Future of GPU Scheduling in Kubernetes

    • Kubernetes Performance at Scale

    • Optimizing AI Inference at Scale: The Full Stack

    • Kueue: Kubernetes-Native Job Queuing and Quota Management

    • Multi-Node Distributed Training on Kubernetes

    • Kubernetes Topology Manager: NUMA-Aware GPU Scheduling

    • NVIDIA NIM: Optimized Inference Microservices on Kubernetes

    • GPU Autoscaling on Kubernetes: KEDA, HPA, and Cluster Autoscaler

    • kubernetes Index


    Management

    Programming

    Terraform

    Z_Appendix

    0-root

Cover Image for Dynamic Resource Allocation: The Future of GPU Scheduling in Kubernetes
kubernetes

Dynamic Resource Allocation: The Future of GPU Scheduling in Kubernetes

How Kubernetes DRA replaces Device Plugins for GPU scheduling — ResourceClaim, DeviceClass, ResourceSlice, CEL selectors, topology-aware allocation, the NVIDIA GPU DRA driver, and how DRA and Device Plugins coexist during migration.

Kubernetes
DRA
GPU
NVIDIA
Scheduling
DGX
← Previous

NVIDIA Network Operator: InfiniBand, SR-IOV, RDMA, and Multus

Next →

Kubernetes Performance at Scale

Dynamic Resource Allocation: The Future of GPU Scheduling in Kubernetes

The Device Plugin framework has been how Kubernetes schedules GPUs since 2018.

It works. But it has limits that become painful at DGX scale:

  • GPUs are exposed as opaque integer counts — no attributes, no topology
  • The scheduler cannot place a Pod on a node where GPUs are NVLink-connected
  • Sharing a GPU between two Pods requires workarounds (MIG, time-slicing)
  • A Pod requesting nvidia.com/gpu: 8 cannot express "give me 8 GPUs on the same NVSwitch domain"

Dynamic Resource Allocation (DRA) — graduated to beta in Kubernetes 1.31 — is the replacement. It replaces opaque integer counting with a rich, structured model: devices have attributes, users write selectors, and the scheduler understands topology.


Device Plugin Limitations

The Device Plugin model works like a counter: the plugin advertises nvidia.com/gpu: 8 and the scheduler subtracts integers.

flowchart LR

DevicePlugin["Device Plugin\n(ListAndWatch)"]

-->|"nvidia.com/gpu: 8\n(opaque count)"| Kubelet

Kubelet

-->|"8 integer slots"| Scheduler

Scheduler

-->|"subtract 1\nper Pod"| Allocation["nvidia.com/gpu: 1\nallocated to Pod"]

What the scheduler cannot see:

Information Device Plugin Consequence
GPU model (H100 vs A100) ❌ Can't select by GPU type without node labels
GPU memory (80 GB vs 40 GB) ❌ Can't select by memory requirement
NVLink topology ❌ Can't guarantee 8 GPUs are NVSwitch-connected
MIG partition attributes ❌ MIG profiles are separate resource names, not attributes
Shared access ❌ One Pod per GPU slot (no DRA-level sharing)

DRA Architecture

DRA introduces four new concepts: DeviceClass, ResourceSlice, ResourceClaim, and ResourceClaimTemplate.

flowchart TB

Driver["DRA Driver\n(NVIDIA GPU Driver)"]

-->|"publishes"| RS["ResourceSlice\n(per node — device inventory\nwith attributes)"]

User["User / Operator"]

-->|"creates"| RC["ResourceClaim\n(what devices I need\n+ CEL selectors)"]

Scheduler

-->|"matches claims\nto ResourceSlices"| Alloc["Allocation\n(specific device IDs\nassigned to claim)"]

Pod

-->|"references"| RC

RC

-->|"fulfilled by"| Alloc

DeviceClass

A DeviceClass is a cluster-wide template that defines a category of device and default constraints. Cluster admins create them; users reference them in claims.

apiVersion: resource.k8s.io/v1beta1
kind: DeviceClass
metadata:
  name: gpu.nvidia.com
spec:
  selectors:
  - cel:
      expression: device.driver == "gpu.resource.nvidia.com"

For specialized access (e.g., only H100 SXM5 nodes):

apiVersion: resource.k8s.io/v1beta1
kind: DeviceClass
metadata:
  name: h100-sxm5.nvidia.com
spec:
  selectors:
  - cel:
      expression: >
        device.driver == "gpu.resource.nvidia.com" &&
        device.attributes["model"].string == "H100 SXM5 80GB"

ResourceSlice

A ResourceSlice is published per-node by the DRA driver. It advertises the actual devices on that node with their full attribute set.

apiVersion: resource.k8s.io/v1beta1
kind: ResourceSlice
metadata:
  name: node-dgx-01-gpus
spec:
  driver: gpu.resource.nvidia.com
  nodeName: node-dgx-01
  pool:
    name: node-dgx-01
    generation: 1
    resourceSliceCount: 1
  devices:
  - name: gpu-0
    attributes:
      model:
        string: "H100 SXM5 80GB"
      memory:
        quantity: "80Gi"
      nvlinkDomain:
        string: "nvswitch-0"
      computeCapability:
        version: "9.0"
      uuid:
        string: "GPU-a1b2c3d4-..."
  - name: gpu-1
    attributes:
      model:
        string: "H100 SXM5 80GB"
      memory:
        quantity: "80Gi"
      nvlinkDomain:
        string: "nvswitch-0"   # same NVSwitch domain as gpu-0
      uuid:
        string: "GPU-e5f6a7b8-..."
  # ... gpu-2 through gpu-7

The scheduler reads all ResourceSlice objects — it has a complete, structured view of every device in the cluster.

ResourceClaim

A ResourceClaim is what a user (or operator) creates to request devices. It uses CEL expressions to express requirements.

apiVersion: resource.k8s.io/v1beta1
kind: ResourceClaim
metadata:
  name: training-gpus
  namespace: team-research
spec:
  devices:
    requests:
    - name: gpus
      deviceClassName: gpu.nvidia.com
      count: 8
      selectors:
      - cel:
          expression: >
            device.attributes["memory"].quantity >= "80Gi" &&
            device.attributes["model"].string == "H100 SXM5 80GB"
      allocationMode: ExactCount

The scheduler finds a node where 8 GPUs matching all selectors are available and unallocated, then writes the allocation back into the claim.


Pod Integration

A Pod references a ResourceClaim by name. When the Pod is scheduled, Kubernetes ensures the claim's allocated devices are on the same node.

apiVersion: v1
kind: Pod
metadata:
  name: llm-training
spec:
  resourceClaims:
  - name: training-gpus
    resourceClaimName: training-gpus   # references the claim above
  containers:
  - name: trainer
    image: nvcr.io/nvidia/pytorch:24.10-py3
    resources:
      claims:
      - name: training-gpus           # which claim this container uses
    command: ["torchrun", "--nproc-per-node=8", "train.py"]

The kubelet and DRA driver together ensure the allocated GPUs are injected into the container — analogous to the Device Plugin's Allocate gRPC call, but driven by the structured allocation in the claim rather than by opaque device IDs.


Topology-Aware Allocation

The most important DRA capability for DGX workloads is topology constraints on allocation.

An 8-GPU training job should always get 8 GPUs on the same NVSwitch domain. With Device Plugins, this requires manual scheduling heuristics (node affinity labels, custom scheduler plugins). With DRA:

spec:
  devices:
    requests:
    - name: gpus
      deviceClassName: gpu.nvidia.com
      count: 8
      selectors:
      - cel:
          expression: >
            device.attributes["nvlinkDomain"].string == "nvswitch-0"

The scheduler only allocates this claim on a node where 8 available GPUs all have nvlinkDomain == "nvswitch-0". If no such set exists on any node, the Pod stays Pending — correctly, rather than silently running with non-NVLink-connected GPUs and wondering why AllReduce is slow.


ResourceClaimTemplate — Per-Pod Claims

For workloads like Deployments where each replica needs its own devices, use ResourceClaimTemplate:

apiVersion: resource.k8s.io/v1beta1
kind: ResourceClaimTemplate
metadata:
  name: inference-gpu-template
  namespace: inference
spec:
  spec:
    devices:
      requests:
      - name: gpu
        deviceClassName: gpu.nvidia.com
        count: 1
        selectors:
        - cel:
            expression: device.attributes["memory"].quantity >= "40Gi"
# In the Pod template of a Deployment:
spec:
  resourceClaims:
  - name: inference-gpu
    resourceClaimTemplateName: inference-gpu-template

Each replica Pod gets its own independent ResourceClaim generated from the template. When the Pod is deleted, its claim is deleted too.


NVIDIA GPU DRA Driver

NVIDIA ships a DRA driver (gpu.resource.nvidia.com) that:

  1. Publishes ResourceSlice objects for every GPU on the node (with model, memory, NVLink topology, MIG capability, etc.)
  2. Handles NodePrepareResources and NodeUnprepareResources gRPC calls from the kubelet to set up and tear down GPU access
  3. Supports MIG partitions as first-class devices with their own attributes
flowchart LR

NVIDIADriver["NVIDIA DRA Driver\n(DaemonSet)"]

-->|"publishes"| RS["ResourceSlice\n(all GPU attributes)"]

NVIDIADriver

-->|"NodePrepareResources"| Setup["Creates /dev/nvidia*\nconfigures environment"]

Setup

-->Container["Container\n(CUDA_VISIBLE_DEVICES set\nfrom claim allocation)"]

The GPU Operator (ClusterPolicy) deploys the DRA driver alongside the legacy Device Plugin during the transition period — both can run simultaneously.


DRA vs Device Plugin

Capability Device Plugin DRA
Device advertisement Integer count per resource name Structured attributes (model, memory, topology)
Selection criteria None (only count) CEL expressions on any attribute
Topology awareness ❌ ✅ (same NVSwitch domain, same NUMA node)
MIG support Separate resource names per profile First-class devices with attributes
Sharing Via time-slicing or MPS workarounds Native via allocationMode: All or admin access
Dynamic partitioning ❌ ✅ (driver can create MIG partitions on demand)
Scheduler visibility Opaque Full — scheduler reads ResourceSlice
Migration effort None (existing) New driver, new Pod spec fields

Coexistence During Migration

Device Plugins and DRA can run on the same cluster simultaneously. A node can advertise nvidia.com/gpu (Device Plugin path) and also publish ResourceSlice (DRA path).

flowchart LR

Node["DGX Node"]

-->DP["Device Plugin\nnvidia.com/gpu: 8\n(legacy Pods)"]

Node

-->DRA["DRA Driver\nResourceSlice\n(new Pods)"]

DP

-->OldPod["Pod using\nnvidia.com/gpu: 1"]

DRA

-->NewPod["Pod using\nResourceClaim"]

Migration path:

  1. Deploy the NVIDIA DRA driver alongside the existing GPU Operator
  2. New workloads opt in by using resourceClaims in their Pod spec
  3. Legacy workloads continue using nvidia.com/gpu limits unchanged
  4. Once all workloads are migrated, Device Plugin can be disabled

Kubernetes Version Timeline

K8s Version DRA Status Key change
1.26 Alpha Initial DRA API
1.30 Alpha Structured Parameters introduced
1.31 Beta Structured Parameters stable; production-ready
1.32 Beta ResourceSlice partition API (for MIG)
~1.33 Expected GA Full stability

DRA beta in 1.31 means the API is stable enough to deploy in production, though the feature gate (DynamicResourceAllocation) must still be enabled explicitly.


Key Takeaways

Concept Purpose
DeviceClass Cluster-admin-defined template for a device category
ResourceSlice Per-node device inventory published by the DRA driver
ResourceClaim User request for specific devices with CEL selectors
ResourceClaimTemplate Per-Pod claim template for Deployments/StatefulSets
CEL selectors Express constraints: memory, model, NVLink domain, MIG capability
Topology awareness Guarantee 8 GPUs are NVSwitch-connected — impossible with Device Plugins
Coexistence Device Plugins and DRA work simultaneously during migration

DRA is not a drop-in replacement for Device Plugins yet — it requires Pod spec changes, a new DRA driver, and cluster feature gates. But it is the only path to topology-aware GPU allocation and per-device attribute selection at DGX scale. Any cluster running K8s 1.31+ should be evaluating migration.

Hitesh Sahu
Written by Hitesh Sahu, a passionate developer and blogger.

Tue Jul 07 2026

Share This on

← Previous

NVIDIA Network Operator: InfiniBand, SR-IOV, RDMA, and Multus

Next →

Kubernetes Performance at Scale

kubernetes/3-2-DRA
Let's work together
+49 176-2019-2523
hiteshkrsahu@gmail.com
WhatsApp
Skype
Munich 🥨, Germany 🇩🇪, EU
Playstore
Hitesh Sahu's apps on Google Play Store
Need Help?
Let's Connect
Navigation
  Home/About
  Skills
  Work/Projects
  Lab/Experiments
  Contribution
  Awards
  Art/Sketches
  Thoughts
  Contact
Links
  Sitemap
  Legal Notice
  Privacy Policy

Made with

NextJS logo

NextJS by

hitesh Sahu

| © 2026 All rights reserved.