Virtual Clusters, Explained

Every Kubernetes platform team eventually hits the same wall. Multiple teams want to share your infrastructure. What does each team actually get?

The two classic answers, and why both hurt

Option one: a dedicated cluster per team. The waking world. Full physical isolation and independent machines, but building a brand new world for every team from scratch is slow, heavy, and extremely expensive.

The costs pile up fast. Every managed cluster bills a control plane fee before a single app runs. Every cluster needs its own nodes, its own upgrades, its own monitoring. Provisioning one takes around twenty minutes. Ten teams means ten clusters to patch on security-release day.

Option two: a namespace per team. Sharing a single dream space. Cheap and efficient, but the walls are paper-thin. When you share a dream level, one team's subconscious projections can easily bleed into another's.

Cheap, but the mental walls are leaky. And here's the part people underestimate: the leaks aren't where you expect.

  • CRDs are cluster-wide. Custom resource types can't be namespaced. If Team A installs version 2 of an operator and Team B needs version 1, someone loses.
  • One API server for everyone. A misbehaving controller from one team can hammer the API server that all teams depend on.
  • One Kubernetes version for everyone. Nobody can test the next release without a separate cluster anyway.
  • One blast radius. A bad admission webhook installed by one team can block deployments for every team.

So the platform team gets to choose: pay for massive physical worlds nobody fully uses, or play referee when roommate projections collide in a shared dream. For years these were the only choices.

The middle path: a cluster inside a cluster

A virtual cluster (I use the vcluster project) is a complete Kubernetes control plane that runs as a single pod inside a host cluster.

Read that again, because it sounds stranger than it is. The thing your team connects to is a real API server, with its own database, its own CRDs, its own RBAC, its own Kubernetes version. It passes conformance tests. Your tooling can't tell the difference.

But from the host cluster's point of view, that entire "cluster" is just a namespace containing a couple of pods.

Think of it like a dream within a dream. The tenant gets their own self-contained dream level with its own physics (CRDs), users, and rules. To the tenant's tools, the dream is entirely real. But to the host cluster - the waking world - the entire dream level is just a single sleeper (a pod) resting in a corner of a namespace.

How it works: the syncer

A control plane alone can't run anything. It's a database of wishes with nobody to fulfil them (the reconciliation loop idea again). So where do the actual workloads go?

A component called the syncer acts as the architect bridging the dream world and physical reality. When you design a pod inside the dream (virtual cluster), the syncer projects it down into the physical world (the host cluster) to run on real hardware. It then mirrors the status back up, so to the user inside the dream, the pod appears to be running on their own dedicated servers.

Everything else stays private. Deployments, CRDs, RBAC roles, secrets: they live only in the virtual cluster's private subconscious (its own database). The host never sees them. Only the things that must physically exist (pods, their services) get projected down.

That split is the whole trick. The expensive, conflict-prone parts of a cluster (API server, CRDs, versions) are duplicated per tenant, because they're cheap to duplicate. The genuinely expensive part (compute) stays shared.

What virtual clusters don't solve

Honesty section. The isolation is real at the API layer, not the hardware layer.

  • Workloads still share nodes and a kernel. Against merely clumsy neighbours, that's fine. Against actively hostile tenants, you still need the heavier tools: isolated node pools, sandboxed runtimes, real network policy.
  • Compute contention doesn't vanish. A tenant that eats all the CPU still hurts everyone. Resource quotas remain your friend.
  • The host cluster is still a single point of failure. If it goes down, every virtual cluster inside it goes down too. You've consolidated blast radius for control planes, not eliminated it.
  • Networking is shared. Cross-tenant traffic control still needs deliberate design.

Virtual clusters remove the organisational conflicts of shared tenancy: CRD versions, API server access, upgrade schedules, admission webhooks. The physical concerns stay exactly where they were.

Sources and further reading

  • vCluster project, the open source project this post is based on.
  • GitHub: loft-sh/vcluster. The source code and technical documentation.
  • CNCF: Conformance results for vcluster. The official CNCF submission backing the "passes conformance tests" claim in this post, vcluster is a certified Kubernetes distribution.
  • CNCF blog: Solving Kubernetes Multi-tenancy Challenges with vCluster. A broader look at the multi-tenancy problem this post covers.