Part 4 - Namespaces in Kubernetes

Erhan Cetin
7 min readNov 19, 2020

Smooth Transition to Kubernetes

Please check the news-tracker-application on Github and Ephemeral Pods. Those will help to make this post understandable.

The Labels are being used to organize Kubernetes objects. Let’s take a closer look at our application pods with labels figure.

As you see in the figure above, we have multiple pods and can do any operation with label filtering, like :

$ kubectl delete pod -l env=develop  # delete all backend pods which have "env=develop" label.

Is that easy? Of course yes … But let’s imagine that developers in our team want to manage the pods which they create. For that, firstly, the developer’s name should be put into the Pod definition as a label. Then, they can do Kubernetes operation on their resource by using that label. What I mean :

$ kubectl delete pod -L dev-name=xxx 

So a question came to my mind: How can developers manage all names in the Pod definition? I hear from here that that should be a joke. I’m agreed. But what is the most smooth solution to tackle this problem? Actually, the right question is “ How can I calmly manage a group of objects/resources in Kubernetes ? “. I’m giving an answer: “ with a Namespace”.

What is a Namespace :

If you want to split Kubernetes resources into a separate group, then, you can use namespaces, other than the labels. You can easily split up Kubernetes resources to develop, stage ( or QA), and production environments. All resources are logically isolated from each other.

When you create a pod without a namespace, the resource will be created in the “default” namespace configured in the current “kubectl” context. Of course, you can create Kubernetes resources in your Namespace, which is called “custom namespace”. Kind of Namespaces :

  • Default Namespace:
$ kubectl get ns # Check the configured default namespace in current context.

The command below will create a pod in the “default” namespace.

$ kubectl apply -f  https://raw.githubusercontent.com/ErhanCetin/k8s-smooth-transition/develop/k8s/medium-post/pods/news-tracker-activemq-pod.yaml$ kubectl get pod activemq-pod -o yaml

When you hit the “ $ kubectl get pods “, kubectl is adding “ -n default “ like “kubectl get pods -n default” to fetch the resource from the default namespace.

  • Custom Namespaces:

There are two ways to create a resource with namespace :

  1. The first is through kubectl, use “-n <namespace-name> “ in kubectl, but the namespace should be created first. For creating a namespace, also, there are two ways, either via kubectl or YAML files below ;
$ kubectl create namespace develop  # let's continue with that way.
Create a namespace via a YAML file.

Create a pod in the “develop” namespace :

$ kubectl -n develop apply -f https://raw.githubusercontent.com/ErhanCetin/k8s-smooth-transition/develop/k8s/medium-post/pods/news-tracker-activemq-pod.yaml

Check the pod in the develop namespace :

$ kubectl get pods -n develop

2. The second is to add “namespace” to your pod definition, but remember, firstly create a namespace. When the pod is created, it will directly be part of the “develop” namespace.

Around the Namespaces

  • Resource names need to be uniques within a namespace, but two different namespaces can have the same name.
  • All resource is not tied to a single namespace like a Node resource. The node resource is namespace-less.
  • When you perform the “kubectl” command without specifying the namespace, the action will have happened in the default namespace configured in the current kubectl context.
  • Users interacting with one namespace do not see the content in another namespace.
  • Namespaces can be used to allow different teams to use the same cluster as though they are using separate Kubernetes clusters.
  • Namespaces allow you to isolate objects but that doesn’t mean a resource cannot communicate with each other. E.g., If a pod in any namespace knows the IP of a pod in any other namespace, it can communicate with each other. There is nothing preventing it from sending traffic.

I guess you have an idea about namespaces. Another important point, It is time to talk about a bit, is Kubernetes config and context.

Kubernetes Cluster Config :

The kubectl command-line tool uses kubeconfig file ( ~/.kube/config for MACOS) to find the information it needs to choose a cluster and communicate with the API server of a cluster. When you install and start the “Minikube” in your local, the Minikube will put cluster and context data to the config file which context info of cluster are in :

$ kubectl get config

Also, you can check config via “ cat ~/.kube/config “ in your local ( for MACOS users).

$ kubectl cluster-info

Kubernetes Context :

A context is a group of access parameters used by kubectl. Each context contains a Kubernetes cluster, a user, and optionally a namespace. Let’s check context data in the Minikube config :

$ kubectl config get-contexts minikube
$ kubectl config view -o jsonpath='{.users[*].name}'
# get a list of users
$ kubectl config current-context # get current context ( means minikube for us.)

You can assign a namespace to context. In this case, your default namespace will be what you put into context:

$ kubectl config set-context --current —namespace=my-namespace
$ kubectl config get-contexts minikube

So, If you hit “ $ kubectl get pods”, it will be turned into “ $ kubectl get pods -n my-namespace”. It means your default namespace is “my-namespace”.

What we understand about using the context which is via kubeconfig file is that kubectl a command-line needs to know which cluster to use with which users. In your local, you might have some configuration with more than one cluster. In this case, just change the context as follows and instruct the Kubernetes resources.

$  kubectl config current-context # check the current context .It will return “minikube”
$ kubectl config use-context <another-context-name> # set the another context if you have

You can use the commands like “kubectl set-cluster, kubectl set-credentials, and kubectl set-context “ to create a proper context which you want to instruct.

Useful Namespace and Config of Cluster Commands :

$ kubectl get ns # get namespace list.$ kubectl create namespace <your-namespace> # create a new namespace.$ kubectl get pods -n <your-namespace> # get any resource within your-namespace .E.g , just pods.$ kubectl delete ns <a-namespace> # remove namespace$ kubectl get pods --all-namespaces # get pods in all namespaces

Get rid of writing the namespace in each time :

When you want to work resource in the separate namespace as follows,

$ kubectl get pods -n develop
$ kubectl get pods -n stage
$ kubectl get pods -n prod

You could create an alias and use to get rid of the repetition of writing a namespace in the kubectl command:

$ alias kdev='kubectl -n > kubectl get pods -n develop’$ kdev get pods # means kubectl -n develop get pods.$ alias kstg='kubectl -n > kubectl get pods -n stage'$ alias kprd='kubectl -n > kubectl get pods -n prod'

Config of Cluster & Context :

$ kubectl get config # get config data which is on the ~/kube/config file.$ kubectl cluster-info # get cluster info$ kubectl get nodes # get node info$ kubectl config get-contexts # get all context in your local.$ kubectl config current-context   # get current context . It might be more than one.$ kubectl config set-context --current —namespace=your-namespace 
# set default namespace for current context
$ kubectl config use-context <another-context-name> # change default context

That’s all. See you next post.

--

--