Complete guide to understand Kubernetes Namespace

Kubernetes namespace allows you logically organise your resources into group. You can think of namespace as virtual cluster. Kubernetes namespace created virtual clusters inside the physical cluster. You can have multiple namespaces inside a single Kubernetes cluster, and they are all logically isolated from each other. They can help you and your teams with organization, security, and even performance!

Before going through this post, if you are not familiar with how we can deploy complete end to end application on Kubernetes cluster, i would highly recommend to go through this post first :

By default 4 nampesapces are being created in Kubernetes cluster.

  1. default
  2. kube-node-lease
  3. kube-public
  4. kube-system

Kube-System : Ideally you should not touch or change anything in Kube-system namespace. Kube-system namespace is for Kubernetes , as it contain the different system processes and kubectl processes etc.

Kube-public : Kube-public contains the publicly accessed data, it has configMap which contains information about your cluster. Kube-public data can be accessed without authentication.

Kube-node-lease : Kube-node-lease contains the information about the different nodes heartbeat to verify the availability of any node.

Default : default namespace is the namespace where your resources are created in the beginning if you do not specify any namespace while creating your cluster.

Creating Namespaces

You can create the namespace with the following command, Let’s i want to create a namespace with name as “ishant-namespace”.

kubectl create namespace ishant-namespace

Or you can create a YAML file and apply it just like any other Kubernetes resource.

ishant-namespace.yaml

kind: Namespace
apiVersion: v1
metadata:
  name: test
  labels:
    name: test

To create the namesapce using the above file, you will have to execute the below command :

kubectl apply -f ishant-namespace.yaml

Viewing Namespaces

You can see all the Namespaces with the following command:

kubectl get namespace

You can see the four built-in Namespaces, as well as the new Namespace called ‘ishant-namespace.’

💡 Note : Kubernetes-dasboard namespace only comes with minikube, you will not find it in other Kubernetes cluster.

Deleting a Namespace

Delete a namespace with

kubectl delete namespaces <insert-some-namespace-name>

Why do we need Namesapce ?

A single cluster should be able to satisfy the needs of multiple users or groups of users (henceforth a ‘user community’). Kubernetes namespaces help different projects, teams, or customers to share a Kubernetes cluster. It does this by providing the following:

  1. A scope for Names.
  2. A mechanism to attach authorization and policy to a subsection of the cluster.

Generally each user community(Team) has its own:

  1. resources (pods, services, replication controllers, etc.)
  2. policies (who can or cannot perform actions in their community)
  3. constraints (this community is allowed this much quota, etc.)

A cluster operator may create a Namespace for each unique user community. Namespace provides a unique scope for:

  1. named resources (to avoid basic naming collisions)
  2. delegated management authority to trusted users
  3. ability to limit community resource consumption

Let’s discuss different scenarios in which you might need to create namespace in your application :

Scenario 1 : Need to logically breakdown the application in one cluster

Let’s you have created an application and you are deploying on the Kubernetes cluster. You have created all the resources like database, services, service-pods, secrets, configMaps in the default namespace only and multiple users are working on the same namespace.

If you have all your resources in default namespace, Sooner it will become very difficult to manage all the different versions of the different components. It is better to logically group the resource into different namespace.

We can logically group different component into different namespace as database contain all the resources related to databases, monitoring will contain all the resources like prometheus etc, application-service will contain the different services etc.

Scenario 2 : Different Environment on one clsuter

Another scenario would be like that you want to create different environment for your application, one is the development env and another environment. Different services might have different version in different environment , as generally we do rapid development in dev environment whereas there is more stable code in staging. So we can keep our services into two different namespace as dev and staging and share the common resources like nginx-ingress and other logging resources in both the namespace as depicted in image below:

Scenario 3 : Delegate authority to partitions of the cluster to trusted users in those communities.

Cluster admin can limit the authority of the Team A user only to access the Team-A-namespace and Team-B user to Team-B-namespace only.

Scenario 4 : Limit Resources per User Team.

Cluster Admin can limit the amount of resources each community can consume in order to limit the impact to other communities using the cluster.

There are many other scenarios where it make more sense to create different namespace and logically group the resources but i think above scenarios are enough to get convinced that we would require namespace in Kubernetes cluster.

As we have understood the basic of namespace and are clear with why do we need namespace, let’s learn how to manage resources in a namespace and how to work with multiple namespace.

Creating Resources in the Namespace

Let’s create a simple nginx-pod in “ishant-namesapce”.

pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: mypod
  labels:
    name: mypod
spec:
  containers:
  - name: mypod
    image: nginx

Run the below command and also specify the namespace in which you want to create this resource :

kubectl apply -f pod.yaml --namespace=ishant-namespace

Once you have run the above command you will have resource created in the namespace = ishant-namespace.

You can also specify a Namespace in the YAML declaration.

pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: mypod
  namespace: ishant-namespace
  labels:
    name: mypod
spec:
  containers:
  - name: mypod
    image: nginx

Then you can apply the command without specifying the namespace.

kubectl apply -f pod.yaml

Viewing resources in the Namespace

If you try to find your Pod, you might notice you it does not give any result, can you think of why it is so ?

$ kubectl get pods
No resources found.

This is because all commands are run against the currently active Namespace. If you are working in the same way as mentioned in this blog, your current namesapce is “default” namespace beacuse you never changes your namespace.

To find your Pod, you need to use the “namespace” flag.

kubectl get pods --namespace=ishant-namespace

Managing your active Namespace

Out of the box, your active namespace is the “default” namespace. Unless you specify a Namespace in the YAML, all Kubernetes commands will use the active Namespace.

To change the active namespace you can use below command to manage current namespace.

kubectl config set-context --current --namespace=ishant-namespace

💡 Note : Once you run the above command, you permanently save the namespace for all subsequent kubectl commands in that context.

There are also other add on which you can use if you are not able to remember the above command :  kubectx & kubens

Cross Namespace communication

Namespaces are “hidden” from each other, but they are not fully isolated by default. A service in one Namespace can talk to a service in another Namespace. This can often be very useful, for example to have your team’s service in your Namespace communicate with another team’s service in another Namespace.

When your app wants to access a Kubernetes sService, you can use the built-in DNS service discovery and just point your app at the Service’s name. However, you can create a service with the same name in multiple Namespaces! Thankfully, it’s easy to get around this by using the expanded form of the DNS address.

Services in Kubernetes expose their endpoint using a common DNS pattern. It looks like this:

<Service Aame>.<Namespace Name>.svc.cluster.local

Normally, you just need the Service’s name and DNS will automatically resolve to the full address. However, if you need to access a Service in another Namespace just use the Service name plus the Namespace name.

For example, if you want to connect to the “database” service in the “test” namespace, you can use the following address:

database.test

If you want to connect to the “database” service in the “production” namespace, you can use the following address:

database.production

Conclusion :

In this post, we learned about the namespace, we understood what is namespace, why do we need namespace. Different CRUD operation for namespace and we also saw how to set the active namespace as your current namespace. Yo can read further from Kubernetes documentation : https://kubernetes.io/docs/tasks/administer-cluster/namespaces/#deleting-a-namespace

This is all from this post, if you find anything incorrect or have different thoughts, please leave a comment in the comment box below.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s