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.
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.
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.
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, 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.
Kubernetes cluster, 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.
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:
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
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
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
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” 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.
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.
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 is a full-stack developer and data scientist who loves to make the cold and hard topics exciting and easy to understand.