KubernetesXIV · Namespace ArchitectureTenancy and isolation
Namespaces — logical isolation is not security isolation
What you'll learn
- Explain what a Namespace isolates and what it does not
- Reason about namespaces as the standard unit of soft multi-tenancy
- Distinguish the isolation provided by namespaces from the isolation provided by NetworkPolicy, RBAC, ResourceQuota, and node-level separation
- Identify production failure modes caused by namespace misuse
Prerequisites
Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16
A Namespace is the standard tenancy boundary in Kubernetes. It is
the unit at which almost every cluster-scoped policy is anchored:
RBAC RoleBindings, NetworkPolicy selectors, ResourceQuotas,
LimitRanges, Pod Security Standards enforcement, and the DNS
suffix. But a Namespace by itself does almost none of those things —
it is a name prefix. The isolation a Namespace provides is whatever
the operator wires into it. This lesson establishes what that means
in production.
What is a Namespace
A Namespace is a cluster-scoped object (apiVersion: v1, kind: Namespace)
that scopes resource names. Every namespaced object (Pod, Service,
Deployment, ConfigMap, Secret, etc.) belongs to exactly one Namespace.
Cluster-scoped objects (Node, PersistentVolume, ClusterRole,
StorageClass, Namespace itself) do not.
kubectl get namespaces
NAME STATUS ACTIVE AGE
default Active 30d # every object without a namespace goes here
kube-system Active 30d # control-plane and add-on workloads
kube-public Active 30d # readable by any user; used for cluster-wide info
kube-node-lease Active 30d # node heartbeats
my-app Active 5d
team-a Active 5d
team-b Active 5d
What a Namespace actually isolates
A Namespace itself only isolates resource names. Two Pods in different Namespaces can have the same name; two Services can have the same name; two ConfigMaps can have the same name. That is the entire native isolation guarantee.
Everything else is bolted on:
| Capability | What enforces it |
|---|---|
| Name uniqueness within a Namespace | Kubernetes itself |
| RBAC (who can act on objects in this Namespace) | Role + RoleBinding in the Namespace |
| Network isolation between Namespaces | NetworkPolicy (and a CNI that enforces it) |
| CPU / memory / object-count limits | ResourceQuota in the Namespace |
| Default request/limit defaults for Pods | LimitRange in the Namespace |
| Pod Security Standards (privileged / baseline / restricted) | Namespace labels (pod-security.kubernetes.io/enforce) |
| Default ServiceAccount and image pull policy | Namespace annotations and defaults |
| DNS suffix | Built in: <svc>.<ns>.svc.cluster.local |
A Namespace with none of the above is just a name prefix.
What a Namespace does not isolate
A Namespace by itself is not a security or blast-radius boundary. The following failures cross Namespace boundaries:
- Network reachability. Two Pods in different Namespaces can
talk to each other by default, because the default
NetworkPolicyon most CNIs is “allow all.” Isolation requires an explicitNetworkPolicythat denies traffic between Namespaces. - Resource exhaustion. A Pod in
team-acan starve the node of CPU and evict Pods inteam-bbecause the kernel cgroups and kubelet do not see Namespaces.ResourceQuotalimits the sum of Pods in the Namespace but does not isolate the node they share. - Node failure. All Namespaces on a node fail together when the node disappears. The kubelet, the CNI agent, and the runtime are shared.
- Storage backend. A buggy or slow CSI driver affects every Namespace that uses it.
- etcd blast radius. A bad write or a
kubectl delete nscan cascade. Namespaces are deletable; deleting one tears down every object in it unlessfinalizersand the API server stop it.
A real production isolation model
A multi-tenant Kubernetes estate combines Namespaces with the following layered controls:
flowchart LR
A[Cluster] --> B[Node pool A]
A --> C[Node pool B]
B --> D[Namespace: prod-app]
B --> E[Namespace: prod-data]
C --> F[Namespace: dev-app]
C --> G[Namespace: build-runners]
D --> H[NetworkPolicy: deny-all + explicit allow]
E --> H
F --> I[NetworkPolicy: deny-all + explicit allow]
D --> J[ResourceQuota: 32 CPU, 64Gi memory]
D --> K[LimitRange: default 500m / 512Mi]
D --> L[PodSecurity: restricted]
D --> M[RoleBinding: team-a -> dev, ci]
The Namespace is the unit at which every policy is anchored. None of those policies is enforced by the Namespace itself.
How to design a Namespace layout
Two patterns dominate production:
- Per-environment (
dev,staging,prod) — simplest, works when teams share infrastructure. Often combined with cluster separation (one cluster per environment, see Part CI). - Per-team (
team-a,team-b) — when teams have independent services and need independent quotas. Often combined with per-environment, givingteam-a-prod,team-a-staging, etc.
The worst case is a single Namespace for “everything production.” It satisfies the name-prefix requirement and provides none of the production benefits. If you have one Namespace for prod, you have no tenancy model.
How to inspect namespaces
The three commands you will use constantly:
$ kubectl get namespacesNAME STATUS AGE
default Active 30d
kube-system Active 30d
team-a-prod Active 12d
team-b-prod Active 12d$ kubectl describe namespace team-a-prodName: team-a-prod
Labels: kubernetes.io/metadata.name=team-a-prod
Annotations: pod-security.kubernetes.io/enforce: restricted
Status: Active
Resource Quotas
Name: team-a-prod-cpu
Resource Used Hard
-------- --- ---
cpu 24 32
memory 48Gi 64Gi
pods 84 200
Resource Limits
Name: team-a-prod-defaults
Type Resource Min Max Default
---- -------- --- --- -------
Container cpu - - 500m
Container memory - - 512Mi$ kubectl api-resources --namespaced=true | head -20NAME SHORTNAMES APIVERSION NAMESPACED KIND
bindings v1 true Binding
configmaps cm v1 true ConfigMap
endpoints ep v1 true Endpoints
events ev v1 true Event
limitranges limits v1 true LimitRange
persistentvolumeclaims pvc v1 true PersistentVolumeClaim
pods po v1 true Pod
...Cross-course references
- The Linux course covers Linux namespaces (
man 7 namespaces) — the underlying kernel primitive Kubernetes reuses for Pod isolation. Pods and Linux namespaces are related but distinct concepts: a Pod gives each container a private mount, PID, IPC and (with default CNI) network namespace, but the same Pod shares these across its containers. - The VyOS course covers VRF-style logical isolation at the network layer; Kubernetes NetworkPolicy achieves a similar effect at L3/L4 in the cluster but does not extend outside the cluster.
- The OPNsense course covers firewall-based multi-tenancy; that is the network boundary Kubernetes sits inside for a typical on-premises deployment.
- The Observability course covers tenant-aware metrics and logs; multi-tenant Kubernetes observability requires namespace-aware relabelling.
Quiz
Knowledge check · 4 questions
Q1. What does a Kubernetes Namespace actually isolate by default, without any additional policies?
Q2. A production deployment targeting the default namespace is acceptable when no other namespace has been created for it.
Q3. An operator runs `kubectl delete namespace prod-app`. They expected only the Deployment to be removed. What actually happens, and how would you have prevented it?
The namespace `prod-app` contains a Deployment with 6 replicas, a StatefulSet with 3 PVCs backed by a StorageClass with `reclaimPolicy: Delete`, two ConfigMaps, three Secrets, two ServiceAccounts, a NetworkPolicy, a ResourceQuota, and a RoleBinding. The StatefulSet's `volumeClaimTemplates` use the default storage class. The operator is in the prod cluster, the namespace is not on a no-cascade list, and they ran the command as a service account with cluster-admin scope.
Q4. Name three policies that operate at the Namespace level and explain what each one isolates.
Passing score: 75%. Answers are checked in this browser.
Production discipline
A Namespace is a name prefix. The isolation it provides in production is entirely a function of which policies the operator binds to it. A production-grade tenancy model pairs every Namespace with:
- A
NetworkPolicyset that defaults to deny-all with explicit ingress and egress allowances. - A
ResourceQuotathat bounds CPU, memory, object count, and storage. - A
LimitRangethat sets sane per-container defaults so new Pods land inside the quota. - A
pod-security.kubernetes.io/enforce: restrictedlabel so Pods cannot run as privileged, with root, or with dangerous capabilities by default. - A
RoleBinding(or cluster-scoped binding) that grants only the identities that need to operate there. - A documented blast radius — what can the namespace take down if a workload misbehaves, and what should an incident responder expect to see?
Namespaces are the standard unit of multi-tenancy; the platform’s isolation guarantees are the policies attached to them.