DRA API Objects

DRA API Objects

This page describes the Kubernetes API kinds that dynamic resource allocation (DRA) uses to categorize, request, and allocate devices.

DRA terminology

DRA uses the following Kubernetes API kinds to provide the core allocation functionality. All of these API kinds are included in the resource.k8s.io/v1 API group.

DeviceClass
Defines a category of devices that can be claimed and how to select specific device attributes in claims. The DeviceClass parameters can match zero or more devices in ResourceSlices. To claim devices from a DeviceClass, ResourceClaims select specific device attributes.
ResourceClaim
Describes a request for access to attached resources, such as devices, in the cluster. ResourceClaims provide Pods with access to a specific resource. ResourceClaims can be created by workload operators or generated by Kubernetes based on a ResourceClaimTemplate.
ResourceClaimTemplate
Defines a template that Kubernetes uses to create per-Pod ResourceClaims for a workload. ResourceClaimTemplates provide Pods with access to separate, similar resources. Each ResourceClaim that Kubernetes generates from the template is bound to a specific Pod. When the Pod terminates, Kubernetes deletes the corresponding ResourceClaim.
ResourceSlice
Represents one or more resources that are attached to nodes, such as devices. Drivers create and manage ResourceSlices in the cluster. When a ResourceClaim is created and used in a Pod, Kubernetes uses ResourceSlices to find nodes that have access to the claimed resources. Kubernetes allocates resources to the ResourceClaim and schedules the Pod onto a node that can access the resources.

DeviceClass

A DeviceClass lets cluster admins or device drivers define categories of devices in the cluster. DeviceClasses tell operators what devices they can request and how they can request those devices. You can use common expression language (CEL) to select devices based on specific attributes. A ResourceClaim that references the DeviceClass can then request specific configurations within the DeviceClass.

To create a DeviceClass, see Set Up DRA in a Cluster.

ResourceClaims and ResourceClaimTemplates

A ResourceClaim defines the resources that a workload needs. Every ResourceClaim has requests that reference a DeviceClass and select devices from that DeviceClass. ResourceClaims can also use selectors to filter for devices that meet specific requirements, and can use constraints to limit the devices that can satisfy a request. ResourceClaims can be created by workload operators or can be generated by Kubernetes based on a ResourceClaimTemplate. A ResourceClaimTemplate defines a template that Kubernetes can use to auto-generate ResourceClaims for Pods.

Use cases for ResourceClaims and ResourceClaimTemplates

The method that you use depends on your requirements, as follows:

  • ResourceClaim: you want multiple Pods to share access to specific devices. You manually manage the lifecycle of ResourceClaims that you create.
  • ResourceClaimTemplate: you want Pods to have independent access to separate, similarly-configured devices. Kubernetes generates ResourceClaims from the specification in the ResourceClaimTemplate. The lifetime of each generated ResourceClaim is bound to the lifetime of the corresponding Pod.
  • PodGroup ResourceClaimTemplate: you want PodGroups to have independent access to separate, similarly-configured devices that can be shared by their Pods. Kubernetes generates one ResourceClaim for the PodGroup from the specification in the ResourceClaimTemplate. The lifetime of each generated ResourceClaim is bound to the lifetime of the corresponding PodGroup. This requires the DRAWorkloadResourceClaims feature to be enabled.

When you define a workload, you can use Common Expression Language (CEL) to filter for specific device attributes or capacity. The available parameters for filtering depend on the device and the drivers.

If you directly reference a specific ResourceClaim in a Pod, that ResourceClaim must already exist in the same namespace as the Pod. If the ResourceClaim doesn't exist in the namespace, the Pod won't schedule. This behavior is similar to how a PersistentVolumeClaim must exist in the same namespace as a Pod that references it.

You can reference an auto-generated ResourceClaim in a Pod, but this isn't recommended because auto-generated ResourceClaims are bound to the lifetime of the Pod or PodGroup that triggered the generation.

To learn how to claim resources using one of these methods, see Allocate Devices to Workloads with DRA.

Prioritized list

FEATURE STATE: Kubernetes v1.36 [stable](enabled by default)

You can provide a prioritized list of subrequests for requests in a ResourceClaim or ResourceClaimTemplate. The scheduler will then select the first subrequest that can be allocated. This allows users to specify alternative devices that can be used by the workload if the primary choice is not available.

