Continuing with our theme of organization, kubernetes allows us to think of the cluster as a set of virtual clusters using Namespaces.
What is a Namespace?
A namespace is a logical separation between resources in the same kubernetes cluster.
The word logical implies that there is no physical separation between resources in different namespaces. Resources in different namespaces may talk to each other.
The constraint then, is for the viewer (user). Using RBAC, you can limit a user to only be able to access and deploy to a particular namespace. As a user he/she considers his/her namespace to be all-in-all.
In the post on resources we learnt how kubectl create
cannot a create a pod with the same name as an already existing pod. Using namespaces we can!
Things to remember
- There is no physical separation between resources. They can talk to each other if they wish to do so.
- Users can be given namespace-specific roles as well as roles that span across all namespaces
- By default your user in Minikube can access all namespaces.
- There are some resources that are outside namespaces, such as nodes etc.
- Resources in different namespaces can share the same nodes.
Default namespaces
By default, kubernetes creates 4 namespaces. To see available namespaces you can do kubectl get namespaces
param@param-Inspiron-7560:~$ kubectl get namespaces
NAME STATUS AGE
default Active 5d16h
kube-node-lease Active 5d16h
kube-public Active 5d16h
kube-system Active 5d16h
If you specify no namespace, you will deploy to default namespace. All kubernetes services are deployed in kube-system namespace. kube-node-lease is specifically for lease objects which each node creates to help with status updates. kube-public is a publicly readable namespace (even for unauthenticated users). If you do not specify a namespace when issuing a command default namespace is assumed.
Resources in Namespaces
To view resources in namespaces use the command line option -n in kubectl
$ kubectl get pods -n default
NAME READY STATUS RESTARTS AGE
centos-pod 1/1 Running 1 2d9h
junk-pod 1/1 Running 1 2d9h
ubuntu-pod 1/1 Running 1 2d9h
$ kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-6955765f44-7hjbw 1/1 Running 6 5d17h
coredns-6955765f44-j8tzv 1/1 Running 6 5d17h
etcd-m01 1/1 Running 6 5d17h
kube-apiserver-m01 1/1 Running 7 5d17h
kube-controller-manager-m01 1/1 Running 6 5d17h
kube-proxy-9d2sw 1/1 Running 6 5d17h
kube-scheduler-m01 1/1 Running 6 5d17h
storage-provisioner 1/1 Running 11 5d17h
To view resources in all names spaces use the option –all-namespaces.
$ kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
default centos-pod 1/1 Running 1 2d9h
default junk-pod 1/1 Running 1 2d9h
default ubuntu-pod 1/1 Running 1 2d9h
kube-system coredns-6955765f44-7hjbw 1/1 Running 6 5d17h
kube-system coredns-6955765f44-j8tzv 1/1 Running 6 5d17h
kube-system etcd-m01 1/1 Running 6 5d17h
kube-system kube-apiserver-m01 1/1 Running 7 5d17h
kube-system kube-controller-manager-m01 1/1 Running 6 5d17h
kube-system kube-proxy-9d2sw 1/1 Running 6 5d17h
kube-system kube-scheduler-m01 1/1 Running 6 5d17h
kube-system storage-provisioner 1/1 Running 11 5d17h
Switching Namespaces like a boss
If you plan to work on a particular namespace exclusively you can tell kubectl to do that with the below command
kubectl config set-context --current --namespace=<insert-namespace-name-here>
Also do take a look at these tools which provide a UI to choose the context and the Namespace. (Only useful if you have many contexts, and many namespaces)
Kubectx and kubens : https://github.com/ahmetb/kubectx
Lets see how we can use namespaces with a real-world example!.
The Tale of Two Teams
Alice and Bob are TechLeads of 2 teams called “Alice” and “Bob” and each has 1 service called (you guessed it!) “Alice” and “Bob” (Narcissism rules in Tech). Your infra team has created a SuperDuperInfraPod which has to be installed, once for each Team. You also are sick of listening to Alice and Bob constantly complaining about each other. You don’t think much about the other engineers (as usual) and so have given both teams instructions to use this pod specification verbatim.
apiVersion: "v1"
kind: Pod
metadata:
name: superduperinfra
labels:
app: superduperinfra
version: v5
role: backend
spec:
containers:
- name: ubuntu-container
image: ubuntu
command: ["/bin/bash"]
args: ["-c", "while [ \"a\" = \"a\" ]; do echo \"All your pods are belong to us\"; sleep 5; done" ]
Here are alice and bob pod specifications. Please treat these as highly confidential.
apiVersion: "v1"
kind: Pod
metadata:
name: alice
labels:
app: alice
version: v5
role: backend
spec:
containers:
- name: ubuntu-container
image: ubuntu
command: ["/bin/bash"]
args: ["-c", "while [ \"a\" = \"a\" ]; do echo \"alice is the best\"; sleep 5; done" ]
apiVersion: "v1"
kind: Pod
metadata:
name: bob
labels:
app: bob
version: v5
role: backend
spec:
containers:
- name: ubuntu-container
image: ubuntu
command: ["/bin/bash"]
args: ["-c", "while [ \"a\" = \"a\" ]; do echo \"Bob is the best\"; sleep 5; done" ]
Deploying Alice And Bob
You first need to create the namespaces. Lets think of some good names! How about “Alice’s team” and “Bob’s team”? perfect!
$ kubectl create namespace "alice's team"
The Namespace "alice's team" is invalid: metadata.name: Invalid value: "alice's team": a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')
That sucks, you are only allowed [a-z][0-9] and -
. Lets try again.
$ kubectl create namespace "alices-team"
namespace/alices-team created
$ kubectl create namespace "bobs-team"
namespace/bobs-team created
$ kubectl get namespaces
NAME STATUS AGE
alices-team Active 21s
bobs-team Active 13s
default Active 5d18h
kube-node-lease Active 5d18h
kube-public Active 5d18h
kube-system Active 5d18h
Lets deploy alice and bob services to their respective namespaces
$ kubectl create -f alice.yml -n alices-team
pod/alice created
$ kubectl create -f bob.yml -n bobs-team
pod/bob created
Quick check to see if everything is running.
param@param-Inspiron-7560:~/repos/kubernetes101$ kubectl get pods -n bobs-team
NAME READY STATUS RESTARTS AGE
bob 1/1 Running 0 2m32s
param@param-Inspiron-7560:~/repos/kubernetes101$ kubectl get pods -n alices-team
NAME READY STATUS RESTARTS AGE
alice 1/1 Running 0 2m58s
By using proper permissions we can restrict Alice’s team to only see the namespace alices-team
and Bob’s team to only see the namespace bobs-team.
Finally lets create the SuperDuperInfraPod in both namespaces.
$ kubectl create -f superduperinfra.yml -n alices-team
pod/superduperinfra created
$ kubectl create -f superduperinfra.yml -n bobs-team
pod/superduperinfra created
$ kubectl get pods -n alices-team
NAME READY STATUS RESTARTS AGE
alice 1/1 Running 0 6m9s
superduperinfra 1/1 Running 0 16s
$ kubectl get pods -n bobs-team
NAME READY STATUS RESTARTS AGE
bob 1/1 Running 0 5m53s
superduperinfra 1/1 Running 0 14s
Learnings
Namespace is only a logical separation. They can still talk to each other.
Try not to name your services and teams by the Tech Lead’s name. (I know its hard)
Pods and Resources in different namespace can have the same name.
Users can be configured to have access only to specific namespaces.
In a company I worked for, we had a service called Kingsly which handled certificate expiry, because, before the service, Kingsly used to do it. Good joke, but the first question every engineer asks at onboarding is Why Kingsly? Even worse, if someone has an issue with Kingsly, they, by default, ping Kingsly who no longer works on that service!
Conclusion
Labels and Namespaces are ways to organize your kube-cluster. Right now you may be thinking of a pod here or a service there, but very soon you will be dealing with 10000s of pods. There is much pain to be avoided here!
The logical structure of your cluster(s) should follow the structure of your org. When you are a single team then there is no need for namespaces. When the team splits though, you need to setup proper separation and interfaces. Namespaces and labels are here to help. A little thought can save a lot of pain later.
In the next post we will look at setting up Roles based on Namespaces.