Kubernetes Core Concepts - Namespaces

Kubernetes Core Concepts - Namespaces

What are Kubernetes Namespaces?

As per official documentation Kubernetes supports multiple virtual clusters backed by the same physical cluster. These virtual clusters are called namespaces.

In a simpler way Kubernetes namespaces helps an organization working on/with different projects, teams, or customers to share a common Kubernetes infrastructure.

Why do you need namespaces?

When we have a large set of Kubernetes resources running on our cluster Kubernetes namespaces helps in organizing them and allows you to group them together based on the nature of the project. By doing so you have more control over them and can effectively manage them by using unit filters.

For example you can have separate namespaces created for different application life cycle environments such as development, staging, production etc. for a project or an application.

Kube-namespaces.png

Names of all the kubernetes resources are required to be unique within a namespace, but not across namespaces. And this feature of having same resource object names across namespaces comes handy in application life cycle environments we discussed above.

Nesting of Namespaces isn't allowed as all the Kubernetes resources can only be in one namespace.

default Namespace in Kubernetes

By design, when you provision a Kubernetes cluster it will start with a default namespace to hold the default set of Pods, Services, and Deployments used by the cluster. The objects part of this namespace will be part of no other namespaces.

List all Namespaces part of a Kubernetes cluster->

root@kube-master:~# kubectl get namespaces

kubectl_get_ns.png

Apart from default you can see three more namespaces created above. Let's understand what are they.

namespaces.png

Learn more about default Namespace

kubectl describe command can be used to display the labels and annotations associated with a namespace, as well as any quotas or resource limits that have been applied on it.

root@kube-master:~# kubectl describe namespaces default

decsribe_default.png

Create a new Namespace

Like any other Kubernetes object Namespaces also can be created in two ways.

  • Using command line tool kubectl
  • Using yaml manifest file

In order to create a new namespace from the command line terminal, use the command kubectl create namespace by supplying the namespace name you want to create as an argument to the command.

root@kube-master:~# kubectl create namespace lco-namespace-demo
namespace/lco-namespace-demo created

List the Namespace created->

root@kube-master:~# kubectl get namespaces

kubectl_get_ns-1.png

Describe the Namespace->

root@kube-master:~# kubectl describe namespaces lco-namespace-demo

decsribe_ns.png

Create Namespace using a yaml manifest file->

Like any other Kubernetes resource Namespaces also can be created by applying a manifest file.

root@kube-master:~# cat lco-namespace-demo.yml
apiVersion: v1
kind: Namespace
metadata:
  name: lco-demo-namespace

Apply the file and create the Namespace->

root@kube-master:~# kubectl apply -f lco-namespace-demo.yml
namespace/lco-demo-namespace created

List the Namespace created->

root@kube-master:~# kubectl get namespaces

kubectl_get_ns-2.png

Launch kubernetes objects in newly created Namespace

Now we have a Namespaces created named lco-demo-namespace. Let's launch a pod in that Namespace using following command. You need to specify the namespace name where you want to launch the object.

root@kube-master:~# kubectl run namespace-demo-nginx --image=nginx --namespace=lco-namespace-demo
pod/namespace-demo-nginx created

List the Pod created within that Namespace->

root@kube-master:~# kubectl get pods --namespace=lco-namespace-demo
NAME                   READY   STATUS    RESTARTS   AGE
namespace-demo-nginx   1/1     Running   0          17s

You need to specify a filter (--namespace=lco-namespace-demo) to view the newly created object.

By default a kubernetes object will be added to the default namespace in case we don't specify explicitly while creating it.

Changing default Namespace by setting the context

When you are working on a project you want to avoid providing the same namespace for each of your commands while creating or modifying objects. This can be done by changing the default namespace.

To achieve this we need to change the context settings.

What is Context in Kubernetes?

A context is a group of access parameters. Each context contains a Kubernetes cluster, a user, and a namespace. The current context is the cluster that is currently the default for kubectl. All kubectl commands run against that cluster.

To list your current context configuration details, type:

