Namespaces are Kubernetes objects which partition a single Kubernetes cluster into multiple virtual clusters.
Namespaces are Kubernetes objects which partition a single Kubernetes cluster into multiple virtual clusters. Each Kubernetes namespace provides the scope for Kubernetes Names
it contains; which means that using the combination of an object name and a Namespace, each object gets a unique identity across the cluster.
By default, a Kubernetes cluster is created with the following three namespaces:
- default: By default, all the resource created in the Kubernetes cluster are created in the
default namespace
. By default thedefault namespace
can allow applications to run with unbounded CPU and memory requests/limits (Until someone set resource quota for thedefault namespace
). - Kube-public: Namespace for resources that are publicly readable by all users. This namespace is generally reserved for cluster usage.
- Kube-system: It is the Namespace for objects created by Kubernetes systems/control plane.
Prerequisites
- Basic experience with Linux/Unix system.
- Familiarity with Kubernetes.
- Kubernetes cluster to perform the demo.
Create a Namespace.
- List the namespaces present in the Kubernetes cluster.
$ kubectl get namespaces NAME STATUS AGE default Active 5m kube-public Active 5m kube-system Active 5m
We can create a Namespace in two ways either by using kubectl create namespace
command or by using a configuration file.
- Create a new namespace
my-namespace
with command.
$ kubectl create ns my-namespace namespace/my-namespace created
- List the namespaces.
$ kubectl get namespace NAME STATUS AGE default Active 8m kube-public Active 8m kube-system Active 8m my-namespace Active 3s
We can also create a namespace using the configuration file.
- Let’s create a namespace from the configuration file.
apiVersion: v1 kind: Namespace metadata: name: test-ns
- Deploy the above file.
$ kubectl apply -f namespace.yaml namespace/test-ns created
- List the namespaces.
$ kubectl get namespace NAME STATUS AGE default Active 18m kube-public Active 18m kube-system Active 18m my-namespace Active 9m test-ns Active 2m
Use-cases of Namespaces
Partition Cluster resources.
Kubernetes Namespaces can be used to divide a cluster into logical partitions allowing a single large Kubernetes cluster to be used by multiple users and teams, or a single user with multiple applications. Each user, the team, or application running in a Namespace, is isolated from every other user, team, or application in other Namespaces and they operate as if they are the sole user of the cluster (note that Namespaces do not provide network segmentation).
Deploy the application in a specific namespace.
Now we will see how to create a Kubernetes object inside a specific namespace.
- List the namespaces.
$ kubectl get namespace NAME STATUS AGE default Active 18m kube-public Active 18m kube-system Active 18m my-namespace Active 9m test-ns Active 2m
- Let’s create a pod from the following configuration.
apiVersion: v1 kind: Pod metadata: name: mypod namespace: my-namespace labels: app: mypod spec: containers: - name: mypod image: nginx:alpine
In the above configuration, we have specified the namespace with field namespace: my-namespace
. So this pod will be created inside the my-namespace
namespace.
- Deploy a pod with the above configuration.
$ kubectl apply -f mypopd.yaml pod/mypod created
- List the pods present in
my-namespace
namespace.
$ kubectl get pod -n my-namespace NAME READY STATUS RESTARTS AGE mypod 1/1 Running 0 16s
Bind user to a specific namespace.
By setting the context, we can bind a user to a specific namespace, so this namespace will be the default namespace for that user. You can do it either by modifying the kubeconfig
file or using following command
- Create a Namespace for different teams like
dev, qa and production
$ kubectl create ns dev # Namespace for Developer team $ kubectl create ns qa # Namespace for QA team $ kubectl create ns production # Namespace for Production team
- Set the context for different user groups.
# Bind dev context to dev namespace $ kubectl config set-context dev --namespace=dev --cluster=kubernetes --user=dev # Bind qa context to QA namespace kubectl config set-context qa --namespace=qa --cluster=kubernetes --user=qa # Bind production context to production namespace kubectl config set-context production --namespace=prod --cluster=kubernetes --user=production
Here we have bound Dev team to dev
namespace, QA team to qa
namespace and Production team to production
namespace.
This specific namespace will act as the default namespace for the particular team assigned to it. For detailed information of Kubernetes context and kubeconfig follow the documentation given at kubernetes.io.
Ability to specify resource consumption policies.
With Resource Quotas
applied on namespaces, we can limit the cluster resource usage of a particular set of users. A resource quota is responsible for limiting resource consumption per namespace. It also can limit the number of objects that can be created in a namespace by type, as well as the total amount of computing resources that may be consumed by resources in that namespace.
Now we will see how we can configure the resource quota for specific Namespace.
- Create a new
demo
namespace.
$ kubectl create namespace demo namespace/demo created
- Create a resource quota object for
demo
namespace.
apiVersion: v1 kind: ResourceQuota metadata: name: mem-cpu namespace: demo spec: hard: requests.cpu: "0.5" requests.memory: 512Mi limits.cpu: "1" limits.memory: 1Gi
Here, we are specifying that in the demo namespace; we can not request more than 0.5 CPU and 512Mi RAM overall. So if we already have a pod running with 256 Mi request; we would not be able to schedule a new pod, if that requires more than the remaining 256 Mi memory. Similarly, we are setting the hard limit of 1 CPU and 1GB RAM for the namespace.
Deploy this resource qouta object.
$ kubectl apply -f qouta.yaml resourcequota/mem-cpu created
- Get detailed information about the above-created resource quota.
kubectl get resourcequota mem-cpu --namespace=demo --output=yaml apiVersion: v1 kind: ResourceQuota metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"v1","kind":"ResourceQuota","metadata":{"annotations":{},"name":"mem-cpu","namespace":"demo"},"spec":{"hard":{"limits.cpu":"1","limits.memory":"1Gi","requests.cpu":"0.5","requests.memory":"512Mi"}}} creationTimestamp: 2018-11-21T07:05:48Z name: mem-cpu namespace: demo resourceVersion: "6091" selfLink: /api/v1/namespaces/demo/resourcequotas/mem-cpu uid: dfd1002c-ed5b-11e8-ab3b-507b9d3bd0b6 spec: hard: limits.cpu: "1" limits.memory: 1Gi requests.cpu: 500m requests.memory: 512Mi status: hard: limits.cpu: "1" limits.memory: 1Gi requests.cpu: 500m requests.memory: 512Mi used: limits.cpu: "0" limits.memory: "0" requests.cpu: "0" requests.memory: "0"
Here we can see the information about the hard limits as well as used resources for a given namespace.
- Deploy Demo1 application within this namespace. Whose resource request can be fulfilled by the resource quota set for this namespace.
apiVersion: v1 kind: Pod metadata: namespace: demo name: pod-demo1 labels: app: demo1 spec: containers: - name: demo1 image: nginx:alpine ports: - containerPort: 80 resources: limits: memory: "400Mi" cpu: "0.3" requests: memory: "300Mi" cpu: "0.2"
- Deploy this demo1 application.
$ kubectl apply -f demo1.yaml pod/pod-demo1 created
This application resource request was within the resource quota’s specification. So this pod got deployed.
- Now let’s create another pod in
demo
namespace. Whose resource request is exceeding the resource quota set for the namespace. And let’s see what happens.
apiVersion: v1 kind: Pod metadata: namespace: demo name: demo-pod2 labels: app: demo spec: containers: - name: demo image: nginx:alpine ports: - containerPort: 80 resources: limits: memory: "700Mi" cpu: "0.6" requests: memory: "600Mi" cpu: "0.6"
- Let’s try to deploy this demo2 application.
$ kubectl apply -f demo2.yaml Error from server (Forbidden): error when creating "demo2.yaml": pods "demo-pod2" is forbidden: exceeded quota: mem-cpu, requested: limits.memory=700Mi,requests.cpu=600m,requests.memory=600Mi, used: limits.memory=400Mi,requests.cpu=200m,requests.memory=300Mi, limited: limits.memory=1Gi,requests.cpu=500m,requests.memory=512Mi
This error occurred because this pod is requesting greater resources than specified in the resource quota.
- Let’s delete the
demo
namespace. It will delete the namespace along with all the objects running inside it.
$ kubectl delete namespace demo namespace "demo" deleted
- Delete earlier created namespace.
$ kubectl delete namespace my-namespace test-ns namespace "my-namespace" deleted namespace "test-ns" deleted
Policies to run resources.
With the Role-based access control (RBAC), we can control the access permissions within a particular Namespace. Cluster Admin can control the access permission granted to the user or groups of users in specific namespaces, this can be achieved with the help of Role Binding.
A unique scope for Kubernetes Names.
Kubernetes namespace provides the scope for Kubernetes Names
. Within the Namespace, an Object can be referred by a short name like my-app
and the Namespace adds further scope to identify the object, e.g. my-app.my-namespace
. Within the Namespace, the name of the object must be unique and the combination of Name and Namespace (e.g. my-app.my-namespace
) must have to be unique at the cluster level.
Summary
Namespaces are essential objects for dividing and managing Kubernetes clusters. Namespaces allow us to logically segregate and assign resources to individual users, teams or applications. Namespaces provide the basic building blocks for resource usage allowance, access control and isolation for applications, users, or groups of users. By using Namespaces, you can increase resource efficiencies as a single cluster can now be used for a diverse set of workloads.
References
- Kubernetes Namespaces : https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
- Kubernetes Names : https://kubernetes.io/docs/concepts/overview/working-with-objects/names/
- Role-based access control (RBAC) : https://kubernetes.io/docs/reference/access-authn-authz/rbac/
- Resource Quotas : https://kubernetes.io/docs/concepts/policy/resource-quotas/)
- Kubeconfig : https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/