Kubernetes Namespace: The What, Why, and How
Tags: kubernetes, vcluster, devspace, loft
Published: 2022-09-14 16:55:26

By Talha Khalid

Unlike Docker, Kubernetes supports multiple virtual sub-clusters called namespaces that are backed by the same physical cluster.

In this post, we'll explore what Kubernetes namespaces are, why you need them, and how to create them.

![alt_text](https://loft.sh/blog/images/content/namespace.png "image_tooltip")

## What Is Kubernetes Namespace?

A namespace provides scope for Kubernetes resource names. It's useful when many users across multiple teams or projects use the same cluster and there's a risk of name collisions.

A namespace is a method that Kubernetes offers us to help isolate our resources logically. 

Namespace not only divides resources, but it's also useful for security purposes. It allows you to provide role-based access to different users, which also translates into better performance.

Kubernetes namespace does its job by providing the user with several tools. These can include a scope for names and a way to allow authorizations and policies attached to a particular subsection of a system cluster.

## When Do You Need Multiple Namespaces?

The Kubernetes namespace option has many characteristics, including its ability to divide a set of specific cluster resources among various users, as well as its contribution to the processes that allow clusters to be shared among different clients, teams, and projects.

So, if the user needs to separate some resources that differ only slightly, he doesn't need to use more than one Kubernetes namespace. Instead, he can use the tags the platform offers.

However, if you have multiple teams, such as production and test, it's better to avoid clutter and use the option to create multiple namespaces. 

<p id="gdcalert2" ><span style="color: red; font-weight: bold">>>>>>  gd2md-html alert: inline image link here (to images/image2.png). Store image on your image server and adjust path/filename/extension if necessary. </span><br>(<a href="#">Back to top</a>)(<a href="#gdcalert3">Next alert</a>)<br><span style="color: red; font-weight: bold">>>>>> </span></p>

![alt_text](https://loft.sh/blog/images/content/namespacejob.png "image_tooltip")

## How Does Kubernetes Namespace Work?

Kubernetes namespace does its job by providing the user with many tools, such as a scope for names and a way to allow authorizations and policies to be attached to a particular subsection of a system cluster.

It should also be noted that most of the Kubernetes objects and resources are located in some namespaces, such as pods, replication controllers managed by[ kube-controller-manager](https://kubernetes.io/docs/reference/command-line-tools-reference/kube-controller-manager/), and so on. However, some elements are responsible for representing these Kubernetes namespaces so they're not inside them. Likewise, you can't find low-level resources, such as persistent volumes or nodes, within the platform’s namespaces.

## Default Kubernetes Namespaces

[Kubernetes cluster](https://loft.sh/blog/vcluster-for-local-development/), by default, already has three namespaces. To verify this, you can list your cluster's current namespaces by using the following command:

```
kubectl get namespace
```

Here's the result:

```
NAME              STATUS   AGE

default           Active   25d

kube-public       Active   25d

kube-system       Active   25d
```

* **default**—This is the default Kubernetes namespace the system sets. It's intended for objects that don't indicate or specify any of the namespaces.
* **kube-system**—You can assign this namespace to resources created by the Kubernetes platform itself.
* **kube-public**—This is the Kubernetes namespace that the system automatically creates and is visible to all users—even those who aren't authenticated. Usually, this namespace focuses on the internal use of the platform cluster in situations where some of the resources need to be publicly visible and readable for the entire cluster.

## Creating a Namespace in Kubernetes

Before creating a namespace, it's important to keep in mind the naming conventions for creating a namespace:

* The name can include alphanumeric characters.
* The name can also include hyphens; however, you can’t use them initially.
* The name cannot include special characters. 
* Resource names must be unique within a namespace but not between different namespaces.
* Namespaces cannot be nested, and each Kubernetes resource can only be in one namespace.

There are two ways to create our namespace: using a template in YAML format or without. To create a namespace, you need to create a `.yml` file like the one below:

```
apiVersion: v1

kind: Namespace

metadata:

  name: production

kubectl -f file.yml
```

Or, you can also run the **kubectl create namespace** command to create a namespace:

```
kubectl create namespace production
```

When Kubernetes creates a service, it'll create a DNS entry within your cluster, and this DNS entry has the following name—_service-name.namespace-name.svc.cluster.local—_which your application can use to connect to your service.

You can create a pod within a given namespace by running the following:

```
kubectl --namespace=production run nginx --image=nginx
```

Finally, you can use the following command to check on the specified namespaces' creation:

```
kubectl get namespace
```

## Setting a Default Namespace

A context determines the cluster and the user. You can indicate in a certain context a namespace in such a way that when we use said context, it also uses the indicated namespace.

It won't be necessary to indicate it with the option **\-n**. For this, it's necessary to determine the context in which you're working.

```
kubectl config current-context

kubernetes-admin@kubernetes
```

Then, you can modify the context by adding the namespace you want to use by default.

```
kubectl config set-context kubernetes-admin@kubernetes --namespace=production

Context "kubernetes-admin@kubernetes" modified
```

## Limitation of Resources or Objects

When using a shared environment, there's always a concern with resource issues. Within it, Kubernetes can solve this using “resource quota,” which provides a resource limitation per namespace. This limitation can range from hardware to the number of objects created by type within the namespace.

When Kubernetes checks if it's possible to create a “pod, service,[ replication controller](https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#:~:text=A%20ReplicationController%20manages%20all%20the,without%20affecting%20the%20running%20pods.)” inside the namespace, it checks if there are any resource limitations. If it exists, Kubernetes already notifies the user that creating the desired component is impossible. An example resource policy that you can create is as follows:

* Namespace test has 20 GB of memory and 20 cores
* Namespace production has 40 GB of memory and 20 cores

However, if your environment has 50 GB of memory, Kubernetes will allocate CPU memory to the component that makes the request first, thus having no way to prioritize a given namespace. In addition to making CPU and memory limitations, it's also possible to perform disk and object limitations.

You can see an example of creating a “resource quota” below.

```
apiVersion: v1

kind: ResourceQuota

metadata:

  name: limited-resources

spec:
  hard:
    pods: "10"
    limits.cpu: "10"
    limits.memory: 20Gi
```

![alt_text](https://loft.sh/blog/images/content/tasks.jpg "image_tooltip")

## **Kubernetes Namespace Best Practices**

Now that we've looked at what namespaces are and how to use them, let's look at some best practices that you can follow.

* **Adopt a structure according to your workflow.** Most people have to face the dilemma of choosing between namespacing around logical grouping or a deployment environment. It is best practice to choose the structure according to your requirements in such situations. If you have small teams, namespace per environment performs better; however, logical grouping becomes a more efficient option when you want to scale and have multiple teams.
* **Use resource quotas.** When you have multiple teams working on different microservices and there are shared clusters, one single team can begin utilizing more resources. To avoid this, you could use resource quotas to limit the amount of resource utilization at a namespace level.
* **Don't shy away from creating namespaces.** Usually, most people suggest avoiding creating too many namespaces, as it makes it difficult to share secrets and *configmaps* between namespaces. However, it's not an iron law, and it depends on your workflow. You can create namespaces to separate microservices and their dependencies to make things more secure. If you want to scale, you can also have namespaces per environment and use labels to group microservices together.

## Conclusion

Namespaces in Kubernetes are an excellent way to manage your clusters. This is especially true when you have different teams working on a project.

In addition, the ResourceQuota object combined with namespaces allows you to further optimize the resource usage of your Kubernetes objects, thus increasing performance.

*This post was written by Talha Khalid. [Talha](http://medium.com/@talhakhalid101) is a full-stack developer and data scientist who loves to make the cold and hard topics exciting and easy to understand.*