Running third-party schedulers on Together GPU clusters is in beta. The steps and pinned version here (Kueue v0.18.3) are validated on current clusters, but the workflow and defaults may change. Report issues through the support form.
Requirements
- A Together Kubernetes GPU cluster in the Ready state.
- Cluster-admin access, which the cluster’s admin kubeconfig grants. Only project admins can download the admin kubeconfig.
kubectlconfigured against the cluster. Download the admin kubeconfig withtg clusters get-credentials <CLUSTER_ID> --set-default-context --no-json.
Install Kueue
Apply the versioned release manifest. The bundled custom resource definitions are large, so pass--server-side:
Running:
Define quotas
Kueue admits jobs against a quota that you define with three resources:- ResourceFlavor: Represents a class of nodes. One flavor is enough when your GPU nodes are homogeneous.
- ClusterQueue: Defines the cluster-wide quota pool. It must cover every resource your jobs request, including CPU and memory. Kueue never admits a job that requests a resource the ClusterQueue doesn’t cover.
- LocalQueue: Accepts the jobs users submit in its namespace and points to the ClusterQueue whose quota they draw on.
kueue-quota.yaml
nominalQuota sets how much of it the ClusterQueue can admit at once. The jobs in the following sections assume this eight-GPU quota. For your own workloads, set the GPU quota to the number of GPUs you want this queue to control.
Attach shared storage
To let queued jobs read and write the same dataset and checkpoints, bind a PersistentVolumeClaim to your cluster’s shared volume. Together provisions a static PersistentVolume named after the shared volume, so setvolumeName to your shared volume’s name:
shared-pvc.yaml
Submit a job to a queue
Point a standardbatch/v1 Job at the LocalQueue with the kueue.x-k8s.io/queue-name label, and set suspend: true. Kueue takes over the suspend flag and sets it to false when it admits the job:
gpu-job.yaml
Workload object for the job. Six GPUs fit within the eight-GPU quota, so Kueue admits the job and its pod starts. Confirm that the Workload is admitted:
Queue a second job until quota frees up
Submit a second job that also requests six GPUs. The two jobs need 12 GPUs combined, which exceeds the eight-GPU quota. To create it, copygpu-job.yaml, change metadata.name in the copy to gpu-job-b, and apply the copy.
Compare the two jobs:
QuotaReserved condition:
suspend flag:
Troubleshooting
- A job stays suspended and has no Workload: The
kueue.x-k8s.io/queue-namelabel is missing, so Kueue ignores the job and never unsuspends it. - A job’s Workload says the LocalQueue doesn’t exist: The
kueue.x-k8s.io/queue-namelabel names a LocalQueue that isn’t in the job’s namespace. - A job’s Workload is never admitted: Check the Workload’s
QuotaReservedcondition message. Either the job’s combined request exceeds the ClusterQueue quota, or the ClusterQueue doesn’t cover every resource the job requests. A ClusterQueue that covers only GPUs never admits a job whose pods also request CPU and memory, so add them tocoveredResources. - The ClusterQueue shows no active quota: Its ResourceFlavor is missing or misnamed. Each
flavors[].namemust match the name of a ResourceFlavor.
Next steps
Gang-schedule GPU jobs with Volcano
Run distributed training with all-or-nothing gang scheduling.
Run workloads on Kubernetes
Deploy pods with persistent storage and monitor them with Grafana.