Kubernetes best practices. Kubernetes Namespace Organization
As you begin to create more and more Kubernetes services, easy-to-get-started tasks get more complicated. For example, development teams cannot create services or deployments under the same name. If you have thousands of hearths, a simple listing of them will take a lot of time, not to mention providing them with normal management. And this is just the tip of the iceberg.
Let’s take a look at how namespace namespace makes Kubernetes resource management easier. So what exactly is a namespace? Namespace can be thought of as a virtual cluster inside your Kubernetes cluster. You can have multiple namespaces isolated from each other within the same Kubernetes cluster. They can really help you and your teams with organization, security and even system performance.
On most Kubernetes distributions, the cluster is “out of the box” with a namespace called “default”. There are actually three namespaces that Kubernetes is dealing with: default, kube-system, and kube-public. Currently, Kube-public is not used very often.
Not touching the kube namespace is a good idea, especially on a managed system like the Google Kubernetes Engine. It uses the default namespace as the place where your services and applications are created. There is absolutely nothing special about it, except that Kubernetes is out of the box configured to use it, and you cannot remove it. This is great for getting started and systems with little performance, but I would not recommend using the default namespace in large prod systems. In the latter case, one development team can easily rewrite someone else’s code and disrupt the work of another team without even realizing it.
Therefore, you should create several namespaces and use them to segment your services into manageable links. A namespace can be created with a single command. If you want to create a namespace called test, then use the $ kubectl create namespace test command or simply create a YAML file and use it like any other Kubernetes resource.
You can view all namespaces using the $ kubectl get namespace command.
After its execution, you will see three built-in namespaces and a new namespace called “test”. Let’s look at a simple YAML file for creating pods. You may notice that there is no mention of a namespace in it.
If you use kubectl to run this file, it will create the mypod module in the current active namespace. This will be the default namespace until you change it. There are 2 ways to tell Kubernetes in which namespace you want to create your resource. The first way is to use the namespace flag when creating the resource.
The second way is to specify the namespace in the YAML declaration.
If you specify a namespace in YAML, then the resource will always be created in this space. If you try to use a different namespace when using the namespace flag, the command will fail. Now, if you try to find your pod, you can’t do it.
This is because all commands are executed outside the current active namespace. To find your pod, you need to use the namespace flag, but this is quickly boring, especially if you work as a developer in a group that uses its own namespace and does not want to use such a flag for each individual command. Let’s see how this can be fixed.
Out of the box, your active namespace is called default. If you do not specify the namespace in the YAML of the resource, then all Kubernetes commands will use this active default namespace. Unfortunately, an attempt to manage the active namespace using kubectl may fail. However, there is a very good tool called Kubens, which greatly simplifies this process. When you run the kubens command, you see all the namespaces with the highlighted active namespace.
To switch the active namespace to the test namespace, you simply run the $ kubens test command. If after this you enter the $ kubens command again, you can see that a new active namespace is now allocated – test.
This means that you do not need a namespace flag to see the pod in the test namespace.
Therefore, namespaces are hidden from each other, but not isolated from each other. A service from one namespace can quite easily communicate with a service in another namespace, which is often very useful. The ability to communicate between different namespaces means that the service of your developers can interact with the service of another dev-command in a different namespace.
Usually, when your application wants to access the Kubernetes service, you use the built-in DNS discovery service and just give your application the name of the service. However, you can create a service under the same name in several namespaces, which is invalid.
Fortunately, this is easily circumvented by using the expanded form of the DNS address. Services at Kubernetes expose their endpoints using a common DNS pattern. It looks something like this:
Typically, you just need a service name, and DNS will automatically determine the full address.
However, if you need to access the service in a different namespace, just use the service name plus the namespace name:
For example, if you want to connect to a service database in a test namespace, you can use the database address database.test
If you want to connect to the service database in the prod namespace, you use database.prod.
If you really want to isolate and restrict access to the namespace, Kubernetes allows you to do this using Kubernetes Network Policies. I will talk about this in the next series.
I am often asked how many namespaces need to be created and for what purposes? What is a managed piece of data?
If you create too many namespaces, they just get in your way. If there are too few of them, you will lose all the advantages of such a solution. I think that there are four main stages that each company goes through in the process of creating its own organizational structure. Depending on the stage of development at which your project or company is located, you can adopt the appropriate strategy for creating a namespace.
Imagine that you are part of a small team that works on the development of 5-10 microservices and you can easily assemble all the developers in one room. In this situation, it makes sense to run all prod services in the default namespace. Of course, for greater scope of action, you can use 2 namespaces – separately for prod and dev. And most likely, you are testing your development on a local computer using something like Minikube.
Suppose the conditions have changed and now you have a rapidly growing team that is simultaneously working on more than 10 microservices. There comes a time when you need to use multiple clusters or namespaces, separately for prod and dev. You can split a team into several subgroups so that each of them has its own microservices and each of these teams can choose its own namespace to facilitate the process of managing the development and release of software.
As each team member gets an idea of how the system as a whole works, coordinating each change with all other developers becomes more and more difficult. Trying to spin a full stack on your local computer is getting harder every day.
In large companies, developers do not know at all who exactly is working on what. Teams communicate using service contracts or use Service mesh technology, which adds an abstraction layer over the network, such as the Istio configuration tool. Attempting to run the entire stack locally is simply not possible. I highly recommend using a continuous delivery (CD) platform like Spinnaker on Kubernetes. So, the moment comes when each team definitely needs its own namespace. Each command can even select multiple namespaces for the dev environment and the prod environment.
Finally, there are large entrepreneurial companies in which one development group is not even aware of the existence of other groups. Such a company can generally hire third-party developers who interact with through well-documented APIs. In each such group there are several teams and several microservices. In this case, you must use all the tools that I mentioned earlier.
Programmers should not deploy services manually and should not have access to namespaces that do not concern them. At this stage, it is advisable to have several clusters to reduce the “explosion radius” of poorly configured applications, to simplify billing and resource management processes.
Thus, using your organization’s namespaces correctly makes Kubernetes more manageable, manageable, secure, and flexible.
To be continued very soon …