In the example below, the ResourceClaimTemplate requested a device with the color black and the size large. If a device with those attributes is not available, the pod cannot be scheduled. With the prioritized list feature, a second alternative can be specified, which requests two devices with the color white and size small. The large black device will be allocated if it is available. If it is not, but two small white devices are available, the pod will still be able to run.

apiVersion: resource.k8s.io/v1
kind: ResourceClaimTemplate
metadata:
  name: prioritized-list-claim-template
spec:
  spec:
    devices:
      requests:
      - name: req-0
        firstAvailable:
        - name: large-black
          deviceClassName: resource.example.com
          selectors:
          - cel:
              expression: |-
                device.attributes["resource-driver.example.com"].color == "black" &&
                device.attributes["resource-driver.example.com"].size == "large"
        - name: small-white
          deviceClassName: resource.example.com
          selectors:
          - cel:
              expression: |-
                device.attributes["resource-driver.example.com"].color == "white" &&
                device.attributes["resource-driver.example.com"].size == "small"
          count: 2

If the pod is eligible for multiple nodes in the cluster, the scheduler will use the index of chosen subrequests from any prioritized lists as one of the inputs when it scores each node. So nodes that can allocate devices requested in a higher ranked subrequest are more likely to be chosen than nodes that can only allocate devices for lower ranked subrequests.

The decision is made on a per-Pod basis, so if the Pod is a member of a ReplicaSet or similar grouping, you cannot rely on all the members of the group having the same subrequest chosen. Your workload must be able to accommodate this.

Workload ResourceClaims

FEATURE STATE: Kubernetes v1.36 [alpha](disabled by default)

When you organize Pods with the Workload API, you can reserve ResourceClaims for entire PodGroups instead of individual Pods and generate ResourceClaimTemplates for a PodGroup instead of a single Pod, allowing the Pods within a PodGroup to share access to devices allocated to the generated ResourceClaim.

This feature targets two problems:

  • The ResourceClaim API's status.reservedFor list can only contain 256 items. Since kube-scheduler only records individual Pods in that list, only 256 Pods can share a ResourceClaim. By allowing PodGroups to be recorded in status.reservedFor, many more than 256 Pods can share a ResourceClaim.
  • Pods can only share a ResourceClaim when its exact name is known. For complex workloads that replicate groups of Pods, ResourceClaims shared by the Pods in each group need to be created and deleted explicitly when the set of groups scales up and down. By generating ResourceClaims for each PodGroup, a single ResourceClaimTemplate can form the basis for ResourceClaims that are both replicated automatically and shareable among the Pods in a PodGroup.

The PodGroup API defines a spec.resourceClaims field with the same structure and similar meaning as the spec.resourceClaims field in the Pod API:

apiVersion: scheduling.k8s.io/v1alpha2
kind: PodGroup
metadata:
  name: training-group
  namespace: some-ns
spec:
  ...
  resourceClaims:
  - name: pg-claim
    resourceClaimName: my-pg-claim
  - name: pg-claim-template
    resourceClaimTemplateName: my-pg-template

Like claims made by Pods, claims for PodGroups defining a resourceClaimName refer to a ResourceClaim by name. Claims defining a resourceClaimTemplateName refer to a ResourceClaimTemplate which replicates into one ResourceClaim for the entire PodGroup that can be shared amongst its Pods.

When a Pod defines a claim with a name, resourceClaimName, and resourceClaimTemplateName that all match one of its PodGroup's spec.resourceClaims, then kube-scheduler reserves the ResourceClaim for the PodGroup instead of the Pod. If the Pod's claim does not match one made by its PodGroup, then kube-scheduler reserves the ResourceClaim for the Pod. In either case, reservation is recorded in the ResourceClaim's status.reservedFor. PodGroup reservations and the corresponding resource allocation persist in the ResourceClaim until the PodGroup is deleted, even if the group no longer has any Pods.

When a Pod claim matching a PodGroup claim defines a resourceClaimTemplateName, then one ResourceClaim is generated for the PodGroup. Other Pods in the group defining the same claim will share that generated ResourceClaim instead of prompting a new ResourceClaim to be generated for each Pod. Whether or not a resourceClaimTemplateName claim matches a PodGroup claim, the name of the generated ResourceClaim is recorded in the Pod's status.resourceClaimStatuses.

