# KubeStellar: one binding policy, many Kubernetes clusters

> A CNCF Sandbox project that adds a control layer above your clusters, so you describe a workload and a policy saying where it should run, and the platform propagates it. It is built around a workspace cluster, an inventory of clusters, and a transport that carries the result to each one.

**kubestellar/kubestellar** — KubeStellar - a flexible solution for multi-cluster configuration management for edge, multi-cloud, and hybrid cloud

- Repository: https://github.com/kubestellar/kubestellar
- Website: https://kubestellar.io
- Stars: 725 · Forks: 328
- Language: Go
- License: Apache-2.0
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/kubestellar-kubestellar

## The problem is that clusters are deployed and configured one at a time

KubeStellar is a Cloud Native Computing Foundation Sandbox project that simplifies the deployment and configuration of applications across multiple Kubernetes clusters. It gives the experience of working with a single cluster, and it integrates with the tools you are already familiar with, eliminating the need to modify existing resources.

The problem it names is concrete. In a single cluster setup, developers typically access the cluster and deploy Kubernetes objects directly. Without KubeStellar, multiple clusters are usually deployed and configured individually, which is time-consuming and complex.

The reason multiple clusters exist in the first place is worth reading, because it tells you whether the tool fits. The documented advantages are separation of environments such as development, testing and staging, isolation of groups, teams or departments, compliance with enterprise security or data governance requirements, enhanced resiliency including across different clouds, improved resource availability, access to heterogeneous resources, and the capability to run applications on the edge, including in disconnected environments.

Those last two are the interesting ones for edge. Access to heterogeneous resources means clusters with different hardware and different cloud providers, and running on the edge in disconnected environments means the control path has to work when the network does not. Those two requirements are what shape the architecture, and they are also where the hard problems live.

## Binding policies are the one new concept you have to learn

KubeStellar simplifies the multi-cluster problem by allowing developers to define a binding policy between clusters and Kubernetes objects. It then uses your regular single-cluster tooling to deploy and configure each cluster based on these binding policies, making multi-cluster operations as straightforward as managing a single cluster.

That is the whole idea in one sentence, and it is a good design, because it means you do not learn a new deployment API. You write the manifest you already write, and you add a policy object that says which clusters it belongs in. The existing resource does not change, which is what the eliminating the need to modify existing resources line refers to.

The repository topics name the moving parts: deployment, edge, gitops, placement, rollout, scheduling, status, summarization and synching. Placement and rollout are the two halves of the binding policy idea, and status and summarization are the two halves of the feedback loop.

The ecosystem table describes the core engine as delivering BindingPolicy, WDS, ITS, WEC workload propagation. Those three component names carry the architecture, and it is worth spelling them out because they are how the rest of the platform is organised.

WDS is the control plane where you author things, ITS is the inventory that holds the descriptions of the clusters you manage, and WEC is the execution site on each cluster where the propagated workload actually lands. The propagation path runs from the workspace, through the transport, to the execution sites, and the status travels back the other way.

## The Go module tells you what it is built on

The go.mod file is a good map of the design, because a multi-cluster control plane is mostly a pile of Kubernetes client libraries and controllers.

The module is github.com/kubestellar/kubestellar, built for go 1.25.0. The direct dependencies show four distinct concerns.

First, the Kubernetes stack, at version 0.32.13 across the board: k8s.io/api, apiextensions-apiserver, apimachinery, apiserver, cli-runtime, client-go, code-generator, component-base and the full k8s.io/kubernetes module, plus sigs.k8s.io/controller-runtime v0.20.4 and sigs.k8s.io/yaml. The full kubernetes dependency rather than a curated set is the tell that this project builds API machinery, not just a client.

Second, open-cluster-management.io/api v1.0.0. The Open Cluster Management API is the model for describing a set of clusters and registering them in a central place, and that is exactly what the inventory does. Depending on it rather than inventing a cluster registry is a significant decision.

Third, two expression engines. github.com/google/cel-go v0.22.0 gives you Common Expression Language, and github.com/dop251/goja is a JavaScript interpreter in pure Go. Two of them means the binding policies can be written in more than one language, which is how you express conditions like which cluster a workload belongs in without hard coding a list.

Fourth, github.com/kubestellar/kubeflex v0.9.3. KubeFlex is the project that provides the hosting cluster used in development, and its presence as a direct dependency is a hint about how you run KubeStellar locally.

## Building locally, and the hosting cluster the Makefile expects

The Makefile shows how the project expects to be run and built, and the variables at the top are the important part.

```bash
DOCKER_REGISTRY ?= ghcr.io/kubestellar/kubestellar
```

```bash
IMAGE_TAG ?= $(shell git rev-parse --short HEAD)
```

```bash
KIND_HOSTING_CLUSTER ?= kubeflex
```

So the images are published to ghcr.io under the kubestellar organisation, and the default image tag is the short commit hash, which means every build is uniquely identifiable and nothing depends on a moving tag like latest. The default hosting cluster is named kubeflex for both kind and k3d, so the local development environment is a KubeFlex instance, either on kind or on k3d, chosen by the same variable name.

