Namespaces are one of Kubernetes' most important tools for organizing a cluster shared by multiple applications, teams or tenants. They provide a scope for namespaced resources and work with features such as role-based access control, network policies and resource quotas.

Standard Kubernetes namespaces are intentionally flat. A namespace cannot natively contain another namespace. For organizations that wanted a parent-child namespace model, the Kubernetes community developed the Hierarchical Namespace Controller, commonly called HNC.

There is an important modern caveat: HNC is no longer an actively maintained Kubernetes project. Its repository was archived in 2025. Existing HNC installations can still help explain the hierarchical namespace model, but new production architectures should not treat HNC as a currently supported Kubernetes feature.

Kubernetes namespaces explained

A Kubernetes namespace provides a logical scope for namespaced resources such as Pods, Deployments, Services, ConfigMaps and Secrets. Resource names must be unique inside a namespace, but the same name can exist in another namespace.

Namespaces do not contain Nodes, PersistentVolumes, StorageClasses or other cluster-scoped resources.

A namespace can be created declaratively with a manifest:

apiVersion: v1
kind: Namespace
metadata:
  name: coolapp

Apply the manifest with kubectl:

kubectl apply -f namespace.yaml

For quick administrative work, create the same namespace imperatively:

kubectl create namespace coolapp

You can then create a Pod in that namespace:

kubectl run nginx --image=nginx -n coolapp

List the Pods in the namespace with:

kubectl get pods -n coolapp

A typical result looks like this:

NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          30s

If you omit the namespace, kubectl normally queries the namespace configured in the current context, which is often default. Therefore, the Pod above will not appear in a plain kubectl get pods command if the current namespace is default.

Namespaces and Kubernetes security

Namespaces are an important security and administration boundary, but a namespace by itself is not a complete security boundary. Modern multi-tenant designs typically combine namespaces with RBAC, NetworkPolicy, ResourceQuota, LimitRange and Pod Security Admission.

For example, a RoleBinding can grant a development team permissions only inside the coolapp namespace. A NetworkPolicy can restrict which workloads communicate across namespace boundaries, while ResourceQuota can prevent one tenant from consuming an unreasonable share of cluster resources.

This combination makes namespace-based tenancy useful when multiple teams share a Kubernetes control plane.

Multi-tenant Kubernetes architecture

A multi-tenant Kubernetes cluster allows multiple teams, applications or organizations to share the same cluster. This can improve infrastructure utilization and reduce the operational overhead associated with maintaining a separate cluster for every tenant.

kubernetes multiple tenants

Kubernetes can support multiple tenants in a single cluster.

However, shared clusters also increase the importance of isolation. Tenants share cluster-level infrastructure and potentially worker nodes, so administrators must deliberately configure authorization, networking, resource consumption and workload security.

For stronger isolation requirements, separate clusters or virtual-cluster technologies may be more appropriate than namespace-only tenancy.

The problem hierarchical namespaces tried to solve

Native Kubernetes namespaces are flat. Consider an application named acme-app used by three companies, each with HR, Finance and Scheduling workloads. A flat namespace design might look like this:

acme-app-company-a-hr
acme-app-company-a-finance
acme-app-company-a-scheduling
acme-app-company-b-hr
acme-app-company-b-finance
acme-app-company-b-scheduling
acme-app-company-c-hr
acme-app-company-c-finance
acme-app-company-c-scheduling

This works, but common policies can become repetitive. An administrator who wants the same RBAC policy in every Company A namespace must normally manage that policy across several namespaces.

isolated kubernetes cluster tenants

Namespaces can be used to isolate tenants inside a shared Kubernetes cluster.

How the Hierarchical Namespace Controller worked

The Hierarchical Namespace Controller extended Kubernetes with parent-child relationships between namespaces. HNC could create subnamespaces and propagate selected policy objects from a parent namespace to its descendants.

The same Acme example could therefore be represented conceptually as a tree:

acme-app
├── company-a
│   ├── company-a-hr
│   ├── company-a-finance
│   └── company-a-scheduling
├── company-b
│   ├── company-b-hr
│   ├── company-b-finance
│   └── company-b-scheduling
└── company-c
    ├── company-c-hr
    ├── company-c-finance
    └── company-c-scheduling

With HNC, policy defined higher in the hierarchy could be propagated to descendants. HNC also supported delegated namespace creation, which allowed a team with appropriate permissions in a parent namespace to create subnamespaces without receiving unrestricted cluster-wide namespace creation privileges.

Those capabilities made HNC attractive for namespace-as-a-service platforms and large shared clusters.

Historical HNC kubectl example