ResourceClaims generated from a ResourceClaimTemplate for a PodGroup follow the lifecycle of the PodGroup. The ResourceClaim is first created when both the PodGroup and its ResourceClaimTemplate exist. The ResourceClaim is deleted after the PodGroup has been deleted and the ResourceClaim is no longer reserved.

Consider the following example:

apiVersion: scheduling.k8s.io/v1alpha2
kind: PodGroup
metadata:
  name: training-group
  namespace: some-ns
spec:
  ...
  resourceClaims:
  - name: pg-claim
    resourceClaimName: my-pg-claim
  - name: pg-claim-template
    resourceClaimTemplateName: my-pg-template
---
apiVersion: v1
kind: Pod
metadata:
  name: training-group-pod-1
  namespace: some-ns
spec:
  ...
  schedulingGroup:
    podGroupName: training-group
  resourceClaims:
  - name: pod-claim
    resourceClaimName: my-pod-claim
  - name: pod-claim-template
    resourceClaimTemplateName: my-pod-template
  - name: pg-claim
    resourceClaimName: my-pg-claim
  - name: pg-claim-template
    resourceClaimTemplateName: my-pg-template

In this example, the training-group PodGroup has one Pod named training-group-pod-1. The Pod's pod-claim and pod-claim-template claims do not match any claim made by the PodGroup, so those claims are not affected by the PodGroup: ResourceClaim my-pod-claim becomes reserved for the Pod and a ResourceClaim is generated from ResourceClaimTemplate my-pod-template and also becomes reserved for the Pod. The pg-claim and pg-claim-template do match claims made by the PodGroup. ResourceClaim my-pg-claim becomes reserved for the PodGroup and a ResourceClaim is generated from ResourceClaimTemplate my-pg-template and also becomes reserved for the PodGroup.

Associating ResourceClaims with Workload API resources is controlled by the DRAWorkloadResourceClaims feature gate in the kube-apiserver, kube-controller-manager, kube-scheduler, and kubelet.

ResourceSlice

Each ResourceSlice represents one or more devices in a pool. The pool is managed by a device driver, which creates and manages ResourceSlices. The resources in a pool might be represented by a single ResourceSlice or span multiple ResourceSlices.

ResourceSlices provide useful information to device users and to the scheduler, and are crucial for dynamic resource allocation. Every ResourceSlice must include the following information:

  • Resource pool: a group of one or more resources that the driver manages. The pool can span more than one ResourceSlice. Changes to the resources in a pool must be propagated across all of the ResourceSlices in that pool. The device driver that manages the pool is responsible for ensuring that this propagation happens.
  • Devices: devices in the managed pool. A ResourceSlice can list every device in a pool or a subset of the devices in a pool. The ResourceSlice defines device information like attributes, versions, and capacity. Device users can select devices for allocation by filtering for device information in ResourceClaims or in DeviceClasses.
  • Nodes: the nodes that can access the resources. Drivers can choose which nodes can access the resources, whether that's all of the nodes in the cluster, a single named node, or nodes that have specific node labels.

Drivers use a controller to reconcile ResourceSlices in the cluster with the information that the driver has to publish. This controller overwrites any manual changes, such as cluster users creating or modifying ResourceSlices.

Consider the following example ResourceSlice:

apiVersion: resource.k8s.io/v1
kind: ResourceSlice
metadata:
  name: cat-slice
spec:
  driver: "resource-driver.example.com"
  pool:
    generation: 1
    name: "black-cat-pool"
    resourceSliceCount: 1
  # The allNodes field defines whether any node in the cluster can access the device.
  allNodes: true
  devices:
  - name: "large-black-cat"
    attributes:
      color:
        string: "black"
      size:
        string: "large"
      cat:
        bool: true

This ResourceSlice is managed by the resource-driver.example.com driver in the black-cat-pool pool. The allNodes: true field indicates that any node in the cluster can access the devices. There's one device in the ResourceSlice, named large-black-cat, with the following attributes:

  • color: black
  • size: large
  • cat: true

A DeviceClass could select this ResourceSlice by using these attributes, and a ResourceClaim could filter for specific devices in that DeviceClass.

Naming and prioritization