The Makefile also defines the two images it builds, a controller-manager image and an ocm-transport-controller image, plus a kflex-get-kubeconfig image used to obtain credentials for the hosting cluster, with INSTALL_KUBEFLEX defaulting to true. The controller manager verbosity is exposed as a variable too, so you can turn the logging up when you are debugging why a binding policy did not do what you expected.

For test infrastructure there is an envtest target pointing at kubebuilder assets version 1.26.1, and a default namespace of default and a default WDS name of wds1 for local deploys.

The readme points at the quickstart in the project documentation for the actual installation walkthrough, and at the website for usage and architecture material. There is no single install command in the readme itself, so the quickstart page is the place to start, and the Makefile targets are what you will be running from it.

## The repository layout is mostly governance, security and docs

Look at the top level entries and you get a sense of what kind of project this is.

The code is in api, cmd, config, core-chart, options, pkg, scripts and test. The core-chart directory is the Helm chart, config is the standard controller-runtime configuration, and options holds the command line and configuration options the controllers expose.

Then there is an unusual amount of governance and security material. There is GOVERNANCE.md plus GOVERNANCE-CONSOLE.md and GOVERNANCE-HIVE.md, which tells you the project runs a hive structure with a console project governed separately from the core. There is a DCO file, meaning contributors sign off on the Developer Certificate of Origin rather than a CLA, and a CODE_OF_CONDUCT.md.

The security side is unusually well documented for a Kubernetes project. There is SECURITY.md, a SECURITY_CONTACTS file, a THREAT-MODEL.md, a SECURITY-INSIGHTS.yml, and a .secrets.baseline file, which is the detect-secrets baseline used to catch credentials in commits. A multi-cluster control plane has a wide attack surface, because a compromise of the control plane reaches every cluster it manages, and a project that publishes a threat model is telling you it has thought about that.

The rest is developer infrastructure: .golangci.yaml for linting, .goreleaser.yaml for release binaries, .pre-commit-config.yaml, .prow.yaml for the Prow based CI, .clomonitor.yml, and a Makefile.venv for a Python virtual environment used by some tooling. There is also ADOPTERS.md, ONBOARDING.md, RELEASES documentation in RELEASE.md, REPOSITORIES.md, and users.md, which is a habit worth copying: the users document tells people what they are running.

The one thing to note is a duplication warning at the very top of the readme. There are two README files with nearly identical content, at /README.md and /docs/content/readme.md, and the note asks that if you update shared content in one you make the same change in the other. That is a small thing that tells you the readme is generated into the docs site, and it is a mild trap for contributors who edit one and not the other.

## A console, an MCP server, and community cards around the engine

The ecosystem section is new relative to what most people know about this project, and it is where the AI tooling story sits.

The core engine is complemented by sub-projects that deliver UI, AI agent tooling, and community content. The console is an AI-powered web dashboard with 160+ cards, GPU monitoring and AI missions. The console-marketplace holds 153+ community card presets covering GPU, AI and ML, ArgoCD, OPA, Falco and LLM-d. The console-kb is an AI knowledge base of community missions and operational runbooks. And kubestellar-mcp is an MCP server for AI agent tooling across Claude, Cursor, Windsurf and VS Code.

The try it line is notable because it removes the install barrier for evaluation. You can start the console in demo mode with no install required, monitor clusters, deploy workloads, manage GPU resources and troubleshoot with 400+ AI-powered missions.

The readme frames the combination as an AI-native stack: kubestellar-mcp for natural-language cluster operations paired with the console monitoring cards, for end-to-end AI inference infrastructure management.

The honest read is that the console is where you would evaluate this project, and where most of the visible activity is. The core repository is the engine, and the sub-projects are separate repositories with their own release cycles. That matters for adoption, because adopting the console means adopting a set of moving parts beyond the engine, and the 400+ missions figure is a count of bundled presets, not evidence that any particular mission works for your cluster.

There is also a community presence worth noting for a project at this stage: a Slack channel in the CNCF workspace, kubestellar-dev and kubestellar-users mailing lists, a community meeting calendar, and past meeting recordings on YouTube.

## Where KubeStellar is the wrong tool

There are clear cases where this is the wrong choice, and they are about scale and topology rather than about features.

The first is a single cluster. Everything in the design, the binding policies, the inventory, the transport, the per-cluster execution sites, exists to spread one declaration across many destinations. With one cluster you would be running a control plane to talk to one cluster, and the readme itself says the tool is particularly beneficial if you are currently deploying in a single cluster and are looking to expand to multiple clusters, or if you are already using multiple clusters and are seeking a less cumbersome developer experience. If neither applies, you are adding a layer without a job for it.

The second is clusters that are simply too many. The inventory and the transport have to hold and update state for every cluster you register. A fleet of several hundred clusters with frequent membership churn is a different engineering problem from a handful, and the project documentation does not describe how the platform behaves at that scale.