HNC provided the kubectl hns plugin. After an administrator installed the controller and plugin, a hierarchy could be created with commands such as these:

kubectl create namespace acme-app

kubectl hns create company-a -n acme-app
kubectl hns create company-a-hr -n company-a
kubectl hns create company-a-finance -n company-a
kubectl hns create company-a-scheduling -n company-a

kubectl hns create company-b -n acme-app
kubectl hns create company-b-hr -n company-b
kubectl hns create company-b-finance -n company-b
kubectl hns create company-b-scheduling -n company-b

kubectl hns create company-c -n acme-app
kubectl hns create company-c-hr -n company-c
kubectl hns create company-c-finance -n company-c
kubectl hns create company-c-scheduling -n company-c

kubectl hns tree acme-app

The resulting tree would resemble:

acme-app
├── [s] company-a
│   ├── [s] company-a-finance
│   ├── [s] company-a-hr
│   └── [s] company-a-scheduling
├── [s] company-b
│   ├── [s] company-b-finance
│   ├── [s] company-b-hr
│   └── [s] company-b-scheduling
└── [s] company-c
    ├── [s] company-c-finance
    ├── [s] company-c-hr
    └── [s] company-c-scheduling

[s] indicates subnamespaces

These commands are useful for understanding existing HNC environments, but they should now be treated as legacy examples rather than instructions for a new production deployment.

Do not install the old HNC v0.8 manifest

Older versions of this tutorial installed HNC v0.8.0 from the former kubernetes-sigs/multi-tenancy repository. That procedure is obsolete.

HNC later moved to its own hierarchical-namespaces repository, reached a production-oriented 1.0 release in 2022 and released version 1.1 in 2023. The project was subsequently retired, and its repository was archived in April 2025.

For that reason, a modern Kubernetes tutorial should not tell administrators to install the old controller from an outdated GitHub release manifest. Archived controllers do not receive the ongoing compatibility, bug-fix and security maintenance expected from an actively supported Kubernetes component.

Modern alternatives to hierarchical namespaces

For new Kubernetes environments, start with native namespaces and build the required policy model around them. A typical namespace-as-a-service design combines several Kubernetes features:

  • RBAC to control which users and service accounts can access each namespace.
  • NetworkPolicy to control allowed network communication between workloads.
  • ResourceQuota to limit aggregate resource consumption inside a namespace.
  • LimitRange to establish default and allowed resource requests and limits.
  • Pod Security Admission to enforce Pod Security Standards at the namespace level.
  • Labels and annotations to identify ownership, environment, cost center and policy intent.
  • GitOps or policy automation to apply common configuration consistently across groups of namespaces.

For example, a modern cluster can label namespaces according to tenant and environment:

kubectl label namespace company-a-hr tenant=company-a
kubectl label namespace company-a-finance tenant=company-a
kubectl label namespace company-a-scheduling tenant=company-a

Platform automation can then use those labels as part of a broader policy and deployment strategy. This does not make the namespaces hierarchical, but it provides an explicit and maintainable way to group them without depending on an archived controller.

Example namespace ResourceQuota

A multi-tenant cluster should also protect shared capacity. The following ResourceQuota limits the aggregate compute resources consumed by workloads in a namespace:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: tenant-compute
  namespace: company-a-hr
spec:
  hard:
    requests.cpu: "4"
    requests.memory: 8Gi
    limits.cpu: "8"
    limits.memory: 16Gi

Apply it declaratively:

kubectl apply -f resource-quota.yaml

Example Pod Security Admission configuration

Kubernetes can also enforce Pod Security Standards through namespace labels. For example, the following command configures a namespace to enforce the restricted policy:

kubectl label namespace company-a-hr \
  pod-security.kubernetes.io/enforce=restricted

Production policy choices should be tested against the workloads that actually run in the namespace. A restrictive policy is useful only when applications can operate correctly under it.

Hierarchical namespaces in modern Kubernetes

The original idea behind hierarchical namespaces remains useful: large clusters need a way to group namespaces, delegate administration and apply common policy consistently. What changed is the implementation guidance.

Native Kubernetes namespaces are still flat. HNC demonstrated how parent-child relationships and policy propagation could make namespace-based multi-tenancy easier, but HNC is now an archived project rather than an actively maintained Kubernetes extension.

If you maintain an existing HNC deployment, the hierarchy and kubectl hns commands remain important operational knowledge. If you are designing a new platform, prefer actively maintained Kubernetes capabilities and automation for RBAC, networking, quotas, Pod Security and namespace provisioning. Where namespace-level isolation is not strong enough, consider a multi-cluster or virtual-cluster architecture instead.