The order in which the Kubernetes scheduler evaluates devices for allocation is determined by the lexicographical sorting of ResourceSlice and resource pool names. The scheduler uses a first-fit strategy, meaning it selects the first available device that satisfies the claim's requirements.

This allows the priority of resource allocation to be influenced by the names assigned to pools and ResourceSlices. Note that pools without binding conditions are always evaluated before those with binding conditions, regardless of their names.

For drivers built using the k8s.io/dynamic-resources/kubeletplugin Go package or the ResourceSlice controller from that module, these components automatically handle ResourceSlice naming to ensure they are evaluated in the order specified by the driver.

Admin access

FEATURE STATE: Kubernetes v1.36 [stable](enabled by default)

You can mark a request in a ResourceClaim or ResourceClaimTemplate as having privileged features for maintenance and troubleshooting tasks. A request with admin access grants access to in-use devices and may enable additional permissions when making the device available in a container:

apiVersion: resource.k8s.io/v1
kind: ResourceClaimTemplate
metadata:
  name: large-black-cat-claim-template
spec:
  spec:
    devices:
      requests:
      - name: req-0
        exactly:
          deviceClassName: resource.example.com
          allocationMode: All
          adminAccess: true

Admin access is a privileged mode and should not be granted to regular users in multi-tenant clusters. Only users authorized to create ResourceClaim or ResourceClaimTemplate objects in namespaces labeled with resource.kubernetes.io/admin-access: "true" (case-sensitive) can use the adminAccess field. This ensures that non-admin users cannot misuse the feature.

Admin access is controlled by the DRAAdminAccess feature gate in the kube-apiserver, kube-scheduler, and kubelet.

List type attributes

FEATURE STATE: Kubernetes v1.36 [alpha](disabled by default)

This feature improves the ResourceSlice API, allowing DRA drivers to specify list values for device attributes instead of only scalars. This is useful for modeling more complex internal node topologies, for example when a CPU has adjacency to multiple PCIe roots.

For ResourceClaim authors (end users), this means that the matchAttribute and distinctAttribute work better for these cases.

  • matchAttribute — the two attributes must have a non-empty list intersection, rather than be identical (scalar values are treated as single-item lists). This just means that if one driver publishes a single value for, say, the PCIe root, and another driver publishes a list, the constraint is met as long as the single value appears somewhere in the list.
  • distinctAttribute — the attribute values must be pairwise-disjoint (no value shared between any two devices)

To help ResourceClaim authors use attributes that may be lists inside CEL expressions, this feature also introduces an includes() CEL function.

# Scalar attribute (backward compatible)
# assume: device.attributes["dra.example.com"].model = "model-a"
device.attributes["dra.example.com"].model.includes("model-a")  # true
device.attributes["dra.example.com"].model.includes("model-b")  # false

# List-type attribute (requires DRAListTypeAttributes)
# assume: device.attributes["dra.example.com"].supported-models= ["model-a", "model-b"]
device.attributes["dra.example.com"].supported-models.includes("model-a")  # true
device.attributes["dra.example.com"].supported-models.includes("model-c")  # false

Details for DRA Driver Authors

By default, each DeviceAttribute holds exactly one scalar value: a boolean, an integer, a string, or a semantic version string. The DRAListTypeAttributes feature gate extends DeviceAttribute with four list-type fields, allowing a device to advertise multiple values for a single attribute:

  • bools — a list of boolean values
  • ints — a list of 64-bit integer values
  • strings — a list of strings (each at most 64 characters)
  • versions — a list of semantic version strings per semver.org spec 2.0.0 (each at most 64 characters)

The total number of individual attribute values per device (scalar fields plus all list elements combined) is limited to 48. When any device in a ResourceSlice uses this feature or other advanced features such as taints, the ResourceSlice will be limited to at most 64 devices. use list-type attributes or other advanced features such as taints.

Here is an example of a device advertising multiple supported models using a list-type string attribute:

kind: ResourceSlice
apiVersion: resource.k8s.io/v1
metadata:
  name: example-resourceslice
spec:
  nodeName: worker-1
  pool:
    name: pool
    generation: 1
    resourceSliceCount: 1
  driver: dra.example.com
  devices:
  - name: gpu-0
    attributes:
      dra.example.com/supported-models:
        strings:
        - model-a
        - model-b

List type attributes is controlled by the DRAListTypeAttributes feature gate in the kube-apiserver and kube-scheduler.