The third is a fully disconnected estate with no edge requirement. The listed advantage about running on the edge, including in disconnected environments, describes a capability, not a detail of how the transport behaves when a cluster is unreachable for a week. The readme does not document that behaviour, and status reporting for unreachable clusters is exactly the kind of thing you need to know before you commit.

The fourth is if you want GitOps through a tool you already run. The topics include gitops, and a GitOps tool that reconciles per cluster does much of what a binding policy does, with the tooling your team already knows. The difference in approach is that KubeStellar adds a central decision point with its own controllers and its own transport, rather than extending the GitOps tooling you have.

And the fifth is the maturity question. KubeStellar is a CNCF Sandbox project, which is the early stage of the CNCF lifecycle, and the release history shows v0.29.0 in November 2025 followed by v0.30.0 in May 2026, with a release candidate in between. The repository is not archived and the last push was on 2026-10-16, so work is happening, but a Sandbox project with a version number below 1.0 is going to have API changes.

## Against a federated API mesh, and against a plain GitOps loop

Two comparisons make the value proposition clearer.

The first is against a service mesh or a federated API layer. A service mesh connects workloads inside and across clusters and gives you one control plane for traffic policy. KubeStellar is not about traffic, it is about configuration objects: you want the same Deployment, with cluster specific values, to exist in several places, and you want one place to say which. The difference in approach is that a mesh operates on the network path between workloads, while a binding policy operates on the placement of the workload itself. A team needs one, the other, or both, and confusing them leads to putting policy in the wrong layer.

The second is against a plain GitOps loop with per cluster repositories or per cluster values files. The difference in approach is where the decision is made. In the GitOps model, the repository holds the answer and the tooling distributes it, so a conditional placement rule has to be encoded as templating or as separate manifests per cluster. In the KubeStellar model, the repository holds the workload and the policy holds the condition, and the platform evaluates the condition and decides.

That is a genuine improvement in the multi cluster case, because the number of things you have to maintain grows with the number of clusters in the first model and with the number of rules in the second. The cost is that the policy is now a second API to learn and to debug, and a mistake in a policy propagates to every cluster it matches.

So the deciding question is narrow. If your clusters differ only in values and you have a handful of them, per cluster templating is simpler and you already have the tooling. If you have clusters whose selection depends on runtime properties, and the number of clusters is growing, the policy model is what you need.

## Conclusion

Adopt KubeStellar if you run several Kubernetes clusters and want one place to decide which workload goes where, especially with edge or disconnected clusters in the mix. Skip it if a single cluster covers your deployment, since the whole design is about spreading across many. Verify first that the version you install matches the Kubernetes libraries it vendors, that the transport model suits how isolated your remote clusters are, and how the workload status reporting behaves when a cluster is unreachable.

## FAQ

### What is KubeStellar and what problem does it solve?

KubeStellar is a CNCF Sandbox project that simplifies deployment and configuration of applications across multiple Kubernetes clusters. You define a binding policy between clusters and Kubernetes objects, and it uses your regular single-cluster tooling to deploy each cluster based on those policies.

### What are the WDS, ITS and WEC components in KubeStellar?

They are the parts of the core engine. The ecosystem table describes kubestellar as the core engine delivering BindingPolicy, WDS, ITS and WEC workload propagation, where the workspace holds what you author, the inventory holds the cluster descriptions, and the execution site is where the workload lands on each cluster.

### How do I run KubeStellar locally?

The Makefile targets a KubeFlex hosting cluster, with KIND_HOSTING_CLUSTER and K3D_HOSTING_CLUSTER both defaulting to kubeflex, and INSTALL_KUBEFLEX defaulting to true. The project documentation has a quickstart page linked from the readme, and the Makefile also exposes a default namespace of default and a default WDS name of wds1 for local deploys.

### Is KubeStellar suitable for edge and disconnected clusters?

Running applications on the edge, including in disconnected environments, is one of the listed advantages of a multi-cluster setup, and edge is a topic the repository is tagged with. The readme does not describe how the transport behaves when a cluster is unreachable, so that behaviour needs checking for your own topology.

### What is the relationship between KubeStellar and the console projects?

The core repository is the engine, and the sub-projects deliver UI, AI agent tooling and community content. The console is an AI-powered web dashboard, console-marketplace holds community card presets, console-kb is a knowledge base of missions and runbooks, and kubestellar-mcp is an MCP server for AI agent tooling.

### What licence does KubeStellar use and how active is it?

The project is licensed under Apache-2.0, with the LICENSE file at the root of the repository. The last push was on 2026-10-16 and the recent releases include v0.30.0 on 2026-05-13 and v0.29.0 on 2025-11-06, so it is a Sandbox stage project below version 1.0.

## Sources

- [kubestellar/kubestellar on GitHub](https://github.com/kubestellar/kubestellar)
- [License: Apache-2.0](https://github.com/kubestellar/kubestellar/blob/main/LICENSE)
- [Project website](https://kubestellar.io)
- [README](https://github.com/kubestellar/kubestellar/blob/main/README.md)
- [Releases](https://github.com/kubestellar/kubestellar/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/kubestellar-kubestellar
