Choose Kueue mode or plain mode¶
The adapter runs in one of two modes, chosen by a single key: the kueue section of its
configuration. Present means Kueue mode. Absent means plain mode. There is no other switch.
| Kueue mode | Plain mode | |
|---|---|---|
| Configuration | kueue.localQueue set |
no kueue section |
| Start gate | annotation kueue.x-k8s.io/admission-gated-by |
spec.suspend: true |
Open |
removes dispatch's gate from the annotation | sets suspend: false and the opened annotation, raises A; with a hold in place, writes only the opened annotation (holds) |
| Readmission gate | dispatch-admission, an AdmissionCheck controller |
none needed |
| Hold | Workload spec.active: false |
TrainJob spec.suspend: true |
Who writes spec.suspend |
Kueue; the adapter never does | the adapter |
| Needs in the cluster | Kueue, a LocalQueue and ClusterQueue, dispatch-admission |
nothing beyond Trainer and JobSet |
Use Kueue mode when your cluster queues and shares GPUs with Kueue. Use plain mode when it does not.
Kueue mode¶
Set the kueue section:
{
"namespace": "team-a",
"runtimes": [{"kind": "ClusterTrainingRuntime", "name": "torch-distributed"}],
"kueue": {
"localQueue": "lq",
"priorityClass": "low",
"admissionCheck": "dispatch-admission"
}
}
localQueueis required. Every TrainJob gets the labelkueue.x-k8s.io/queue-namewith it.priorityClassis optional. When set, every TrainJob getskueue.x-k8s.io/priority-classwith it; it names a Kueue WorkloadPriorityClass.admissionCheckis optional in the schema but is needed to write. See below.admissionLeasenames the controller's Lease; the default isdispatch-system/dispatch-admission.
You need, in the cluster: Kueue v0.20 (the adapter requires the API group-version
kueue.x-k8s.io/v1beta2 and coordination.k8s.io/v1), the LocalQueue, its ClusterQueue listing the
AdmissionCheck for every flavor, the AdmissionCheck object, and the controller running.
Install the admission controller does that.
With admissionCheck unset, preflight sets ReadmissionGate to no with the reason
kueue.admissionCheck is not set, and the adapter is observe-only: it reads and classifies, and
Start is refused. Treat the key as required.
Plain mode¶
Leave the kueue section out:
{
"namespace": "team-a",
"runtimes": [{"kind": "ClusterTrainingRuntime", "name": "torch-distributed"}]
}
Nothing re-admits a TrainJob without Kueue, so no readmission gate runs and none is needed;
preflight declares ReadmissionGate no with the reason
not needed: nothing re-admits a TrainJob without Kueue. That no is not a fault: the capability
says whether a gate runs, and plain mode writes normally without one.
Kueue must not manage queue-less jobs. If Kueue is installed with manageJobsWithoutQueueName
on, it would make a Workload for every TrainJob and take over spec.suspend. When it runs the probe, preflight catches
this: the probe is a TrainJob with no queue, and if a Workload appears for it the adapter refuses
the cluster for plain mode with ErrUnsupported, naming the setting. If Kueue's API is not served,
or the adapter may not list Workloads, the check is skipped without a word, so where Kueue is
installed, grant list on workloads
even in plain mode.
In plain mode Open and Release do the work that Kueue and the controller do in Kueue mode, and
both refuse to raise the admission count while a pod of the object may still run. Release on a
plain-mode hold returns ErrPodsRemain until the pods are gone, and the caller retries.
Never two executions at once explains it.
Changing mode¶
The mode is a property of the adapter instance, not of the object. An object created gated by the annotation is opened by removing the annotation, and one created suspended is opened by unsuspending it, so an adapter in the other mode would not operate on it correctly. Do not change the configuration under jobs in flight: stop or drain them first.