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
kubectl
command-line tool interacts with the default namespace. - If you want to use a different namespace, you can pass
kubectl
the--namespace
flag. - For example,
kubectl --namespace=mystuff
references objects in themystuff
namespace. - If you want to interact with all namespaces - for example, to list all Pods in your cluster you can pass the
--all-namespaces
flag.
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 need to 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 default namespace.
[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 in How 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.