Kubernetes multi-tenancy in 2026: namespaces vs vCluster vs separate clusters, compared
Namespaces, Capsule, HNC, vCluster, Kamaji, sandboxed runtimes, or one cluster per tenant: what each Kubernetes multi-tenancy model actually isolates, what it costs per tenant, and who should operate it.
A namespace is a naming, quota and RBAC boundary. Namespaces share one API server, etcd, CRD set, webhooks and, by default, the same nodes and kernel. The Kubernetes docs call this the "soft" end of multi-tenancy.
vCluster gives each tenant its own API server, CRDs and RBAC root. In its default mode, tenant pods still run on the host's shared nodes. That is strong control-plane isolation and no kernel isolation.
One cluster per tenant isolates everything at once. Control-plane fees ($0.10/hour per cluster on EKS, GKE and AKS Standard), minimum nodes and upgrade labour all scale linearly with tenant count.
Untrusted code needs separate nodes. That means gVisor, Kata Containers or separate clusters, because a container escape crosses a namespace boundary but not a node boundary.
Most teams land on a hybrid, and Qovery operates it. Qovery runs whichever boundary you pick inside your own AWS, GCP, Azure, Scaleway or existing Kubernetes cluster.
A namespace is a naming convention with RBAC attached. Treating it as a tenant boundary is how platform teams end up explaining a cross-tenant incident to a customer.
I have run all of these models, and this guide tells you which boundary fits which tenant, what each one costs per tenant, and who ends up operating it. Prices below were checked on the vendor pricing pages on October 31, 2026.
What are the Kubernetes multi-tenancy options, and how did we compare them?
There are seven realistic Kubernetes multi-tenancy models in 2026:
Namespaces plus policy
Hierarchical Namespace Controller (HNC)
Capsule
vCluster
Kamaji
A shared cluster with dedicated node pools and a sandboxed runtime
One cluster per tenant
I scored each one on seven criteria that decide whether a platform team can run many customer environments on it.
Control-plane isolation. Does the tenant get its own API server, datastore and RBAC root, or share yours? With one shared API server, a single tenant's runaway controller competes with everyone else for capacity. API Priority and Fairness is on by default and queues requests "so that, for example, a poorly-behaved controller need not starve others" (Kubernetes docs). That reduces the damage without giving each tenant its own capacity.
Data-plane isolation. Do tenant pods share nodes, kernels and the container runtime? A container escape crosses a namespace boundary but not a node boundary.
Network isolation. By default, a pod "is non-isolated for ingress; all inbound connections are allowed". Also, "creating a NetworkPolicy resource without a controller that implements it will have no effect" (Kubernetes docs). On a CNI without NetworkPolicy support, your policies are accepted and silently ignored.
CRD and cluster-scoped independence. Can tenant A install a CRD, an operator or a mutating webhook without breaking tenant B? Namespaces break here first in practice, because CRDs are cluster-scoped and each CRD has one served version set for the whole cluster.
Operational overhead per tenant. How many control planes, upgrades, certificate rotations, ingress stacks and policy bundles does one engineer end up owning?
Cost per tenant. Managed control-plane fees, minimum node footprint, per-cluster observability and ingress, and whether small tenants can be bin-packed.
Compliance posture. What an auditor will accept as a tenant boundary for SOC 2, HIPAA, PCI scoping and EU data residency.
Two terms carry the rest of this article. The Kubernetes docs describe "'hard' multi-tenancy, which implies strong isolation, and 'soft' multi-tenancy, which implies weaker isolation". They add that hard multi-tenancy "is often used to describe cases where the tenants do not trust each other" (Kubernetes docs). Decide which one you have before you read the table. Your own dev, staging and preview environments are soft. Customers running their own code on your platform are hard.
Which Kubernetes multi-tenancy model should you pick? (comparison table)
Pick hardened namespaces for trusted internal tenants and previews, and Capsule for self-service namespaces without cluster-admin. Pick vCluster when tenants need their own API server and CRDs but not their own nodes, and Kamaji for many real control planes at low cost. Pick dedicated node pools with gVisor or Kata for untrusted code on one cluster, and one cluster per tenant when compliance or residency rules out a shared API server. HNC still appears in older guides, but it is now retired.
Model
Best for
Control-plane isolation
Node / kernel isolation
Tenant can install own CRDs
Ops overhead per tenant
Rough cost per tenant
Who should not pick it
Namespaces + NetworkPolicy + Pod Security Admission + ResourceQuota
Internal teams, dev/staging, per-PR previews
None: all namespaces share one API server and etcd
None by default: namespaces share nodes and the host kernel
No, because CRDs are cluster-scoped
One namespace, one policy set, quotas
Fraction of a node. Default limit is 110 pods per node (Kubernetes docs)
Platforms hosting untrusted customer code or contractual isolation
Hierarchical Namespace Controller (HNC)
Org-tree namespace delegation on legacy clusters
None: HNC subnamespaces share one API server
None: HNC subnamespaces share nodes
No
One extra controller and webhook
Same as namespaces
Anyone starting today: the HNC repo was archived on April 17, 2025 (GitHub)
Capsule
Self-service tenants owning groups of namespaces
None: Capsule tenants share one API server
None by default; Capsule can pin tenants to node selectors
No
One Tenant object, one controller to run
Same as namespaces, plus Capsule controller
Tenants needing cluster-admin or their own operators
vCluster
Tenants needing cluster-admin, own CRDs, a different Kubernetes version
Strong: each vCluster has its own API server, controller manager and datastore
None in shared-nodes mode; dedicated or private nodes are optional
Yes
One virtual control plane pod plus syncer per tenant
One small control-plane pod (SQLite by default) on shared nodes
Teams with only trusted services, or hostile code on shared nodes
Kamaji
Many real tenant clusters with dedicated worker nodes
Strong: Kamaji runs each tenant control plane as pods on a management cluster
Yes when each tenant cluster gets its own worker nodes
Yes
One hosted control plane per tenant plus node lifecycle
Control-plane pods plus a shared datastore (etcd, MySQL, PostgreSQL or NATS)
Small teams without capacity to run a management cluster
Shared cluster + dedicated node pools + gVisor / Kata
Untrusted code on one cluster
None: tenants share one API server
Strong: tainted node pools plus a gVisor user-space kernel or a Kata lightweight VM
No
Node pool, taints, RuntimeClass per tenant
At least one node per tenant pool; no bin-packing across tenants
Workloads sensitive to syscall overhead, or teams that need per-tenant CRDs
One cluster per tenant (EKS, GKE, AKS)
Regulated, region-pinned or contractually isolated customers
Full: each tenant gets its own managed control plane
Full: each tenant gets its own nodes
Yes
Full cluster lifecycle × N, about three upgrades a year
$0.10/hr control plane ≈ $73/month on EKS, GKE and AKS Standard, before nodes
Teams with hundreds of low-revenue tenants or internal previews
The second matrix shows what each model actually separates.
Isolates...
Namespaces
Capsule / HNC
vCluster (shared nodes)
Kamaji
Node pools + gVisor/Kata
Cluster per tenant
API server
No
No
Yes
Yes
No
Yes
etcd / datastore
No
No
Yes
Partial (can share a datastore)
No
Yes
CRDs and webhooks
No
No
Yes
Yes
No
Yes
RBAC root
No
No
Yes
Yes
No
Yes
Nodes and kernel
No
No
No (Yes with private nodes)
Yes
Yes
Yes
Network
Partial (NetworkPolicy)
Partial (NetworkPolicy)
Partial (host CNI)
Yes
Partial (NetworkPolicy)
Yes
Failure domain
No
No
Partial
Partial (shared management cluster)
Partial
Yes
Kubernetes version skew
No
No
Yes
Yes
No
Yes
In Kubernetes, isolation strength and operational cost move together. The only lever that breaks that trade-off is who operates the result.
Are Kubernetes namespaces a security boundary for isolating customer environments?
No. The Kubernetes docs describe a namespace as "a mechanism for isolating groups of API resources within a single cluster". They also say plainly that "namespace-based scoping is applicable only for namespaced objects... and not for cluster-wide objects (e.g. StorageClass, Nodes, PersistentVolumes, etc.)" (Kubernetes docs). A namespace is the right default for tenants you already trust.
What a namespace isolates:
Object names
RBAC subjects, Roles and RoleBindings
ResourceQuota and LimitRange
The default ServiceAccount
Namespaced policy objects
What it does not isolate:
Nodes and the kernel
CRDs and their versions
Mutating and validating admission webhooks
ClusterRoles and ClusterRoleBindings
PersistentVolumes and StorageClasses
Node agents and the CNI
API server throughput
The kernel point is concrete. CVE-2024-21626 in runc 1.1.11 and earlier, part of Snyk's "Leaky Vessels" disclosure, let a container process get "a working directory in the host filesystem namespace, allowing for a container escape". It scored 8.6 (High) and was fixed in runc 1.1.12 (GitHub advisory). No namespace setting stops that.
Before a namespace is defensible as a tenant boundary, add this hardening stack:
Default-deny ingress and egress NetworkPolicy in every namespace, on a CNI that enforces it (Cilium, Calico).
Pod Security Admission enforced at restricted. PSA has three levels (privileged, baseline, restricted), and PodSecurityPolicy "was deprecated in Kubernetes v1.21, and removed from Kubernetes in v1.25" (Kubernetes docs). Kyverno or OPA Gatekeeper cover anything PSA doesn't.
ResourceQuota and LimitRange in every namespace.
Zero cluster-admin bindings for tenants.
One ServiceAccount per workload, with automountServiceAccountToken: false by default.
Separate node pools if you care about kernel neighbours.
The two failures I see most:
A tenant installs an operator whose CRD version conflicts with another tenant's copy of the same operator.
A tenant's controller hammers the API server and slows everyone else down. API Priority and Fairness softens this but does not remove it.
Namespaces are the correct boundary for many environments that belong to one company: dev, staging, per-PR previews and internal teams. They are the wrong boundary for untrusted customer code or for a tenant whose isolation is written into a contract.
What do Capsule and Hierarchical Namespaces add on top of plain namespaces?
Capsule and HNC make namespaces governable at scale. They group namespaces under a tenant or parent object with inherited RBAC, quota and policy, which solves self-service and policy drift. Neither changes the underlying boundary: tenants still share one API server, one CRD set and the same nodes.
HNC came out of the Kubernetes Working Group on Multi-Tenancy. It gives you parent and child namespaces, and you can "create additional namespaces under your team's namespace, even if you don't have cluster-level permission". By default it propagates Roles and RoleBindings down the tree. Other types, such as NetworkPolicies, can be configured to propagate too. It was built for org structure, not isolation. The repository was archived on April 17, 2025 and is now read-only (GitHub), so I would not adopt it for a new platform.
Capsule has been a CNCF Sandbox project since December 13, 2022 (CNCF). It adds a cluster-scoped Tenant object that owns a group of namespaces. Policies, quotas and RBAC defined on the tenant "are automatically inherited by all the namespaces in the tenant" (GitHub). The tenant can also:
Aggregate quota across all of its namespaces (Capsule docs).
Restrict ingress classes and hostnames, storage classes, node selectors, container registries, and NodePort or LoadBalancer services (Capsule docs).
Tenant owners create their own namespaces without cluster-admin.
What they solve:
Namespace self-service without cluster-admin
Consistent policy across hundreds of namespaces
Quota per tenant rather than per namespace
What they don't solve:
CRD and webhook conflicts
Noisy neighbours on the API server
Kernel isolation
A different Kubernetes version per tenant
Who should not pick them: any platform whose tenants need their own operators, pinned CRD versions, or cluster-admin inside their own boundary.
Both also add a controller and an admission webhook to the critical path of namespace creation. If the webhook is down, nobody gets a namespace.
vCluster vs namespaces: when does a virtual cluster give better tenant isolation?
vCluster beats namespaces the moment a tenant needs any of these:
cluster-admin
its own CRDs
its own cluster-scoped objects
a different Kubernetes minor version
That is because each virtual cluster runs its own control plane. vCluster does not beat namespaces on kernel isolation in its default mode, where tenant pods run on the host cluster's shared nodes.
How it works. "Every Tenant Cluster runs a dedicated control plane: API server, controller manager, and data store" (vCluster on GitHub). These run as a single StatefulSet pod in one host namespace. The datastore is embedded SQLite by default, with embedded etcd or external PostgreSQL, MySQL or RDS for bigger tenants. A syncer copies pods, ConfigMaps, Secrets, Services, Ingress and Gateway API objects into the host namespace, and the host scheduler places the pods (vCluster docs).
What vCluster isolates:
The API server and its request load
CRDs and their versions
Cluster-scoped resources
An RBAC root where the tenant really is cluster-admin
The Kubernetes version, separate from the host's
What it shares by default: vCluster's own docs say "tenants share the same kernel and worker nodes", and pods use the host cluster's network. Node DaemonSets and the storage backend are shared too. A container escape from a vCluster pod lands on a shared host node. Newer releases add dedicated node pools and Private Nodes (v0.27+), where external nodes join the tenant cluster "with their own CNI, CSI, and networking stack". That closes much of the gap, at the cost of per-tenant nodes.
Where vCluster is the right answer:
Per-PR or per-customer clusters that start in seconds
CI jobs that need cluster-admin to install operators
SaaS trial and demo environments
Giving internal teams a real cluster experience without real clusters
If your tenants need their own API server but not their own nodes, vCluster is the honest answer and a well-built product. It is also a CNCF Certified Kubernetes distribution.
Trade-offs to plan for:
A second layer to debug when a pod misbehaves.
Edge cases in what the syncer supports.
Host and virtual versions to manage. vCluster tests matching host and tenant versions; mismatched pairs are "likely compatible" but not officially tested (vCluster docs).
Fleet features such as sleep mode live in vCluster Platform rather than the open-source engine.
Who should not pick it:
Teams running only their own trusted services. Namespaces are cheaper and simpler.
Teams with hostile workloads on shared nodes. They need sandboxed runtimes, private nodes or separate clusters.
Ship faster on infrastructure you control.
Qovery gives your team self-service, isolated environments on your own AWS, GCP, Azure or Scaleway account - or your existing Kubernetes cluster. Start deploying in under 10 minutes.
When is one Kubernetes cluster per customer the only acceptable answer, and what does it cost?
Go one cluster per tenant when data residency, compliance scope or a contractual isolation clause makes a shared API server unacceptable. It is the only model that isolates control plane, kernel, network and failure domain at once.
What you get:
Hard multi-tenancy
Independent upgrade windows and failure domains
Optional per-tenant cloud accounts and billing
An audit story an assessor understands on the first call
What you pay (control plane only, checked October 31, 2026):
Amazon EKS: $0.10 per cluster per hour, rising to $0.60 once a version leaves its 14-month standard support window and enters extended support (AWS).
Google GKE: a flat $0.10 per cluster per hour for Autopilot and Standard alike. A $74.40 monthly credit per billing account covers one zonal or Autopilot cluster (Google Cloud).
Azure AKS: the Free tier has no SLA and no fee. Standard is $0.10 and Premium (with long-term support) is $0.60 per cluster per hour (Azure).
At $0.10 an hour, each cluster costs about $73 a month before a single node. That is about $730/month at 10 tenants, $3,650 at 50 and $14,600 at 200. On top of that, each tenant needs:
The smallest viable node pool, usually two or three nodes for availability
An ingress controller
Observability agents and CSI drivers
None of it can be bin-packed across tenants.
The bigger cost is upgrade labour and drift. Kubernetes ships "approximately three times per year" (Kubernetes), and each minor version is supported for "roughly fourteen (14) months" (Kubernetes). With 50 clusters, that means 150 cluster upgrades a year, each with its own add-on compatibility checks. Managed providers enforce the schedule with auto-upgrades or the extended-support surcharge.
Middle options to try before you go all-in:
Dedicated node pools with taints and tolerations per tenant.
gVisor, "an application kernel... [that] runs in userspace" (gVisor), or Kata Containers' "lightweight virtual machines" (Kata Containers) through a RuntimeClass.
Per-tenant cloud accounts with a shared platform layer.
Kamaji, which runs "the Kubernetes Control Plane components in Pods instead of dedicated machines" on a management cluster (Kamaji on GitHub). Each tenant gets a real cluster with its own worker nodes, without a full managed control plane per tenant.
Who should not pick it: a team running 200 internal preview environments. That is a namespace or vCluster problem, and a cluster per preview will wreck both the budget and the on-call rotation.
Cluster-per-tenant works when tenant count is small and revenue per tenant is high. It stops working when tenant count grows faster than the platform team.
Can you mix namespaces, vCluster and separate clusters in one platform?
Yes, and most mature platforms do. The isolation tier should follow each tenant's trust level and contract, not a single company-wide decision. My rule: trust and contract decide the boundary, scale decides the automation.
The CNCF's 2024 survey shows teams already mix tiers. 88% of respondents separate applications with namespaces and 65% with separate clusters (CNCF Annual Survey 2024).
Internal and preview: many namespaces on a shared cluster, with default-deny NetworkPolicy, restricted PSA, quotas and auto-stop for idle environments.
Self-service tenants: vCluster or Capsule tenants on the same shared cluster, so tenants get admin rights inside their own boundary.
Regulated or per-region customers: a dedicated cluster, sometimes in a dedicated cloud account, with the same deployment pipeline on top.
Mixing has a cost: three debugging surfaces, three RBAC models and three upgrade paths. Once you accept that, the deciding question becomes who runs it.
Start every tenant at namespaces. Promote a tenant to vCluster when it asks for CRDs or cluster-admin. Promote it to a dedicated cluster when compliance or residency forces it. Don't design for your hardest tenant on day one.
Who operates all this? Running per-customer environments without a Kubernetes operations team
The isolation model decides your security posture. The platform layer decides whether two engineers can run it. Every model above plain namespaces adds control planes, upgrades, policy bundles and lifecycle work that someone has to own.
The CNCF's 2025 survey lists lack of training (36%) and security (36%) among the top challenges, behind cultural change (47%) (CNCF Annual Survey 2025). In small teams, those challenges all land on the same two people.
The end state most teams want:
Developers create, clone, stop and destroy environments without filing tickets.
The platform enforces RBAC, quotas, network policy and upgrades by default.
This is where we built Qovery. Qovery is an internal developer platform that deploys and operates applications inside your own cloud account on AWS, GCP, Azure, Scaleway, or your existing Kubernetes cluster. It gives you:
An isolated namespace for each environment, with per-environment RBAC
Git-push deployments
A preview environment for every pull request
Auto-stop for non-production environments
Managed cluster upgrades
Databases backed by managed cloud services
To be precise about where Qovery fits: it is not a multi-tenancy isolation technology. It does not replace vCluster's per-tenant API server, and it does not pretend a namespace is a kernel boundary. It removes the operations work around whichever boundary you choose: cluster lifecycle, upgrades, environment lifecycle, RBAC and cost control.
If your tenants must install their own CRDs and operators and hold cluster-admin themselves, pick vCluster or a dedicated cluster for that boundary. Qovery can still run the clusters underneath.
Bring-your-own-cloud (BYOC) matters here. Your cloud bill, Savings Plans and committed-use discounts, and all customer data stay in your own account. That is usually the same requirement that pushed the team toward per-tenant clusters in the first place.
Common combinations:
Qovery environments on a shared cluster for internal and preview work.
One Qovery-managed cluster per regulated customer.
vCluster alongside, for tenants that need cluster-admin.
How do I set up isolated environments with Qovery from Claude Code or Cursor?
Install the Qovery Agent Skills once. Your coding agent can then create the cluster, the environments and the isolation defaults for you. It proposes a plan and asks for your approval before applying anything to your cloud account.
The skills work with Claude Code, Cursor, Codex, OpenCode and Gemini CLI. Install them globally for any compatible agent:
Add the Qovery MCP Server to Claude Code for read-only inspection of what already exists (OAuth login in the browser):
BASH
claude mcp add --transport http qovery https://mcp.qovery.com/mcp --callback-port 4242
Enable write access only when you want the agent to change infrastructure. This also needs write access turned on in the Qovery Console:
BASH
claude mcp add --transport http qovery "https://mcp.qovery.com/mcp?read_write=true" --callback-port 4242
The skills handle deployment: qovery-onboard, qovery-deploy, qovery-troubleshoot, qovery-optimize, qovery-speedup, qovery-preview and qovery-terraform. The MCP Server operates what already exists.
Then ask in plain language, for example "create an isolated environment per customer on my existing EKS cluster with Qovery", and approve the plan. Setup details are in the AI agent quickstart and the Claude Code integration page.
Frequently asked questions
Are Kubernetes namespaces a security boundary?
Only a soft one. A namespace scopes names, RBAC and quotas, but every namespace shares the API server, etcd, CRDs, admission webhooks and, by default, the nodes and kernel. The Kubernetes docs say namespace scoping does not apply to cluster-wide objects such as Nodes and PersistentVolumes. Use namespaces for tenants who trust each other.
vCluster vs namespaces: which gives better tenant isolation?
vCluster isolates more. Each tenant gets its own API server, datastore, CRDs and RBAC root, so tenants can be cluster-admin without affecting each other. In its default shared-nodes mode, vCluster shares the kernel and nodes just like namespaces do. Add dedicated or private nodes, or a sandboxed runtime, for kernel isolation.
When should I use a separate Kubernetes cluster per customer instead of vCluster?
Use a separate cluster when compliance scope, data residency or a contract requires a dedicated control plane, network and failure domain, or when tenants run untrusted code you won't put on shared nodes. Stay on vCluster when tenants mainly need their own API server and CRDs.
How much does running one Kubernetes cluster per tenant cost compared to a shared cluster?
EKS, GKE and AKS Standard each charge $0.10 per cluster per hour, about $73 a month (prices checked October 31, 2026). At 200 tenants that is about $14,600 a month in control-plane fees alone, before each cluster's minimum nodes, ingress and observability. A shared cluster pays one fee and bin-packs tenants onto shared nodes.
Can I mix namespaces, vCluster and separate clusters in the same platform?
Yes. A common setup uses hardened namespaces for internal and preview environments, vCluster for tenants who need cluster-admin, and dedicated clusters for regulated or region-pinned customers. The cost is three operational models, so decide early who runs them.
What is the difference between soft and hard multi-tenancy in Kubernetes?
The Kubernetes docs describe hard multi-tenancy as strong isolation, typically for tenants who do not trust each other, and soft multi-tenancy as weaker isolation. Teams in one company are usually soft multi-tenancy. External customers running their own code are hard multi-tenancy.
Alessandro leads product at Qovery. He drives the changelog, roadmap, and product strategy - turning customer feedback into platform capabilities.
Next step
Ship faster on infrastructure you control.
Qovery gives your team self-service, isolated environments on your own AWS, GCP, Azure or Scaleway account - or your existing Kubernetes cluster. Start deploying in under 10 minutes.