This page describes the Kubernetes API kinds that dynamic resource allocation (DRA) uses to categorize, request, and allocate devices.
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.
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.
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.
The method that you use depends on your requirements, as follows:
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.
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.
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:
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.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.
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:
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: blacksize: largecat: trueA DeviceClass could select this ResourceSlice by using these attributes, and a ResourceClaim could filter for specific devices in that DeviceClass.
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.
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.
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
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 valuesints — a list of 64-bit integer valuesstrings — 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.