Kubernetes Namespaces
Updated Jim Bugwadia
Kubernetes namespaces are objects that partition a single Kubernetes cluster into multiple virtual clusters. Each namespace gives the names it contains their own scope, so the same object name can be used in different namespaces. Namespaces let several users, teams or applications share one cluster, with separate resource quotas and RBAC permissions for each.

Content contributed by CloudYuga; Photo by rawpixel on Unsplash
What is a Kubernetes namespace?
Each Kubernetes namespace provides the scope for the Kubernetes Names it contains. Combine an object’s name with its namespace and every object gets a unique identity across the cluster.
A new Kubernetes cluster is created with three namespaces:
| Namespace | What it holds |
|---|---|
default |
All resources created in the cluster land here unless you name another namespace. Until someone sets a resource quota for it, the default namespace lets applications run with unbounded CPU and memory requests and limits. |
kube-public |
Resources that are publicly readable by all users. This namespace is generally reserved for cluster usage. |
kube-system |
Objects created by the Kubernetes system and control plane. |
To follow the demo below you need basic experience with a Linux/Unix system, some familiarity with Kubernetes, and a Kubernetes cluster to run the commands against.
How do you create a Kubernetes namespace?
Start by listing the namespaces present in the cluster.
$ kubectl get namespaces
NAME STATUS AGE
default Active 5m
kube-public Active 5m
kube-system Active 5m
There are two ways to create a namespace: the kubectl create namespace command, or a configuration file.
- Create a new Kubernetes namespace
my-namespacewith the command.
$ kubectl create ns my-namespace namespace/my-namespace created
- List the Kubernetes namespaces again.
$ kubectl get namespace
NAME STATUS AGE
default Active 8m
kube-public Active 8m
kube-system Active 8m
my-namespace Active 3s
To create a Kubernetes namespace from a configuration file instead, write the manifest:
apiVersion: v1
kind: Namespace
metadata:
name: test-ns
- Deploy the file.
$ kubectl apply -f namespace.yaml
namespace/test-ns created
- List the namespaces.
$ kubectl get namespace
NAME STATUS AGE
default Active 18m
kube-public Active 18m
kube-system Active 18m
my-namespace Active 9m
test-ns Active 2m
What are Kubernetes namespaces used for?
Namespaces have several use cases. These are the main reasons to use them, each covered in its own section below:
| Use case | What the namespace gives you | Kubernetes feature |
|---|---|---|
| Partition cluster resources | A logical slice of one cluster per user, team or application | namespace field, kubectl config set-context |
| Resource consumption policies | Limits on compute and object counts per namespace | Resource Quotas |
| Policies to run resources | Access permissions scoped to one namespace | Role-based access control (RBAC) |
| A unique scope for names | The same short name can exist in different namespaces | Kubernetes Names |
Partition cluster resources
Namespaces divide a cluster into logical partitions, so one large Kubernetes cluster can serve multiple users and teams, or a single user with multiple applications. Each user, team or application in a namespace is isolated from those in other namespaces and operates as if it were the sole user of the cluster. Note that namespaces do not provide network segmentation.
Deploy an application in a specific Kubernetes namespace.
Here is how to create a Kubernetes object inside a specific namespace.
- List the namespaces.
$ kubectl get namespace
NAME STATUS AGE
default Active 18m
kube-public Active 18m
kube-system Active 18m
my-namespace Active 9m
test-ns Active 2m
- Create a pod from the following configuration.
apiVersion: v1
kind: Pod
metadata:
name: mypod
namespace: my-namespace
labels:
app: mypod
spec:
containers:
- name: mypod
image: nginx:alpine
The field namespace: my-namespace sets the Kubernetes namespace, so this pod will be created inside my-namespace.
- Deploy a pod with the configuration above.
$ kubectl apply -f mypopd.yaml
pod/mypod created
- List the pods in the
my-namespacenamespace.
$ kubectl get pod -n my-namespace
NAME READY STATUS RESTARTS AGE
mypod 1/1 Running 0 16s
Bind a user to a specific namespace
Setting a context binds a user to a specific Kubernetes namespace, which then becomes that user’s default namespace. You can do this by editing the kubeconfig file or with the commands below.
- Create a Kubernetes namespace for each team:
dev,qaandproduction.
$ kubectl create ns dev # Namespace for Developer team
$ kubectl create ns qa # Namespace for QA team
$ kubectl create ns production # Namespace for Production team
- Set the context for each user group.
# Bind dev context to dev namespace
$ kubectl config set-context dev --namespace=dev --cluster=kubernetes --user=dev
# Bind qa context to QA namespace
kubectl config set-context qa --namespace=qa --cluster=kubernetes --user=qa
# Bind production context to production namespace
kubectl config set-context production --namespace=prod --cluster=kubernetes --user=production
This binds the Dev team to the dev namespace, the QA team to the qa namespace and the Production team to the production namespace. Each of these namespaces acts as the default namespace for the team assigned to it, so team members don’t have to pass -n on every command. For details on Kubernetes contexts and kubeconfig, see the documentation at kubernetes.io.
Set resource consumption policies with a ResourceQuota
Resource Quotas applied to a namespace limit how much of the cluster a particular set of users can consume. A resource quota limits resource consumption per Kubernetes namespace. It can cap the number of objects of each type created in the namespace, and the total compute resources that its resources may consume.
Here is how to configure a resource quota for a specific namespace.
- Create a new
demonamespace.
$ kubectl create namespace demo
namespace/demo created
- Create a resource quota object for the
demonamespace.
apiVersion: v1
kind: ResourceQuota
metadata:
name: mem-cpu
namespace: demo
spec:
hard:
requests.cpu: "0.5"
requests.memory: 512Mi
limits.cpu: "1"
limits.memory: 1Gi
In the demo namespace, workloads cannot request more than 0.5 CPU and 512Mi RAM overall. If a pod with a 256Mi request is already running, a new pod that needs more than the remaining 256Mi of memory will not be scheduled. The quota also sets a hard limit of 1 CPU and 1GB RAM for the namespace.
- Deploy the resource quota object.
$ kubectl apply -f qouta.yaml
resourcequota/mem-cpu created
- Get detailed information about the resource quota you created.
$ kubectl get resourcequota mem-cpu --namespace=demo --output=yaml
apiVersion: v1
kind: ResourceQuota
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"ResourceQuota","metadata": {"annotations":{},"name":"mem-cpu","namespace":"demo"},"spec":{"hard":{"limits.cpu":"1","limits.memory":"1Gi","requests.cpu":"0.5","requests.memory":"512Mi"}}}
creationTimestamp: 2018-11-21T07:05:48Z
name: mem-cpu
namespace: demo
resourceVersion: "6091"
selfLink: /api/v1/namespaces/demo/resourcequotas/mem-cpu
uid: dfd1002c-ed5b-11e8-ab3b-507b9d3bd0b6
spec:
hard:
limits.cpu: "1"
limits.memory: 1Gi
requests.cpu: 500m
requests.memory: 512Mi
status:
hard:
limits.cpu: "1"
limits.memory: 1Gi
requests.cpu: 500m
requests.memory: 512Mi
used:
limits.cpu: "0"
limits.memory: "0"
requests.cpu: "0"
requests.memory: "0"
The output shows the hard limits and the resources used so far in the namespace.
What happens when a pod exceeds the quota?
First, deploy a Demo1 application whose resource request fits within the quota set for the namespace.
apiVersion: v1
kind: Pod
metadata:
namespace: demo
name: pod-demo1
labels:
app: demo1
spec:
containers:
- name: demo1
image: nginx:alpine
ports:
- containerPort: 80
resources:
limits:
memory: "400Mi"
cpu: "0.3"
requests:
memory: "300Mi"
cpu: "0.2"
- Deploy the demo1 application.
$ kubectl apply -f demo1.yaml
pod/pod-demo1 created
Its resource request was within the quota’s specification, so the pod was deployed.
- Now create another pod in the
demonamespace whose resource request exceeds the quota, and see what happens.
apiVersion: v1
kind: Pod
metadata:
namespace: demo
name: demo-pod2
labels:
app: demo
spec:
containers:
- name: demo
image: nginx:alpine
ports:
- containerPort: 80
resources:
limits:
memory: "700Mi"
cpu: "0.6"
requests:
memory: "600Mi"
cpu: "0.6"
- Try to deploy the demo2 application.
$ kubectl apply -f demo2.yaml
Error from server (Forbidden): error when creating "demo2.yaml": pods "demo-pod2" is forbidden: exceeded quota: mem-cpu, requested: limits.memory=700Mi,requests.cpu=600m,requests.memory=600Mi, used: limits.memory=400Mi,requests.cpu=200m,requests.memory=300Mi, limited: limits.memory=1Gi,requests.cpu=500m,requests.memory=512Mi
The error occurs because this pod requests more resources than the resource quota allows.
- Delete the
demonamespace. This deletes the namespace along with all the objects running inside it.
$ kubectl delete namespace demo
namespace "demo" deleted
- Delete the Kubernetes namespaces created earlier.
$ kubectl delete namespace my-namespace test-ns
namespace "my-namespace" deleted
namespace "test-ns" deleted
Access policies and a unique scope for names
With Role-based access control (RBAC), you can control access permissions within a particular Kubernetes namespace. A cluster admin grants permissions to a user or group of users in specific namespaces with a Role Binding.
Namespaces also provide the scope for Kubernetes Names. Inside a namespace, an object can be referred to by a short name like my-app, and the namespace adds further scope to identify it, e.g. my-app.my-namespace. The name of an object must be unique within its namespace, and the combination of name and namespace (e.g. my-app.my-namespace) must be unique at the cluster level.
Summary
Namespaces are how you divide and manage a Kubernetes cluster. They let you logically separate users, teams or applications and assign resources to each. They provide the basic building blocks for resource allowances, access control and isolation. And because one cluster can now run a diverse set of workloads, namespaces help you use cluster resources more efficiently.
Next steps: to apply policies to namespaces as code, see Kyverno and our guide to policy as code. For more Kubernetes basics, read Kubernetes for Developers Part 2: Replica Sets and Deployments.
References
- Kubernetes Namespaces : https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
- Kubernetes Names : https://kubernetes.io/docs/concepts/overview/working-with-objects/names/
- Role-based access control (RBAC) : https://kubernetes.io/docs/reference/access-authn-authz/rbac/
- Resource Quotas : https://kubernetes.io/docs/concepts/policy/resource-quotas/)
- Kubeconfig : https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/
This blog post was contributed by our training partner CloudYuga.
For expert training in Kubernetes, including Kubernetes namespaces, check out their website at https://cloudyuga.guru/.Discover all that Nirmata’s DevSecOps platform for Kubernetes has to offer by visiting this page.
Frequently asked questions
Do Kubernetes namespaces isolate network traffic?
No. Namespaces scope names, quotas and RBAC permissions, but by default a pod in one namespace can still reach pods in other namespaces over the network. To restrict traffic between namespaces, apply NetworkPolicy resources, which need a network plugin that supports them. Treat a namespace as an administrative boundary, not a security boundary on its own.
Are all Kubernetes objects namespaced?
No. Pods, Services, Deployments and ResourceQuotas live in a namespace, but some resources are cluster-scoped: Nodes, PersistentVolumes, StorageClasses and Namespace objects themselves. Run kubectl api-resources --namespaced=true to list the namespaced kinds, or --namespaced=false to list the cluster-scoped ones. Cluster-scoped objects need names that are unique across the whole cluster.
How do I reach a Service in another namespace?
Use its DNS name. When you create a Service, Kubernetes creates a DNS entry of the form <service-name>.<namespace-name>.svc.cluster.local. A pod that looks up only <service-name> resolves it inside its own namespace, so to call a Service in a different namespace, use at least <service-name>.<namespace-name> or the fully qualified name.
Why does my cluster have a kube-node-lease namespace?
Newer Kubernetes versions create a fourth initial namespace, kube-node-lease, next to default, kube-public and kube-system. It holds one Lease object per node. The kubelet updates its Lease as a heartbeat, which lets the control plane detect node failures without the cost of frequent full Node status updates. You normally don't create anything in it yourself.