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.