The module lifecycle stage: Generally available version
The module has requirements for installation
A GPUClass is an administrator-defined pool of GPUs. It describes which cards belong to the pool and which partition and sharing options are allowed. The module turns that into a set of DeviceClass objects, each with an extended resource name that users can request directly.
This is the recommended way to expose GPUs to users. Without a GPUClass, every user has to author their own DeviceClass with a hand-written CEL selector — that path is described in Usage.
GPUClass is a cluster-scoped resource. Short name: gpucls.
Using GPUClass resources
How GPUClass works:
- The cluster administrator creates a GPUClass with a selector over PhysicalGPU objects.
gpu-controllerfinds the matching cards and reads their capabilities — which MIG profiles they support and which sharing strategies are available.- For every allowed combination it creates a DeviceClass owned by that GPUClass. Each one gets an
extendedResourceName. - Users request a GPU by that extended resource name. The module’s mutating webhook creates the ResourceClaim for them.
Deleting a GPUClass deletes all DeviceClass objects it generated (they are bound to the GPUClass via owner references).
Minimal GPUClass example
Every GPU in the cluster, whole cards only:
apiVersion: gpu.deckhouse.io/v1alpha1
kind: GPUClass
metadata:
name: gpu-any
spec: {}An empty spec means “all PhysicalGPU objects, all supported partition profiles, all supported sharing strategies”. On a mixed cluster this generates a large number of DeviceClass objects, so in practice you need a selector.
Selecting cards
spec.selector is a standard label selector over PhysicalGPU objects. An empty selector matches everything.
Available PhysicalGPU labels:
| Label | Example | Meaning |
|---|---|---|
gpu.deckhouse.io/vendor |
nvidia, metax, amd, intel |
GPU vendor. |
gpu.deckhouse.io/device |
a100-sxm4-40gb, h100-sxm5-96gb, tesla-t4 |
Card model. |
gpu.deckhouse.io/node |
worker-1 |
Node the card is installed in. |
gpu.deckhouse.io/sharing.mps |
true |
The card supports MPS. |
gpu.deckhouse.io/sharing.ts |
true |
The card supports time-slicing. |
To list all PhysicalGPUs in the cluster and their labels, use:
d8 k get physicalgpus --show-labelsExample of a GPU class limited to one model:
apiVersion: gpu.deckhouse.io/v1alpha1
kind: GPUClass
metadata:
name: a100
spec:
selector:
matchLabels:
gpu.deckhouse.io/device: a100-sxm4-40gbRestricting partition profiles
spec.partitionFilter limits which MIG profiles the class exposes. Use allow as a whitelist or deny as a blacklist.
Profile names in the filter must be DNS labels: write 1g5gb, not 1g.5gb. These names are used to build DeviceClass names, which cannot contain dots. A dotted value is rejected by the admission webhook with partitionFilter value "1g.5gb" must be a DNS label: must not contain dots.
To see which profiles a card supports, use:
d8 k get physicalgpu <name> -o jsonpath='{.status.capabilities.partitionSupport.profiles[*].name}'This command prints the hardware names (1g.5gb, 2g.10gb, …). Strip the dots when writing them into the filter.
Example GPUClass that publishes only small A100 partitions:
apiVersion: gpu.deckhouse.io/v1alpha1
kind: GPUClass
metadata:
name: a100-small
spec:
selector:
matchLabels:
gpu.deckhouse.io/device: a100-sxm4-40gb
partitionFilter:
allow:
- 1g5gb
- 2g10gbEverything except the full-card partition:
spec:
partitionFilter:
deny:
- 7g40gbRestricting sharing
spec.sharingFilter limits which sharing strategies the class exposes. Valid names are mps and ts; only strategies the hardware actually supports are used.
Example of a pool for exclusive use only — shared access to these cards is fully denied:
apiVersion: gpu.deckhouse.io/v1alpha1
kind: GPUClass
metadata:
name: a100-exclusive
spec:
selector:
matchLabels:
gpu.deckhouse.io/device: a100-sxm4-40gb
sharingFilter:
deny:
- mps
- tsExample of a pool that only allows MPS:
spec:
sharingFilter:
allow:
- mpsGenerated DeviceClass names
Names are built from the class name plus partition and sharing segments:
| Generated name | What it allocates |
|---|---|
<class> |
A whole card, exclusive. |
<class>-<partition> |
A MIG partition of that profile, exclusive. |
<class>-<sharing>-percent |
A share of a whole card. |
<class>-<partition>-<sharing>-percent |
A share of a MIG partition. |
For example, a class named ml-ai-h100 that allows the 1g12gb profile and MPS produces ml-ai-h100, ml-ai-h100-1g12gb, ml-ai-h100-mps-percent, and ml-ai-h100-1g12gb-mps-percent.
Generated objects get labels that make them easy to find and audit:
d8 k get deviceclasses -l gpu.deckhouse.io/gpuclass=ml-ai-h100| Label | Meaning |
|---|---|
gpu.deckhouse.io/gpuclass |
The owning GPUClass. |
gpu.deckhouse.io/managed-by=gpu-controller |
Generated, not hand-written. Do not edit it. |
gpu.deckhouse.io/partition |
The partition profile; absent for whole-card classes. |
gpu.deckhouse.io/sharing |
mps or ts; absent for exclusive classes. |
gpu.deckhouse.io/capacity-units |
1 for exclusive classes, 100 for -percent classes — the unit the user requests. |
Treat the naming scheme as a convenience, not a contract. The authoritative list is always in .status.deviceClassNames on the GPUClass.
Viewing available GPUClass objects
To list GPUClass objects available in the cluster, use:
d8 k get gpuclassesExample output:
NAME STATE GPUS STATUS AGE
ml-ai-h100 Reconciled 2 10m
Field meanings in the command output:
| Field | Meaning |
|---|---|
STATE (reason of the Ready condition) |
Reconciled means the generated classes are up to date, Failed means the last reconciliation did not succeed. Empty until the class has been reconciled for the first time. |
GPUS (.status.matchingPhysicalGPUCount) |
How many PhysicalGPU objects matched the selector. 0 means the selector is wrong or no matching card exists. It is not a readiness counter: the readiness of those devices lives in their own status. |
STATUS (message of the Ready condition) |
Human-readable message. Empty when there is nothing to report: it is an explanation, not a success indicator. It carries the error text when reconciliation failed, and names the partitionFilter.allow or sharingFilter.allow values that no matching device provides when reconciliation succeeded but part of the class went uncovered. |
AGE |
Time elapsed since the object was created. |
Until gpu-controller is upgraded to the version that writes this message, STATUS instead shows
the constant DeviceClasses are reconciled on a healthy class.
The list of generated DeviceClass names is kept out of the default output because it grows with the
number of partition and sharing variants. Add -o wide to see the DEVICECLASSES column
(.status.deviceClassNames).
To get the full list of DeviceClass names created from a specific GPU class, use:
d8 k get gpuclass ml-ai-h100 -o jsonpath='{.status.deviceClassNames}' | jqWhat information to give users requesting GPUs
Each generated DeviceClass publishes an extended resource named gpu.deckhouse.io/<device-class-name>.
To get that extended resource name, use (ml-ai-h100-1g12gb — replace with your value):
d8 k get deviceclass ml-ai-h100-1g12gb -o jsonpath='{.spec.extendedResourceName}'Example output:
gpu.deckhouse.io/ml-ai-h100-1g12gb
Users must put this string in the Pod spec to request a GPU. See Usage.
GPU class specifics and limitations
GPU classes have the following specifics and limitations:
- Validation is strict and fails closed. The GPUClass webhook has
failurePolicy: Fail, so whilegpu-controlleris unavailable, creating or updating a GPUClass is rejected. Reading and using already-generated DeviceClass objects is unaffected. - Classes may overlap. Nothing stops two GPUClass objects from selecting the same cards; they simply produce two sets of names for the same hardware. Allocation conflicts are resolved by the scheduler, not by the class definition.
- Filters do not invent capabilities. If you allow a MIG profile or sharing strategy the card does not support, no DeviceClass is created for that combination — it is skipped, with no error message. If an expected name is missing from
.status.deviceClassNames, check the card’s.status.capabilitiesfirst. - Do not edit generated objects.
gpu-controllerreconciles them, so manual changes are reverted.