Running several teams or several customers on the same Kubernetes platform boils down to three distinct isolation levels, each with an operational cost proportional to the isolation strength it provides. None is free: the choice depends on the real trust level between tenants, not an abstract technical preference.

Level 1: namespaces + RBAC + ResourceQuota

The lightest model separates tenants by namespace, with RBAC restricting who can act where and ResourceQuota capping each namespace’s consumption. Operational cost is minimal (a single cluster to operate), but isolation stays software-level and partial: every tenant shares the same Kubernetes control plane, the same kube-apiserver, the same etcd, and a flaw in the API server or a misconfigured NetworkPolicy potentially exposes every tenant at once.

# "Soft" isolation: RBAC + quota per namespace,
# but the control plane stays shared across every tenant
apiVersion: v1
kind: ResourceQuota
metadata:
  namespace: tenant-a
spec:
  hard:
    requests.cpu: "10"
    requests.memory: 20Gi

This level suits internal teams that trust each other: the separation protects against mistakes (a misconfigured deployment spilling into another team’s resources), not against malicious intent.

Level 2: vcluster, a virtual control plane per tenant

vcluster runs a complete virtual Kubernetes API server per tenant, inside a namespace of the host cluster: each tenant believes it has its own cluster (its own datastore — an embedded SQLite database by default, etcd being an opt-in choice — its own CRDs, potentially its own Kubernetes version), while sharing the host cluster’s physical nodes and data plane.

# Each tenant gets an isolated control plane,
# workloads still land on the same physical nodes
vcluster create tenant-a --namespace vc-tenant-a

This middle level isolates what matters most in practice (CRDs, admission webhooks, Kubernetes versions) without multiplying physical nodes: a tenant can install its own CRDs without ever conflicting with another’s. The trade-off stays real: different tenants’ workloads still share the same physical nodes, hence the same kernel-level attack surface and the same underlying resource contention, without the guarantee level a genuinely separate cluster provides.

Level 3: physically separate clusters

Maximum isolation assigns a complete, distinct Kubernetes cluster to each tenant, with its own control plane and its own physical nodes. Nothing is shared, which eliminates any possibility of one tenant affecting another, whether by mistake or malicious intent.

# Each tenant gets its own complete cluster:
# no resource, physical or logical, is shared
# → typically managed via one ArgoCD ApplicationSet per cluster,
#   see the article on GitOps at scale

The cost climbs accordingly: each cluster imposes its own control-plane costs (often billed by the cloud provider regardless of actual load), its own version-upgrade management, and multi-cluster orchestration (see the article on GitOps at scale) to keep every cluster from becoming a hand-managed island.

The deciding criterion: trust, not technical preference

The choice between these three levels isn’t primarily about features but about the real trust level between tenants. Internal teams within the same organization, subject to the same compliance constraints, often settle for level 1. Paying external customers, with distinct compliance requirements (healthcare, finance) or justified mutual distrust, generally demand level 3, whatever the cost. vcluster occupies the middle ground: enough when level 1’s software isolation is judged insufficient, but where level 3’s cost stays disproportionate to the actual risk.

Takeaway

Kubernetes multi-tenancy resolves into three levels of increasing isolation: namespaces + RBAC + ResourceQuota (lightweight, shared software isolation), vcluster (isolated virtual control plane, shared physical nodes), separate clusters (total isolation, maximum operational cost). The deciding criterion is the real trust level between tenants, not an architectural preference: stronger isolation than needed costs money with no real benefit, weaker isolation than needed exposes a risk that only surfaces at the incident, a central trade-off the moment a Kubernetes migration needs to host several teams or several customers on the same platform.