What is Multi-tenancy in Kubernetes Explained Simply
Multi-tenancy in Kubernetes lets multiple teams share one cluster safely. Learn namespace-based tenancy, vCluster, RBAC, network policies, and when to go single vs multi-tenant.
Multi-tenancy in Kubernetes means multiple teams, projects, or customers share the same cluster without stepping on each other's toes. Get it right and you save cost. Get it wrong and one team can crash another's workloads.
The Core Problem
By default, Kubernetes has no concept of isolation between tenants. Pod A in namespace team-a can talk to Pod B in namespace team-b. One misconfigured resource limit can steal all cluster CPU. Multi-tenancy is the set of patterns that prevents this.
Types of Multi-tenancy
1. Namespace-based Tenancy (Soft)
Each team gets their own namespace. RBAC controls who can do what. Network policies block cross-namespace traffic.
Pros: Simple, built-in
Cons: Shared control plane, shared nodes — not true isolation
2. Virtual Clusters (Medium)
Tools like vCluster create a full Kubernetes API server per tenant, running as pods inside the host cluster.
Pros: Near-complete isolation, tenant can install CRDs freely
Cons: More overhead than namespaces
3. Separate Clusters (Hard Tenancy)
One cluster per tenant. Full isolation, separate billing.
Pros: True isolation
Cons: High cost, complex fleet management
Setting Up Namespace-based Tenancy
Step 1 — Create namespace per team
kubectl create namespace team-alpha
kubectl create namespace team-betaStep 2 — RBAC per namespace
# team-alpha-rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: team-alpha
name: team-alpha-developer
rules:
- apiGroups: ["", "apps", "batch"]
resources: ["pods", "deployments", "services", "configmaps", "jobs"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: team-alpha-binding
namespace: team-alpha
subjects:
- kind: Group
name: team-alpha-devs
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: team-alpha-developer
apiGroup: rbac.authorization.k8s.ioStep 3 — Resource quotas
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-alpha-quota
namespace: team-alpha
spec:
hard:
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi
pods: "20"
services: "10"
persistentvolumeclaims: "5"Step 4 — LimitRange (prevents resource-hogging pods)
apiVersion: v1
kind: LimitRange
metadata:
name: team-alpha-limits
namespace: team-alpha
spec:
limits:
- type: Container
default:
cpu: 500m
memory: 512Mi
defaultRequest:
cpu: 100m
memory: 128Mi
max:
cpu: "2"
memory: 4GiStep 5 — Network policy (block cross-namespace traffic)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-cross-namespace
namespace: team-alpha
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector: {} # only from same namespace
egress:
- to:
- podSelector: {} # only to same namespace
- ports:
- port: 53 # allow DNS
protocol: UDPvCluster Setup (Virtual Clusters)
# Install vcluster CLI
curl -L -o vcluster "https://github.com/loft-sh/vcluster/releases/latest/download/vcluster-linux-amd64"
chmod +x vcluster && mv vcluster /usr/local/bin
# Create virtual cluster for team-alpha
vcluster create team-alpha --namespace vcluster-team-alpha
# Connect to virtual cluster
vcluster connect team-alpha --namespace vcluster-team-alphaInside the vCluster, the team sees a full Kubernetes API — they can create CRDs, install operators, and manage their own resources without affecting other tenants.
Common Multi-tenancy Issues
Issue: Teams bypassing network policies
Fix: Use a CNI that enforces NetworkPolicy strictly (Cilium, Calico). Flannel does NOT enforce NetworkPolicy.
Issue: Node-level isolation
Namespace isolation doesn't prevent pods from reaching node metadata APIs. Fix with:
# Block AWS IMDS access
- ports:
- port: 80
to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 169.254.169.254/32 # AWS metadata serviceIssue: Shared storage class leaking data
Use per-tenant StorageClasses with encryption enabled and separate backend buckets.
Choosing the Right Model
| Requirement | Namespace | vCluster | Separate Cluster |
|---|---|---|---|
| Dev/test environments | ✅ | ✅ | ❌ too expensive |
| Separate CRDs per team | ❌ | ✅ | ✅ |
| SaaS customer isolation | ❌ | ✅ | ✅ |
| Regulatory compliance | ❌ | ⚠️ | ✅ |
| Cost efficiency | ✅✅ | ✅ | ❌ |
Tools Worth Using
- Capsule — Kubernetes multi-tenancy framework with Tenant CRD
- Loft — Commercial platform for self-service virtual clusters
- HNC (Hierarchical Namespace Controller) — Namespace hierarchy for orgs
- Kyverno — Policy engine to enforce tenant rules
Start with namespaces + RBAC + ResourceQuota for 80% of use cases. Move to vCluster when teams need their own CRDs or cluster-admin access.
Today I Fixed
Short real fixes from production — posted daily
Stay ahead of the curve
Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.
Related Articles
How to Set Up HashiCorp Vault for Secrets Management from Scratch (2026)
HashiCorp Vault is the industry standard for secrets management. This step-by-step guide shows you how to install Vault, configure it, and integrate it with Kubernetes.
What is a Service Mesh? Explained Simply (No Jargon)
Service mesh sounds complicated but the concept is simple. Here's what it actually does, why teams use it, and whether you need one — explained without the buzzwords.
What is an Admission Webhook in Kubernetes Explained
Admission webhooks intercept every Kubernetes API request before it's persisted. Learn how mutating and validating webhooks work, with real examples from OPA, Istio, and custom webhooks.