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: coolappApply the manifest with kubectl:
kubectl apply -f namespace.yamlFor quick administrative work, create the same namespace imperatively:
kubectl create namespace coolappYou can then create a Pod in that namespace:
kubectl run nginx --image=nginx -n coolappList the Pods in the namespace with:
kubectl get pods -n coolappA typical result looks like this:
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 30sIf 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 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-schedulingThis 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.
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-schedulingWith 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-appThe 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 subnamespacesThese 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-aPlatform 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: 16GiApply it declaratively:
kubectl apply -f resource-quota.yamlExample 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=restrictedProduction 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.