Summary
- Kubernetes namespaces are not security boundaries; by default, they lack network, kernel, and control plane isolation, leading to a false sense of security.
- A layered approach is required: use RBAC and ResourceQuotas for trusted internal teams, and add NetworkPolicy and PodSecurityAdmission for semi-trusted workloads.
- For untrusted or paying customers, a shared control plane and kernel remain significant risks, making standard namespace hardening insufficient.
- The only way to achieve strong tenant isolation is with dedicated control planes, which platforms like vCluster provide by virtualizing Kubernetes clusters inside a namespace.
Here is a belief that quietly undermines security posture across thousands of Kubernetes clusters: namespaces are security boundaries.
They are not.
As practitioners on Reddit have put it, "Namespaces are a pretty permeable boundary in general" and "namespaces are not bound to core aspects, so they are not a secure method to isolate workloads per se." Yet the default mental model for most platform and development teams is to spin up a namespace per team, per environment, or per customer and call it a day.
The consequence is a false sense of security. A compromised pod in tenant-a can freely reach services in tenant-b. A noisy neighbor can starve the entire cluster of CPU. A rogue workload with a stolen service account token can enumerate resources across every namespace in the cluster. The blast radius is shared, and kubernetes namespace isolation — in its vanilla form — does not change that.
This article breaks down exactly what namespaces do and do not enforce, makes the gaps viscerally real with concrete examples, and then gives you a layered decision framework tied directly to your threat model.
What Kubernetes Namespaces Actually Are
According to the official Kubernetes documentation, namespaces "provide a mechanism for isolating groups of resources within a single cluster." The keyword is resources — not processes, not network traffic, not kernel access.
Out of the box, a fresh cluster ships with four namespaces:
default— where resources land if you do not specify a namespacekube-system— for Kubernetes system componentskube-public— world-readable, used for cluster infokube-node-lease— heartbeat objects for node health checking
Namespaces let you scope kubectl queries, apply RBAC policies, set resource quotas, and organize objects logically. That is genuinely useful. What they do not provide:
- No network isolation. Without a
NetworkPolicyresource and a CNI plugin that enforces it (Calico, Cilium, etc.), pods across every namespace can talk to each other freely. - No kernel boundary. Every pod on a node shares the same Linux kernel. Kubernetes namespaces are not Linux kernel namespaces — as Rapid7 highlighted, conflating the two is one of the most common and dangerous misunderstandings in Kubernetes security.
- No separate API server. Every namespace talks to the same control plane — the same API server, the same
etcddatastore, the same controller manager.
The Gaps, Made Viscerally Real
Gap 1: Your Network Is Wide Open
Run this against any cluster that has not been explicitly hardened:
kubectl get networkpolicies --all-namespaces
If the output is empty — or if your CNI does not enforce NetworkPolicy at all — every pod in every namespace can reach every other pod by IP. There is no iptables rule, no firewall drop, nothing between tenant-a and tenant-b at the network layer.
Want to prove it? Deploy a test pod in namespace-a and curl a ClusterIP service in namespace-b. It will respond. No credentials, no policy bypass needed.
Gap 2: One Kernel to Rule Them All
All containers on a given node share a single Linux kernel. A container escape — exploiting a kernel CVE — does not care about Kubernetes namespace boundaries. Once an attacker has a foothold in the kernel, they own the node, and every other tenant running on that node is compromised.
This is the fundamental difference between Kubernetes namespace isolation and true OS-level isolation. VMs get separate kernels. Namespace-isolated pods do not.
Gap 3: A Single Shared Control Plane
Every API call from every namespace flows to the same API server. If a pod's service account has overly permissive RBAC bindings — which happens more often than teams realize — an attacker can query the API server for objects across the entire cluster.
And it does not take an exotic exploit. As one practitioner noted in the community, "There's still potential in breaking other namespaces if you change PVs or CRDs which are used by other namespaces." Cluster-scoped resources like PersistentVolumes, ClusterRoles, and CustomResourceDefinitions are visible and, depending on RBAC, modifiable from any namespace.
Gap 4: DNS Enumeration Is Trivially Easy
Kubernetes DNS follows a predictable pattern: <service>.<namespace>.svc.cluster.local. From inside any pod, an attacker can probe this structure to enumerate services across namespaces — no special permissions required.
A Layered Isolation Framework Tied to Your Threat Model
The right level of isolation is not a fixed answer — it depends on how much you trust the workloads sharing your cluster. Here is a practical three-level framework.
Level 1: Trusted Internal Teams — RBAC + ResourceQuotas
Scenario: Different development teams sharing one cluster. The risk is accidental interference, not adversarial tenants.
Goal: Prevent one team from stomping on another's resources and consuming more than their fair share.
RBAC controls who can do what, scoped to a namespace. A Role in tenant-a gives no permissions in tenant-b:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: tenant-a
name: pod-access
rules:
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
Pair that with a RoleBinding scoped to the team, and you have effective access control as described in the Kubernetes RBAC documentation.
ResourceQuotas prevent noisy neighbors from monopolizing cluster resources:
apiVersion: v1
kind: ResourceQuota
metadata:
namespace: tenant-a
name: tenant-a-quota
spec:
hard:
requests.cpu: "2"
requests.memory: 2Gi
limits.cpu: "4"
limits.memory: 4Gi
pods: "10"
This is sufficient when tenants are fully trusted and the primary concern is operational hygiene.
Level 2: Semi-Trusted Tenants — Add NetworkPolicy + PodSecurityAdmission
Scenario: QA vs. production workloads, different business units, or internal services with varying security classifications.
Goal: Add network segmentation and enforce pod hardening to limit lateral movement if something goes wrong.
NetworkPolicy acts as a layer 3/4 firewall for pods. Critically, Kubernetes does not enforce any network isolation by default — you must explicitly apply policies. A good starting point, adapted from the Kubernetes Network Policy Recipes repository, is a deny-by-default rule that blocks all cross-namespace ingress:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-cross-namespace
namespace: tenant-a
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- podSelector: {}
This policy allows intra-namespace traffic (same podSelector: {} in the from field with no namespaceSelector) while silently dropping everything from other namespaces.
PodSecurityAdmission (PSA) enforces pod security standards at the namespace level. Set the restricted policy to mandate hardening practices — no privilege escalation, no root containers, mandatory seccomp profiles:
apiVersion: v1
kind: Namespace
metadata:
name: tenant-b
labels:
pod-security.kubernetes.io/enforce: restricted
The three PSA levels are Privileged (no restrictions), Baseline (prevents known privilege escalations), and Restricted (most locked-down, enforces current best practices). For semi-trusted tenants, Restricted is the right default.
Together, RBAC + ResourceQuotas + NetworkPolicy + PodSecurityAdmission get you a meaningfully hardened namespace. But there is still a shared control plane, a shared kernel, and a shared blast radius. For untrusted workloads — especially paying external customers — this is not enough.
Level 3: Untrusted or Paying External Customers — Dedicated Control Planes
Scenario: You are running a SaaS product, a managed Kubernetes offering, or an AI platform with isolated tenant environments where tenants are external, untrusted, or paying customers. A breach in one tenant's environment must not be able to reach another's.
Why Levels 1 and 2 still fail here:
A shared API server means a compromised or misconfigured tenant can potentially interact with cluster-scoped resources. A shared kernel means a container escape is a node takeover. As the community has correctly identified, "multi-cluster solutions can provide full isolation, but [they are] really expensive in resource consumption and maintenance/management effort."
You need dedicated control planes. You do not need dedicated physical clusters to get them.
The solution: vCluster
vCluster virtualizes the Kubernetes control plane itself — running a fully CNCF-certified Kubernetes cluster as lightweight processes inside the host cluster. Each tenant gets their own dedicated API server, etcd, and controller manager, packaged as pods in a namespace on the host. As one practitioner put it, "using tenant clusters, you have their own API server and etcd, therefore, what happens in a tenant cluster stays there and won't have an impact on other resources on the host cluster."
What this unlocks:
- True blast radius containment. CRD changes, RBAC mistakes, and resource exhaustion inside a tenant cluster cannot propagate to the host or neighboring tenants.
- Full cluster-admin per tenant. Tenants get
cluster-admininside their tenant cluster without any ability to affect the host cluster. - Seconds to provision, near-zero marginal cost. No waiting for physical cluster provisioning. Tenant clusters spin up in seconds and cost a fraction of dedicated infrastructure.
- 100% API compatibility. Every tenant gets a real, certified Kubernetes API — not a stripped-down or emulated version.
vCluster has been deployed across 100K+ GPU nodes and 50+ Fortune 500 and GPU cloud customers including CoreWeave, Nscale, JPMorganChase, and Adobe — with 40M+ tenant clusters created in production.
The final layer: kernel-native workload isolation with vNode
For the most sensitive environments — AI workloads running on shared GPU nodes, untrusted inference workloads, or compliance-heavy scenarios — the shared kernel is still a concern even after control plane isolation. vNode, currently in private beta, closes this gap with kernel-native workload isolation using seccomp, cgroups, AppArmor, and Linux namespaces to provide container breakout protection, without the GPU performance penalty of traditional hypervisors or VMs.
The full isolation stack becomes: vCluster for control plane isolation + vNode for workload isolation. You get dedicated-cluster-equivalent security at shared-cluster economics.
Stop Trusting Namespaces. Start Matching Isolation to Threat Model.
The core mistake is treating kubernetes namespace isolation as a security primitive. It is a convenience feature. It scopes API queries, organizes resources, and provides hooks for policies — but it does not enforce network boundaries, separate kernels, or isolate control planes out of the box.
The right approach depends entirely on who your tenants are:
For teams running workloads that require true tenant isolation — and especially for anyone building a managed Kubernetes or AI platform on shared infrastructure — vCluster is the only production-proven path to a dedicated control plane per tenant without the cost and operational overhead of physical multi-cluster architectures.
Namespaces alone are not a fortress. Build one deliberately. See how vCluster delivers tenant isolation without the overhead by requesting a demo.
Frequently Asked Questions
What is the main security risk of using only Kubernetes namespaces for isolation?
The main risk is a false sense of security; by default, namespaces do not provide any network, kernel, or control plane isolation. A compromised pod in one namespace can freely attack pods in other namespaces, interact with the shared cluster API server, and potentially exploit a kernel vulnerability to take over the entire node.
Are Kubernetes namespaces the same as Linux namespaces?
No, they are fundamentally different concepts. Kubernetes namespaces are an organizational tool for API objects within a cluster. Linux namespaces are a low-level kernel feature that isolates system resources (like process IDs and network stacks) for containers. Conflating the two leads to incorrectly assuming Kubernetes namespaces provide kernel-level isolation.
How do I isolate network traffic between Kubernetes namespaces?
You can isolate network traffic by creating NetworkPolicy resources and using a CNI (Container Network Interface) plugin that enforces them, such as Calico or Cilium. A best practice is to start with a default-deny policy for each namespace, which blocks all cross-namespace traffic unless explicitly allowed.
When are RBAC and ResourceQuotas enough for namespace isolation?
RBAC and ResourceQuotas are generally sufficient for isolating trusted internal teams where the primary risk is accidental interference, not malicious activity. RBAC prevents teams from modifying each other's resources, and ResourceQuotas prevent "noisy neighbor" problems by limiting CPU and memory consumption.
Why isn't NetworkPolicy enough for untrusted tenants?
While NetworkPolicy is a critical layer for network segmentation, it is not enough for untrusted tenants because they still share the same underlying kernel and control plane. An attacker could bypass network rules by exploiting a kernel vulnerability to escape their container or by using a compromised credential to attack the shared API server, affecting the entire cluster.
What is a tenant cluster and how does it improve security?
A tenant cluster from a platform like vCluster gives each tenant their own dedicated Kubernetes control plane (API server, controller manager, etc.) that runs as regular pods inside a namespace on the host cluster. This provides true control plane isolation, meaning a security issue or misconfiguration in one tenant's cluster is contained and cannot affect the host or other tenants.
When do I need kernel-native isolation like vNode on top of vCluster?
You need kernel-native isolation like vNode for the most sensitive workloads, such as running untrusted code from external customers, processing sensitive data on shared GPUs, or meeting strict compliance requirements. While vCluster isolates the control plane, vNode hardens the pod-to-kernel boundary itself, providing a final layer of defense against container escape vulnerabilities.
Deploy your first virtual cluster today.