Volcano: a batch scheduler that sits beside kube-scheduler, not inside it
A Cloud Native Batch System (Project under CNCF)
At a glance
- What is it?
- Volcano is a CNCF incubating, Kubernetes-native batch scheduling system aimed at AI, big data and HPC jobs. It adds gang scheduling, queues and job-level lifecycle control that the default scheduler does not provide, at the cost of running and operating a second scheduler.
- Who is it for?
- Volcano fits teams already running Kubernetes who need gang scheduling, queue-level fairness or job lifecycle control for Spark, Flink, Ray, PyTorch, TensorFlow or MPI workloads, and who are willing to run a second scheduler alongside kube-scheduler. It is the wrong tool for single-pod services, for clusters where every workload can tolerate partial placement, and for teams that cannot absorb the operational cost of a second scheduling control loop.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What Volcano adds that kube-scheduler does not
The default Kubernetes scheduler places pods one at a time. A machine learning training job that needs eight workers across eight GPUs can end up with six pods running and two pending indefinitely, because nothing in the default scheduler treats the group as an all-or-nothing unit. Volcano's README frames the project as a Kubernetes-native batch scheduling system that extends and enhances kube-scheduler, and the workloads it names are exactly the ones where partial placement wastes the resources already committed: AI/ML/DL training, bioinformatics and genomics, and other big data applications.
The audience is therefore narrow and specific. If you run Spark, Flink, Ray, TensorFlow, PyTorch, Argo, MindSpore, PaddlePaddle, Kubeflow, MPI, Horovod or MXNet on Kubernetes and you have felt the cost of a half-placed job, Volcano is aimed at you. The README lists integration documentation for Spark Operator, native Spark, Flink, KubeRay, PyTorch, TensorFlow, kubeflow/trainer v2 and kubeflow/training-operator v1. If your workloads are long-running HTTP services, none of this applies.
Scheduler, controller and admission webhook: the three moving parts
Volcano is not a fork of kube-scheduler that you swap in. It runs as its own components alongside the existing control plane. The README points to an architecture diagram in docs/images/volcano-architecture.png rather than describing the components in prose, so the layout below is what the repository structure and the referenced integrations imply rather than something the README spells out in text.
The core is a second scheduler that watches the same API server. Jobs are expressed through Volcano's own custom resources, and the scheduler evaluates them as groups rather than as independent pods. A controller component reconciles those custom resources into the pods that the scheduler then places, which is why the framework integrations are documented per framework: the operator for Spark, Flink, Ray or Kubeflow has to emit Volcano job objects instead of bare pod specs. An admission webhook completes the picture, intercepting pod creation so that pods belonging to a Volcano job are routed to the Volcano scheduler rather than to kube-scheduler.
The README notes that the scheduler is built on kube-batch, referencing issue #241 and pull request #288. That lineage explains the queue-and-gang vocabulary: kube-batch was the Kubernetes SIG project that explored batch semantics before this work moved into Volcano. It also means the scheduling logic has a longer history than the Volcano repository itself, and that anyone who has read kube-batch design documents will recognize the shape of the plugin model.
Installing it and pointing a job at it
The README does not include an installation command block, so the exact Helm chart values and kubectl invocations cannot be quoted from the supplied material. What the README does establish is that Volcano is deployed into a Kubernetes cluster and that framework operators are configured to use it, for example through the Spark Operator integration page, the Flink on k8s operator documentation, the KubeRay documentation and the kubeflow/trainer v2 scheduling guide, all linked from the Ecosystem section.
That pattern matters more than any single command. Adoption is not a one-line install followed by nothing else. You install the Volcano components, then you change how your jobs are submitted so that they produce Volcano job objects, then you confirm that the admission webhook is routing those pods to the Volcano scheduler. Each integration page in the README's Ecosystem list is the authoritative source for its framework, and the versions of those operators move independently of Volcano's own release cadence.
One concrete versioning fact is visible in the release list: v1.15.2 and v1.14.5 were both published on 2026-08-29, and v1.13.4 followed on 2026-08-31. Three lines are being maintained in parallel, which is useful if you are pinned to an older minor but also means you should read the release notes for the specific line you install rather than assuming the newest tag is the only supported one.
The second-scheduler tax
The clearest limitation is structural rather than a bug. Volcano is a second scheduler. The README describes it as extending and enhancing kube-scheduler, not replacing it, which means both schedulers coexist and both watch the same API server. Every pod in the cluster now has to be routed correctly: Volcano jobs to Volcano, everything else to kube-scheduler. If the admission webhook is misconfigured or unavailable, pods fall through to the default scheduler and you lose gang semantics silently, with jobs that look like they are running normally until you notice that half of them never started.
Scheduling decisions also become harder to reason about during incidents. A pending pod can be pending because Volcano's queue is full, because a gang cannot be satisfied, because a plugin rejected the node, or because the pod never reached Volcano at all. The default scheduler has one place to look. This does not.
The README's own framing is broad: it says Volcano provides a comprehensive set of features for batch and elastic workloads and cites over fifteen years of collective operational experience. That is a statement about the team's background, not about what any given release ships. The feature set that is actually enabled depends on the plugins configured in your deployment, and the README does not enumerate them. Treat the feature list as a menu, not a guarantee.
Where a plain Kubernetes Job is the better answer
If your workload is embarrassingly parallel and each pod is independently useful, gang scheduling buys you nothing and costs you a second scheduler. A Kubernetes Job with a parallelism count, or a Deployment, will place work as capacity appears and will make progress even when the cluster is fragmented. Volcano's value comes from refusing to start work that cannot finish, and that refusal is a liability when partial progress is genuinely fine.
Kueue is the natural comparison point, though it is not named in the supplied material, so the difference has to be stated carefully. Volcano's approach, as the README describes it, is a full batch scheduling system with its own scheduler process and its own job resources. The alternative pattern in the Kubernetes ecosystem is to keep kube-scheduler and add queueing and admission control in front of it, so that jobs wait in a queue until quota is available and are then scheduled by the standard scheduler. The trade-off is direct: Volcano can make scheduling decisions that a queueing layer cannot, because it owns the placement decision, while a queueing layer keeps a single scheduler in the cluster and inherits its behaviour, its metrics and its failure modes unchanged. If your problem is quota and fairness rather than placement, the queueing approach is less machinery.
Maintenance, releases and the Apache-2.0 boundary
Volcano is Apache-2.0 licensed and is an incubating project of the CNCF, per the README. The licence permits commercial use and modification; it also means there is no vendor obligation to support your deployment. The README's note about CNCF membership is an invitation to participate, not a support contract.
Maintenance cost shows up in three places. First, the parallel release lines: v1.15.2, v1.14.5 and v1.13.4 all received releases within days of each other in late August 2026, which suggests backports are maintained but also that you need to track which line you are on. Second, the integration surface: Volcano's compatibility with Spark, Flink, Ray, Kubeflow and the rest depends on those projects' operators emitting the right objects, and those projects release on their own schedules. Third, the scheduler itself: because it makes placement decisions, tuning it is ongoing work rather than a one-time configuration.
The README states that hundreds of contributors participate in commits, reviews, issue discussions, documentation and design proposals. That is a statement about activity, and activity is not the same as stability. The concrete signal to check is whether the specific plugins and integrations you depend on appear in the release notes for the version you plan to run.
What to verify before you commit a cluster to it
Three checks come before any installation. Confirm the Kubernetes version compatibility for your target Volcano release, because a second scheduler that watches the same API server is sensitive to API changes in a way that a queueing layer is not. Read the release notes for the specific minor line you intend to run, since three lines are active and the newest tag is not automatically the right one for an existing cluster. And confirm that your framework's operator documentation, the pages linked from the README's Ecosystem section, describes a Volcano path for the operator version you are running, not just for Volcano itself.
After that, the decision is about whether gang semantics are worth a second control loop. The README's own framing, a Kubernetes-native batch scheduling system that extends kube-scheduler, tells you the project assumes you keep the default scheduler and add this beside it. If you cannot operate two schedulers, the answer is no regardless of the feature list.
Editorial conclusion
Volcano fits teams already running Kubernetes who need gang scheduling, queue-level fairness or job lifecycle control for Spark, Flink, Ray, PyTorch, TensorFlow or MPI workloads, and who are willing to run a second scheduler alongside kube-scheduler. It is the wrong tool for single-pod services, for clusters where every workload can tolerate partial placement, and for teams that cannot absorb the operational cost of a second scheduling control loop. Before adopting it, verify your Kubernetes version against the compatibility matrix for the release you intend to install, confirm which plugins ship enabled in that version's Helm chart, and check whether your framework's operator already documents a Volcano integration path.
Community notes