Putting many teams or tenants in one cluster is a reasonable cost decision. The mistake we see is treating namespace separation as if it were a security boundary. It is not, and pretending otherwise is how a noisy neighbour becomes a real incident.
What namespaces actually give you
A namespace is a scope for names and a place to attach RBAC, quotas and policies. That is genuinely useful: each tenant gets their own slice of the API server, their own roles, their own limits. But the nodes, the kernel, and often the network are shared. A namespace is an organizational unit with policy attached, not a wall.
The controls you must actually set
Soft isolation only works if you turn on the controls. The defaults are wide open. At minimum we set resource quotas and limit ranges so one tenant cannot starve the rest, default deny network policies so namespaces cannot reach each other unless allowed, and tight RBAC so a team only sees its own scope.
kind: ResourceQuota
spec:
hard:
requests.cpu: "20"
requests.memory: 40Gi
limits.cpu: "40"
pods: "100"- ResourceQuota and LimitRange per namespace so nobody can consume the whole cluster
- Default deny NetworkPolicy, then explicitly allow the traffic each tenant needs
- Pod Security admission set to restricted so tenants cannot run privileged containers
- RBAC scoped per namespace with no cluster wide roles handed out casually
A namespace is a label with policy attached, not a wall. Treat it as a wall and you will eventually find the gap the hard way.
Where soft isolation stops
Shared nodes mean shared kernel. A container escape, a hostile workload, or a tenant that genuinely must not see another tenant's data is beyond what namespaces and policies can promise. The same goes for hard compliance or data residency boundaries, and for workloads with wildly different security postures sharing the same nodes. The noisy neighbour problem also persists at the node level even with quotas, because quotas cap requests, not every contention point like disk IO or network bandwidth.
When to reach for a harder boundary
When the risk is real, the answer is node level separation through taints and a dedicated node pool per sensitive tenant, a sandboxed runtime like gVisor or Kata, or simply a separate cluster. Separate clusters cost more and we do not reach for them lightly, but for genuinely untrusted tenants the cluster boundary is the only line we fully trust.