What is a Kubernetes Namespace?
A Kubernetes namespace helps separate a cluster into logical units. It helps granularly organize, allocate, manage, and secure cluster resources. Here are two notable use cases for Kubernetes namespaces:
- Apply policies to cluster segments—Kubernetes namespaces let you apply policies to different parts of a cluster. For example, you can define resource policies to limit resource consumption. You can also use container network interfaces (CNIs) to apply network policies that define how communication is achieved between pods in each namespace. Learn more about Kubernetes networking.
- Apply access controls—namespaces let you define role-based access control (RBAC). You can define a role object type and assign it using role binding. The role you define is applied to a namespace, and RoleBinding is applied to specific objects within this namespace. Using this technique can help you improve the security of your cluster.
In a new cluster, Kubernetes automatically creates the following namespaces: default (for user workloads) and three namespaces for the Kubernetes control plane: kube-node-lease, kube-public, and kube-system. Kubernetes also allows admins to manually create custom namespaces.
Related content: Read our guide to Kubernetes architecture
In this article:
Kubernetes Namespaces Concepts
There are two types of Kubernetes namespaces: Kubernetes system namespaces and custom namespaces.
Default Kubernetes namespaces
Here are the four default namespaces Kubernetes creates automatically:
- default—a default space for objects that do not have a specified namespace.
- kube-system—a default space for Kubernetes system objects, such as kube-dns and kube-proxy, and add-ons providing cluster-level features, such as web UI dashboards, ingresses, and cluster-level logging.
- kube-public—a default space for resources available to all users without authentication.
- kube-node-lease—a default space for objects related to cluster scaling.
Custom Kubernetes namespaces
Admins can create as many Kubernetes namespaces as necessary to isolate workloads or resources and limit access to specific users. Here is how to create a namespace using kubectl:
kubectl create ns mynamespace
Related content: Read our guide to Kubernetes clusters
The Hierarchical Namespace Controller (HNC)
Hierarchical namespaces are an extension to the Kubernetes namespaces mechanism, which allows you to organize groups of namespaces that have a common owner. For example, when a cluster is shared by multiple teams, each team can have a group of namespaces that belong to them.
With hierarchical namespaces, you can create a team namespace, and under it namespaces for specific workloads. You don’t need cluster-level permission to create a namespace within your team namespace, and you also have the flexibility to apply different RBAC rules and network security groups at each level of the namespace hierarchy.
When Should You Use Multiple Kubernetes Namespaces?
In small projects or teams, where there is no need to isolate workloads or users from each other, it can be reasonable to use the default Kubernetes namespace. Consider using multiple namespaces for the following reasons:
- Isolation—if you have a large team, or several teams working on the same cluster, you can use namespaces to create separation between projects and microservices. Activity in one namespace never affects the other namespaces.
- Development stages—if you use the same Kubernetes cluster for multiple stages of the development lifecycle, it is a good idea to separate development, testing, and production environments. You do not want errors or instability in testing environments to affect production users. Ideally, you should use a separate cluster for each environment, but if this is not possible, namespaces can create this separation.
- Permissions—it might be necessary to define separate permissions for different resources in your cluster. You can define separate RBAC rules for each namespace, ensuring that only authorized roles can access the resources in the namespace. This is especially important for mission critical applications, and to protect sensitive data in production deployments.
- Resource control—you can define resource limits at the namespace level, ensuring each namespace has access to a certain amount of CPU and memory resources. This enables separating cluster resources among several projects and ensuring each project has the resources it needs, leaving sufficient resources for other projects.
- Performance—Kubernetes API provides better performance when you define namespaces in the cluster. This is because the API has less items to search through when you perform specific operations.
Quick Tutorial: Working with Kubernetes Namespaces
Let’s see how to perform basic namespace operations—creating a namespace, viewing existing namespaces, and creating a pod in a namespace.
You can create a namespace with a simple kubectl command, like this:
kubectl create namespace mynamespace
This will create a namespace called mynamespace, with default configuration. If you want more control over the namespace, you can create a YAML file and apply it. Here is an example of a namespace YAML file:
kind: Namespace apiVersion: v1 metadata: name: mynamespace labels: name: mynamespace kubectl apply -f test.yaml
To list all the namespaces currently active in your cluster, run this command:
kubectl get namespace
The output will look something like this:
NAME STATUS AGE default Active 3d kube-node-lease Active 3d kube-public Active 3d kube-system Active 3d mynamespace Active 1d
Creating Resources in the Namespace
When you create a resource in Kubernetes without specifying a namespace, it is automatically created in the current namespace.
For example, the following pod specification does not specify a namespace:
apiVersion: v1 kind: Pod metadata: name: mypod labels: name: mypod spec: containers: —name: mypod image: nginx
When you apply this pod specification, the following will happen:
- If you did not create any namespaces in your cluster, the pod will be created in the default namespace
- If you created a namespace and are currently running in it, the pod will be created in that namespace.
How can you explicitly create a resource in a specific namespace?
There are two ways to do this:
- Use the –namespace flag when creating the resource, like this:
kubectl apply -f pod.yaml --namespace=mynamespace
- Specify a namespace in the YAML specification of the resource. Here is what it looks like in a pod specification:
apiVersion: v1 kind: Pod metadata: name: mypod namespace: mynamespace labels: name: mypod ...
- Note that if your YAML specification specifies one namespace, but the apply command specifies another namespace, the command will fail.
- If you try to work with a Kubernetes resource in a different namespace, kubectl will not find the resource. Us the –namespace flag to work with resources in other namespaces, like this:
kubectl get pods --namespace=mynamespace