root@kube-master:~# kubectl config get-contexts
CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
*         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin

This clearly indicates that we have a context called Default which is in use. No namespace is specified by the context, so the default namespace applies.

Change the namespace used by that context->

root@kube-master:~# kubectl config set-context $(kubectl config current-context) --namespace=lco-namespace-demo
Context "kubernetes-admin@kubernetes" modified.

Now list your current context configuration details:

root@kube-master:~# kubectl config get-contexts
CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
*         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin   lco-namespace-demo

Now you no need to specify the namespace parameter each time when you create or modify any Kubernetes object within your namespace (lco-namespace-demo).

Let's try it out by creating another pod.

root@kube-master:~# kubectl run namespace-context-demo-nginx --image=nginx
pod/namespace-context-demo-nginx created

Verify the Pod existence:

root@kube-master:~# kubectl get pods
NAME                           READY   STATUS    RESTARTS   AGE
namespace-context-demo-nginx   1/1     Running   0          13s
namespace-demo-nginx           1/1     Running   0          3m13s

Notice that we haven't specified any --nampespace filter here. It by default shows the objects part of namespace lco-namespace-demo

Validate that our kubectl describe command now uses lco-namespace-demo by default.

root@kube-master:~# kubectl describe pod namespace-context-demo-nginx | grep Namespace
Namespace:    lco-namespace-demo

Switching between Kubernetes namespaces

Just run the same command we used above to switch between different Kubernetes Namespaces.

root@kube-master:~# kubectl config set-context $(kubectl config current-context) --namespace=lco-demo-namespace
Context "kubernetes-admin@kubernetes" modified.

Here we have switched to a different namespace called lco-demo-namespace.

Verify it:

root@kube-master:~# kubectl config get-contexts
CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
*         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin   lco-demo-namespace

Another methods to verify the changes;

root@kube-master:~# kubectl get sa default -o jsonpath='{.metadata.namespace}'

lco-demo-namespace
root@kube-master:~# kubectl config view | grep namespace
    namespace: lco-demo-namespace

Whenever we make any changes to our Kubernetes cluster using kubectl commands all those changes eventually gets configured into kube config file.

root@kube-master:~# cat ~/.kube/config
...
...
contexts:
- context:
    cluster: kubernetes
    namespace: lco-demo-namespace
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
...
...

Rename the Namespace

Not recommended. It shouldn't be done as its not a standard practice to rename a Kubernetes namespace.

Deleting a Namespace

Once you are done with your work and feel that you no longer require a namespace, delete it.

But be cautious here! Because deleting a namespace not only deletes the namespace, but it deletes all the resources deployed within as well. So this is quite dangerous if you are not careful.

The best practice is always list the resources associated with a namespace before deleting to verify the objects that will be removed:

root@kube-master:~# kubectl get all --namespace=lco-namespace-demo
NAME                               READY   STATUS    RESTARTS   AGE
pod/namespace-context-demo-nginx   1/1     Running   0          4m11s
pod/namespace-demo-nginx           1/1     Running   0          7m11s

Now if you are sure and comfortable with the deletion scope go ahead and delete it by running following command:

root@kube-master:~# kubectl delete namespaces lco-namespace-demo
namespace "lco-namespace-demo" deleted

All the resources should be deleted as well:

root@kube-master:~# kubectl get all --namespace=lco-namespace-demo
No resources found in lco-namespace-demo namespace.

Verify the Namespace existence:

root@kube-master:~# kubectl get namespaces

kubectl_get_ns-3.png

Namespace lco-namespace-demo doesn't exist anymore.

Conclusion

In this article, we have learnt about the concept of Kubernetes Namespaces, their use cases in organizing cluster resources and different operations which can be performed with and within the Kubernetes Namespaces.

This is all about Kubernetes Namespaces.

Hope you like the tutorial. Stay tuned and don't forget to provide your feedback in the response section.

Happy Learning!

Did you find this article valuable?

Support Learn Code Online by becoming a sponsor. Any amount is appreciated!