Skip to main content
RunBook Academy

KubernetesXIV · Namespace ArchitectureTenancy and isolation

Namespaces — logical isolation is not security isolation

Advanced⏱ ~16 minkubectlkubeadm

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

Not yet marked complete on this device.

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:

CapabilityWhat enforces it
Name uniqueness within a NamespaceKubernetes itself
RBAC (who can act on objects in this Namespace)Role + RoleBinding in the Namespace
Network isolation between NamespacesNetworkPolicy (and a CNI that enforces it)
CPU / memory / object-count limitsResourceQuota in the Namespace
Default request/limit defaults for PodsLimitRange in the Namespace
Pod Security Standards (privileged / baseline / restricted)Namespace labels (pod-security.kubernetes.io/enforce)
Default ServiceAccount and image pull policyNamespace annotations and defaults
DNS suffixBuilt 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 NetworkPolicy on most CNIs is “allow all.” Isolation requires an explicit NetworkPolicy that denies traffic between Namespaces.
  • Resource exhaustion. A Pod in team-a can starve the node of CPU and evict Pods in team-b because the kernel cgroups and kubelet do not see Namespaces. ResourceQuota limits 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 ns can cascade. Namespaces are deletable; deleting one tears down every object in it unless finalizers and 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:

  1. Per-environment (dev, staging, prod) — simplest, works when teams share infrastructure. Often combined with cluster separation (one cluster per environment, see Part CI).
  2. Per-team (team-a, team-b) — when teams have independent services and need independent quotas. Often combined with per-environment, giving team-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:

Read-only / Safe
$ kubectl get namespaces
NAME              STATUS   AGE
default           Active   30d
kube-system       Active   30d
team-a-prod       Active   12d
team-b-prod       Active   12d
Read-only / Safe
$ kubectl describe namespace team-a-prod
Name:         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
Read-only / Safe
$ kubectl api-resources --namespaced=true | head -20
NAME                              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

  1. Q1. What does a Kubernetes Namespace actually isolate by default, without any additional policies?

  2. Q2. A production deployment targeting the default namespace is acceptable when no other namespace has been created for it.

  3. 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.

  4. 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 NetworkPolicy set that defaults to deny-all with explicit ingress and egress allowances.
  • A ResourceQuota that bounds CPU, memory, object count, and storage.
  • A LimitRange that sets sane per-container defaults so new Pods land inside the quota.
  • A pod-security.kubernetes.io/enforce: restricted label 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.