The Kubernetes Series - Namespaces

(Photo by Free To Use Sounds on Unsplash)

Namespaces is a way for you to isolate different objects, resources and instances in your cluster in a way that they can't interfere with each other. You can set up namespaces to contain different environments on the same cluster, like dev and production, without worrying that one would be able to affect the other.

In other words, namespaces are like the borders for different countries that might exist in the universe of your cluster.

When you create your cluster it creates there are three namespaces by default;

  • kube-system
  • kube-public
  • default

Kube-system is used by Kubernetes to internally manage its services and processes, such and networking and DNS, so you don't have to worry or have access to that.

Kube-public contains shared resources available to all users(even unauthenticated) and environments in your cluster. By default the only thing in here is cluster-info. It is created when you start a cluster with the kubeadm utility.

You will start off with the default namespace as your initial playground. From there you can create your own namespaces and define their own rules, keys, secrets, resource limits, ect.

Creating a namespace

You can create a namespace with a YAML file like so

apiVersion: v1
kind: Namespace
metadata:
  name: dev

Or with command line;

kubectl create namespace dev

Now we can set some namespace configs. Let's put a limit on the resources available.

apiVersion: v1
kind: ResourceQuota
metadata:
  name: dev-quota
  namespace: dev
spec:
  hard:
    pods:"6"
    cpu:"1000"
    requests.cpu:"100"
    requests.memory:100Gi
    limits.memory:200Gi
    

This YAML file will limit the resources in the dev namespace to 6 pods, 1000 cpu units and limiting requests specifically to 100 CPU units. Requests will also not be allowed to exceed  100 gigabytes of memory usage, while the environment as a while is provisioned 200 gigabytes of memory. Nice!

Read more about ResourceQuotas here.

Calling entities in different namespaces

When you refer to entities in your current namespace, you just refer to them by name only(which you defined in their YAML file, for instance). But what if you want to call a service or pod or whatever in another namespace?

Different entities in different namespaces can contact each other if you want them to, you would just append the namespace of the resource you want to access to the name you're calling. Kubernetes automatically handles references to names and namespaces with its internal DNS system.

Let's look at an example. Say you have a front-end running in the default namespace and you have an api called web-api in a namespace called dev. You would refer to the api from your front-end as web-api.dev.svc.cluster.local

Let's break down that URI;

  • cluster.local –> This is the default domain name for your cluster.
  • svc –> This tells the DNS that you're referring to a service on the cluster.
  • dev –> This is the name of the namespace the service resides on
  • web-api –> This is the hostname of the service, defined in the YAML file as name, or hostname(which gets preference).

When using command-line tools like kubectl, you can refer to entities in namespaces other than your active one(the one in your cluster context) with the parameter;

--namespace=namespace-name-here

You can also define the namespace for an object to create in its metadata section in your YAML file, with the property namespace. See the ResourceQuota above as an example.

Switching active namespaces

If you want to run kubectl commands without having to have to append --namespace option every time, you can switch your active namespace with the following;

kubectl config set-context docker-desktop --namespace=dev

The command above sets the default namespace as dev in the config for the context on your docker-desktop cluster.

Thus, when you set your active cluster for kubectl as the docker-desktop one;

kubectl config use-context docker-desktop

And then run

kubectl get pods

You will get the pods in the dev namespace on the cluster docker-desktop.

Or, to just view objects(in this case pods) in all namespaces on the cluster, run;

kubectl get pods --all-namespaces

Conclusion

We now have a better understanding of namespaces and how to keep things organised in your clusters. Next up, Services.