Skip to main content
Using a coding agent? Load the together-volcano skill to teach your agent to write correct Volcano and GPU cluster code for Together AI. Learn more.
Running third-party schedulers on Together GPU clusters is in beta. The steps and pinned version here (Volcano v1.15.0) are validated on current clusters, but the workflow and defaults may change. Report issues to support@together.ai.
Volcano is a Kubernetes-native batch scheduler for AI, machine learning, and high-performance computing workloads. Its defining feature is gang scheduling: a group of pods is scheduled all-at-once or not at all, so a distributed training job never starts with half its workers running and the rest stuck pending. This guide installs Volcano on a Together GPU cluster and runs a gang-scheduled job across the cluster’s GPUs. For background on every field used here, see the Volcano documentation.

Prerequisites

  • A Together Kubernetes GPU cluster in the Ready state.
  • kubectl configured against the cluster. Download credentials with tg beta clusters get-credentials <cluster_id> --set-default-context.
  • Cluster-admin access. The kubeconfig from the Together CLI grants it.
Confirm you can reach the cluster and see its GPU nodes:
GPU nodes report an nvidia.com/gpu count. The NVIDIA device plugin that exposes this resource is preinstalled on Together clusters.

Install Volcano

Install the scheduler, controllers, and custom resource definitions from the versioned release manifest. For other install methods and version compatibility, see the Volcano installation guide:
Wait for the control plane to become available:
All pods should be Running or Completed:
Volcano creates a default queue automatically:
Prefer Helm? Add the chart repo and install into the same namespace: helm repo add volcano-sh https://volcano-sh.github.io/helm-charts && helm install volcano volcano-sh/volcano -n volcano-system --create-namespace.

Create a queue

A queue is the unit Volcano uses to divide cluster capacity between teams or workloads. Create one with a GPU capability cap so jobs in it can request up to eight GPUs:
research-queue.yaml
  • weight: the queue’s share of cluster resources relative to other queues when capacity is contended.
  • capability: the hard upper bound on resources the queue can consume at once.
  • reclaimable: whether the queue gives resources back to other queues when it is over its fair share.
See the queue reference for the full field list, including hierarchical queues and guaranteed resources.

Attach shared storage

Together provisions a static PersistentVolume named after your cluster’s shared volume. Bind a PersistentVolumeClaim to it so every worker reads and writes the same dataset and checkpoints:
shared-pvc.yaml
The next section mounts this claim into the job.

Run a gang-scheduled job

A Volcano Job (vcjob) wraps a set of tasks and enforces gang scheduling through minAvailable. The scheduler admits the job only once it can place at least minAvailable pods together. The following job runs four workers, each requesting two GPUs, for eight GPUs total, with the shared volume mounted at /mnt/shared:
gpu-gang-job.yaml
schedulerName: volcano routes the pods to Volcano instead of the default Kubernetes scheduler. minAvailable: 4 means all four workers start together or none do. Watch the job reach Running:
Volcano tracks the group through a PodGroup. Inspect it and the pods:
Confirm the GPUs are visible inside a worker:
Confirm the shared volume is mounted and writable from every worker. All workers read and write the same ReadWriteMany volume, so a file written by one is visible to the others:

Verify all-or-nothing behavior

Gang scheduling matters most when a job cannot fit. Delete the running job, then submit one that requests more GPUs than the cluster has (eight workers at two GPUs each is 16 GPUs, past this cluster’s 8):
Change minAvailable to 8 and replicas to 8 in the manifest and reapply. The job stays Pending and, critically, no pods run. The default scheduler would start as many as fit and strand the rest; Volcano keeps the whole group pending:
The PodGroup sits in the Inqueue phase until enough resources free up to admit the entire gang.

Route other workloads to Volcano

Any pod, Deployment, or third-party job type can use Volcano by setting schedulerName: volcano in its pod template. This is how you schedule multi-node training launched through the MPI Operator, which is preinstalled on Together clusters. For gang guarantees on those workloads, create a PodGroup and reference it from the pods; see the Volcano documentation.

Troubleshooting

  • Pods stay Pending and the PodGroup is Inqueue: the queue cannot fit minAvailable pods at once. Lower minAvailable, raise the queue’s capability, or wait for other jobs to release GPUs.
  • Pods schedule on the default scheduler instead of Volcano: schedulerName: volcano is missing from the pod template. On a vcjob it belongs under spec.
  • Job rejected on creation: the Volcano admission webhook may still be starting. Confirm volcano-admission is Running in the volcano-system namespace and reapply.
  • Queue rejects a job: the job’s total request exceeds the queue’s capability. Raise the cap or split the work.

Next steps

Queue GPU jobs with Kueue

Gate GPU jobs on quota with a Kubernetes-native queueing controller.

Manage GPU clusters

Deploy workloads, attach storage, and access the Kubernetes dashboard.