Multi-Tenancy Spectrum
Less Isolation βββββββββββββββββββββββββββββββΆ More Isolation
Namespace-per-tenant β Capsule/Hierarchical β vCluster β Separate Clusters
(RBAC + Quotas) (Policy engine) (Virtual) (Physical)
Cost: Low Cost: Low Cost: Medium Cost: High
Isolation: Soft Isolation: Medium Isolation: Strong Isolation: FullPattern 1: Namespace-per-Tenant
Simplest approach β each team gets a namespace with RBAC + ResourceQuota.
apiVersion: v1
kind: Namespace
metadata:
name: team-payments
labels:
tenant: payments
cost-center: "CC-1234"
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-quota
namespace: team-payments
spec:
hard:
requests.cpu: "20"
requests.memory: "40Gi"
limits.cpu: "40"
limits.memory: "80Gi"
pods: "100"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: team-admin
namespace: team-payments
subjects:
- kind: Group
name: payments-team
roleRef:
kind: ClusterRole
name: editPros: Simple, native, no extra tools Cons: No hierarchical namespaces, CRDs are cluster-scoped, noisy neighbors
Pattern 2: Capsule (Policy-Based)
Capsule adds tenant abstraction over namespaces:
apiVersion: capsule.clastix.io/v1beta2
kind: Tenant
metadata:
name: payments-team
spec:
owners:
- name: payments-admin
kind: Group
namespaceOptions:
quota: 5 # Max 5 namespaces
resourceQuotas:
scope: Tenant # Shared across all tenant namespaces
items:
- hard:
requests.cpu: "40"
requests.memory: "80Gi"
pods: "200"
networkPolicies:
items:
- policyTypes: [Ingress, Egress]
ingress:
- from:
- namespaceSelector:
matchLabels:
capsule.clastix.io/tenant: payments-team
limitRanges:
items:
- limits:
- default:
cpu: "500m"
memory: "512Mi"
type: ContainerTenants can create multiple namespaces within their quota β self-service without cluster-admin.
Pattern 3: vCluster (Virtual Clusters)
vCluster runs full virtual Kubernetes clusters inside namespaces:
# Create a virtual cluster
vcluster create team-payments --namespace vcluster-payments
# Connect
vcluster connect team-payments --namespace vcluster-payments
# Tenant sees their own cluster!
kubectl get nodes # Virtual nodes
kubectl get ns # Their own namespaces
kubectl create ns anything # Full freedomArchitecture:
βββββββββββββββββββ Host Cluster βββββββββββββββββββ
β β
β ββββ Namespace: vcluster-payments ββββββββββββ β
β β β β
β β βββββββββββββββββββββββββββββββββββββββ β β
β β β vCluster (virtual control plane) β β β
β β β - API server β β β
β β β - Controller manager β β β
β β β - etcd (or SQLite) β β β
β β βββββββββββββββββββββββββββββββββββββββ β β
β β β β
β β Synced pods run in host namespace β β
β βββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββ Namespace: vcluster-frontend ββββββββββββ β
β β (Another tenant's virtual cluster) β β
β βββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββPros: Full cluster experience per tenant, CRDs isolated, admin-level access Cons: Extra resource overhead (1 API server per tenant), more complex networking
Decision Matrix
| Requirement | Namespace | Capsule | vCluster | Separate |
|---|---|---|---|---|
| Teams need CRDs | β | β | β | β |
| Teams need cluster-admin | β | β | β | β |
| Cost efficiency | β Best | β | β οΈ | β |
| Compliance isolation | β | β οΈ | β | β Best |
| Operational overhead | Low | Low | Medium | High |
| Self-service namespaces | β | β | β | β |
My Recommendation
- Under 10 teams: Namespace-per-tenant + NetworkPolicies + ResourceQuotas
- 10-50 teams: Capsule for self-service namespace management
- Regulated/compliance: vCluster for strong isolation without physical clusters
- Different K8s versions needed: Separate clusters (or vCluster with version pinning)


