You may have heard about Linux namespace which are used to isolate system processes from each other. In a similar concept we have namespace in Kubernetes which can provide a scope for objects names. We will learn more about Kubernetes namespace in this tutorial.
Understanding Kubernetes Namespaces
- Kubernetes uses namespaces to organize objects in the cluster.
- You can think of each namespace as a folder that holds a set of objects.
- Namespace implements strict resource separation
- Resource limitation through quota can be implemented at a Namespace level also
- Use namespaces to separate customer environments within one Kubernetes cluster
- By default, the
kubectlcommand-line tool interacts with the default namespace. - If you want to use a different namespace, you can pass
kubectlthe--namespaceflag. - For example,
kubectl --namespace=mystuffreferences objects in themystuffnamespace. - If you want to interact with all namespaces - for example, to list all
Pods in your cluster you can pass the
--all-namespacesflag.
Four namespaces are defined when a cluster is created:
- default: this is where all the Kubernetes resources are created by default
- kube-node-lease: an administrative namespace where node lease information is stored - may be empty and/or non-existing
- kube-public: a namespace that is world-readable. Generic information can be stored here but it’s often empty
- kube-system: contains all infrastructure pods
Why do we need namespaces?
Using multiple namespaces allows you to split complex systems with numerous components into smaller distinct groups.This is useful in scenarios wherein you want to split and limit resources across different resources. Resource names only needto be unique within a namespace.Two different namespaces can contain resources of the same name.
Although namespaces allow you to isolate objects into distinct groups, which allows you to operate only on those belonging to the specified namespace, they don’t provide any kind of isolation of running objects. For example, you may think that when different users deploy pods across different namespaces, those pods are isolated from each other and can’t communicate, but that’s not necessarily the case. Whether namespaces provide network isolation depends on which networking solution is deployed with Kubernetes. When the solution doesn’t provide inter-namespace network isolation, if a pod in namespace foo knows the IP address of a pod in namespace bar, there is nothing preventing it from sending traffic, such as HTTP requests, to the other pod.
List available namespaces
To get the list of available namespaces. Up to this point, we have operated only in the defaultnamespace.
[root@controller ~]# kubectl get ns
NAME STATUS AGE
default Active 14d
kube-node-lease Active 14d
kube-public Active 14d
kube-system Active 14d
Alternatively you can also use kubectl get namespace. To get a list of
all the available namespaces:
[root@controller ~]# kubectl get all --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system pod/coredns-f9fd979d6-nmsq5 1/1 Running 4 14d
kube-system pod/coredns-f9fd979d6-xtsrj 1/1 Running 4 14d
kube-system pod/etcd-controller.example.com 1/1 Running 4 14d
kube-system pod/kube-apiserver-controller.example.com 1/1 Running 4 14d
kube-system pod/kube-controller-manager-controller.example.com 1/1 Running 4 14d
kube-system pod/kube-proxy-6fxwf 1/1 Running 3 14d
kube-system pod/kube-proxy-7v9zg 1/1 Running 4 14d
kube-system pod/kube-proxy-snk6p 1/1 Running 3 14d
kube-system pod/kube-scheduler-controller.example.com 1/1 Running 4 14d
kube-system pod/weave-net-jczxg 2/2 Running 12 14d
kube-system pod/weave-net-md24g 2/2 Running 236 14d
kube-system pod/weave-net-rxpl5 2/2 Running 239 14d
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default service/kubernetes ClusterIP 10.96.0.1 443/TCP 14d
kube-system service/kube-dns ClusterIP 10.96.0.10 53/UDP,53/TCP,9153/TCP 14d
NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
kube-system daemonset.apps/kube-proxy 3 3 3 3 3 kubernetes.io/os=linux 14d
kube-system daemonset.apps/weave-net 3 3 3 3 3 14d
NAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE
kube-system deployment.apps/coredns 2/2 2 2 14d
NAMESPACE NAME DESIRED CURRENT READY AGE
kube-system replicaset.apps/coredns-f9fd979d6 2 2 2 14d
To list the pods from a specific namespace, for example to list all the
pods under default namespace we will use following command:
[root@controller ~]# kubectl get pods -n default
NAME READY STATUS RESTARTS AGE
nginx-deploy-58f9bf94f7-4cwlr 1/1 Running 0 43h
nginx-deploy-58f9bf94f7-98jr8 1/1 Running 0 43h
pod-as-user-guest 1/1 Running 2 12d
pod-privileged 1/1 Running 2 12d
pod-with-host-network 1/1 Running 2 12d
Here you can also use --namespace instead of -n.
Creating a namespace
A namespace is a Kubernetes resource like any other, so you can create
it by posting a YAML file to the Kubernetes API server or directly via
kubectl command.
Using YAML file
To create a Kubernetes namespace using YAML file we would need the
KIND and apiVersion. To get the KIND value of a namespace we will
list down the api-resources:
[root@controller ~]# kubectl api-resources | grep -iE 'namespace|KIND'
NAME SHORTNAMES APIGROUP NAMESPACED KIND
namespaces ns false Namespace
Now that we have the KIND value, we can use this to get the respective
apiVersion:
[root@controller ~]# kubectl explain Namespace | head -n 2
KIND: Namespace
VERSION: v1
Now since we have the KIND and apiVersion value, let’s create a
custom-namespace.yaml file with the following listing’s contents:
[root@controller ~]# cat app-ns.yml
apiVersion: v1
kind: Namespace
metadata:
name: app
Now, use kubectl to post the file to the Kubernetes API server:
[root@controller ~]# kubectl create -f create-namespace.yml
namespace/app created
List the available namespaces:
[root@controller ~]# kubectl get ns
NAME STATUS AGE
app Active 34s
default Active 37d
kube-node-lease Active 37d
kube-public Active 37d
kube-system Active 37d
Using kubectl command
Although writing a file like the previous one isn’t a big deal, it’s
still a hassle. Luckily, you can also create namespaces with the
dedicated kubectl create namespace command, which is quicker than
writing a YAML file. To create a namespace using kubectl command:
[root@controller ~]# kubectl create ns dev
namespace/dev created
List the available namespace:
[root@controller ~]# kubectl get ns
NAME STATUS AGE
app Active 2m12s
default Active 37d
dev Active 2s
kube-node-lease Active 37d
kube-public Active 37d
kube-system Active 37d
pods-quota-ns Active 36d
Get details of namespace
To get a much detailed output of individual namespace we use
kubectl describe command. As you can see currently there are no quota
or LimitRange assigned to this namespace which we will cover
inHow to
assign Kubernetes resource quota with examples
[root@controller ~]# kubectl describe ns default
Name: default
Labels:
Annotations:
Status: Active
No resource quota.
No LimitRange resource.
To get the details of namespace in YAML format:
[root@controller ~]# kubectl get ns default -o yaml
apiVersion: v1
kind: Namespace
metadata:
creationTimestamp: "2020-11-11T05:46:42Z"
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:status:
f:phase: {}
manager: kube-apiserver
operation: Update
time: "2020-11-11T05:46:42Z"
name: default
resourceVersion: "155"
selfLink: /api/v1/namespaces/default
uid: e45242f9-2f0e-4bcb-a385-6058044f20ce
spec:
finalizers:
- kubernetes
status:
phase: Active
Create resource objects in other namespaces
BY default any resource object you create such as Pods, deployments or any other objects, all of them are created in default namespace unless you explicitly define the namespace in YAML file or as an input argument to kubectl.
Method-1: Using YAML file
In this example I will create a new Pod with nginx container and
explicitly define the namespace as “app” in the YAML file itself under
metadata:
[root@controller ~]# cat nginx-app.yml
apiVersion: v1
kind: Pod
metadata:
name: nginx-app
namespace: app
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
We will create this Pod:
[root@controller ~]# kubectl create -f nginx-app.yml
pod/nginx-app created
As expected now if we look out for this Pod in default namespace, we get
NotFound
[root@controller ~]# kubectl get pods -n default nginx-app
Error from server (NotFound): pods "nginx-app" not found
Because we have created this Pod in app namespace:
[root@controller ~]# kubectl get pods -n app nginx-app
NAME READY STATUS RESTARTS AGE
nginx-app 1/1 Running 0 30s
Method-2: Using kubectl command
We can also pass an input argument to the kubectl command as
-n <namespace-name> to assign a namespace. Here I have a different
YAML file:
apiVersion: v1
kind: Pod
metadata:
name: nginx-dev
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
We will create this Pod inside “dev” namespace:
[root@controller ~]# kubectl create -f nginx-dev.yml -n dev
pod/nginx-dev created
List the newly created Pod under dev namespace:
[root@controller ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
nginx-dev 1/1 Running 0 34s
--namespace (or -n) flag to
kubectl. If you don’t specify the namespace, kubectl performs the
action in the default namespace configured in the current
kubectl context. The current context’s namespace and the current
context itself can be changed through kubectl config commands which we
will learn later.
Terminating namespaces
We have created a number of pods and namespaces in this tutorial which we don’t need anymore so let’s delete them.
Deleting a Pod using name
We have already covered this in Beginners guide on Kubernetes Pods with examples. By deleting a pod, you’re instructing Kubernetes to terminate all the containers that are part of that pod. Kubernetes sends a SIGTERM signal to the process and waits a certain number of seconds (30 by default) for it to shut down gracefully. If it doesn’t shut down in time, the process is then killed through SIGKILL.
[root@controller ~]# kubectl delete pod nginx-dev
pod "nginx-dev" deleted
Deleting pods by deleting the whole namespace
By default when we delete a namespace then all the pods under the provided namespace would also be terminated:
[root@controller ~]# kubectl delete ns dev
namespace "dev" deleted
Deleting all pods in a namespace, while keeping the namespace
Here I have a Pod running inside app namespace:
[root@controller ~]# kubectl get pods -n app
NAME READY STATUS RESTARTS AGE
nginx-app 1/1 Running 0 23m
Now to delete all the pods inside app namespace:
[root@controller ~]# kubectl delete pods -n app --all
pod "nginx-app" deleted
Since we had a single pod so only that one is deleted.
Delete all resources in a namespace
You can delete the ReplicationController and the pods, as well as all
the Services you’ve created, by deleting all resources in the current
namespace with a single command. To demonstrate this command I have
created some of the resource objects in app namespace:
[root@controller ~]# kubectl delete all --all -n app
pod "myapp-replicaset-5hwhc" deleted
pod "myapp-replicaset-hmqj9" deleted
pod "myapp-replicaset-q6m5r" deleted
pod "nginx-deploy-58f9bf94f7-fztpl" deleted
pod "nginx-deploy-58f9bf94f7-qnjhq" deleted
service "nginx-deploy" deleted
deployment.apps "nginx-deploy" deleted
replicaset.apps "myapp-replicaset" deleted
replicaset.apps "nginx-deploy-58f9bf94f7" deleted
The first all in the command specifies that you’re deleting resources
of all types, and the --all option specifies that you’re deleting all
resource instances instead of specifying them by name.
Conclusion
In this Kubernetes tutorial we learned all about namespace and how it can be used to allow different teams to use the same cluster as though they were using separate Kubernetes clusters. You may assign different set of quotas and LimitRange to individual namespace.


