Skip to main content
RunBook Academy

KubernetesCVII · Namespaces and Multi-TenancyMulti-tenancy

Namespace as tenancy boundary — what it isolates and what it does not

Advanced⏱ ~17 minkubectl

What you'll learn

  • Identify what namespaces isolate by default
  • Identify what namespaces do not isolate
  • Apply the layered controls (RBAC, NetworkPolicy, ResourceQuota, PSS) for safe multi-tenancy
  • Apply the operational discipline of treating namespace isolation as a layered system

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.

Namespaces are the standard multi-tenancy boundary in soft multi-tenancy. This lesson walks what namespaces isolate by default, what they do not, the layered controls required, and the operational discipline.

What a Namespace isolates by default

flowchart LR
    A[Namespace] --> B[Resource names unique within ns]
    A --> C[RBAC scope]
    A --> D[NetworkPolicy selector scope]
    A --> E[ResourceQuota scope]
    A --> F[PSS scope via labels]
    A --> G[DNS suffix]

A Namespace isolates:

  • Resource names. Two Pods in different namespaces can have the same name.
  • RBAC scope. RoleBindings in a namespace grant permissions only within that namespace.
  • NetworkPolicy scope. Policies select Pods by namespace label.
  • ResourceQuota scope. Quotas are per-namespace.
  • PSS scope. The pod-security.kubernetes.io/ enforce label is per-namespace.
  • DNS suffix. Pods in namespace A resolve <svc>.A.svc.cluster.local; namespace B resolves <svc>.B.svc.cluster.local.

What a Namespace does NOT isolate

flowchart LR
    A[Namespace does NOT isolate] --> B[Network traffic without NetworkPolicy]
    A --> C[Node failure]
    A --> D["Resource pressure (CPU, memory, disk)"]
    A --> E[Storage backend]
    A --> F[etcd blast radius]
    A --> G[Kernel-level isolation]

A Namespace does NOT isolate:

  • Network traffic (without NetworkPolicy). Two Pods in different namespaces can talk to each other by default.
  • Node failure. All namespaces on a node fail together when the node dies.
  • Resource pressure. A Pod in namespace A can starve the node of CPU and evict Pods in namespace B.
  • Storage backend. A buggy CSI driver affects every namespace using it.
  • etcd blast radius. A bad write or kubectl delete ns cascades.
  • Kernel-level isolation. cgroups are not per-namespace.

The layered controls

flowchart LR
    A[Namespace] --> B[RBAC]
    B --> C[Who can act on objects]
    A --> D[NetworkPolicy]
    D --> E[What can talk to what]
    A --> F[ResourceQuota]
    F --> G[How much can be used]
    A --> H[LimitRange]
    H --> I["Default and min/max per container"]
    A --> J[PodSecurity]
    J --> K[What pods can run]

The layered controls:

  • RBAC. Roles, RoleBindings, ClusterRoles, ClusterRoleBindings. Restrict who can create, read, update, delete objects.
  • NetworkPolicy. Default-deny with explicit ingress/egress allowances.
  • ResourceQuota. Bounded CPU, memory, object counts, storage.
  • LimitRange. Per-container defaults and min/max constraints.
  • Pod Security Standards. Restricted by default (no privileged containers, no root, limited capabilities).

Together, these policies provide strong isolation within a single cluster.

A production tenancy stack

apiVersion: v1
kind: Namespace
metadata:
  name: tenant-a-prod
  labels:
    app.kubernetes.io/name: tenant-a-prod
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/warn: restricted
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
  namespace: tenant-a-prod
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns
  namespace: tenant-a-prod
spec:
  podSelector: {}
  policyTypes:
    - Egress
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: kube-system
      ports:
        - port: 53
          protocol: UDP
---
apiVersion: v1
kind: ResourceQuota
metadata:
  name: tenant-a-quota
  namespace: tenant-a-prod
spec:
  hard:
    requests.cpu: "32"
    requests.memory: 64Gi
    pods: "200"
    persistentvolumeclaims: "50"

The stack: namespace with PSS labels, default-deny NetworkPolicy with explicit DNS allowance, and a ResourceQuota. This is the foundation of safe multi-tenancy.

The operational failure modes

Namespace multi-tenancy fails for predictable reasons:

  • NetworkPolicy missing. Tenants can talk to each other; isolation is broken.
  • PSS permissive. A privileged container runs in the namespace; the tenant breaks out.
  • ResourceQuota missing. A tenant’s workloads starve the node; other tenants suffer.
  • RBAC too broad. A tenant’s ServiceAccount has cluster-admin; the tenant has full access.
  • LimitRange missing. Pods without resource limits are scheduled; the node is starved.

Quiz

Knowledge check · 4 questions

  1. Q1. By default, can a Pod in namespace A reach a Pod in namespace B by IP?

  2. Q2. Applying a NetworkPolicy has no effect if the cluster's CNI plugin does not implement it.

  3. Q3. Explain why a Pod in one tenant namespace can reach a Service in another, and close the gap without cutting live traffic.

    A security review runs a curl probe from a throwaway Pod in namespace `analytics` against `http://ledger.payments.svc.cluster.local:8080/health` and gets an HTTP 200 with the health payload. Both namespaces were created six months ago with RBAC and a ResourceQuota. `kubectl get networkpolicy -n payments` returns no resources, and the CNI is Calico.

  4. Q4. Name the DNS record a Pod in `analytics` uses to reach the `ledger` Service in `payments`, and say which of the two — the lookup or the connection — a default-deny ingress policy in `payments` actually stops.

Passing score: 75%. Answers are checked in this browser.

The operational discipline

Namespace multi-tenancy in production rests on five non-negotiable elements:

  • Apply every layer. RBAC, NetworkPolicy, ResourceQuota, PSS, LimitRange. None is optional.
  • Default-deny NetworkPolicy. Block all traffic by default; explicit allow as needed.
  • PSS restricted. No privileged containers by default.
  • Test isolation. Quarterly: can a tenant access another tenant’s resources?
  • Audit policies. Periodic review of every namespace’s policies.

Multi-tenancy is a layered system. The namespace is the anchor; the policies are the boundary. The discipline is to apply every layer.