In Kubernetes, namespaces provides a mechanism for isolating groups of resources within a single cluster. Names of resources need to be unique within a namespace, but not across namespaces. Namespace-based scoping is applicable only for namespaced objects (e.g. Deployments, Services, etc) and not for cluster-wide objects (e.g. StorageClass, Nodes, PersistentVolumes, etc).
When Should You Use Multiple Namespaces?
In small projects or teams, where there is no need to isolate workloads or users from each other, it can be reasonable to use the default Kubernetes namespace. Consider using multiple namespaces for the following reasons:
Isolation- If you have a large team, or several teams working on the same cluster, you can use namespaces to create separation between projects and microservices. Activity in one namespace never affects the other namespaces.
Development stages - If you use the same Kubernetes cluster for multiple stages of the development lifecycle, it is a good idea to separate development, testing, and production environments. You do not want errors or instability in testing environments to affect production users. Ideally, you should use a separate cluster for each environment, but if this is not possible, namespaces can create this separation.
Permissions - It might be necessary to define separate permissions for different resources in your cluster. You can define separate RBAC rules for each namespace, ensuring that only authorized roles can access the resources in the namespace. This is especially important for mission critical applications, and to protect sensitive data in production deployments.
Resource control - You can define resource limits at the namespace level, ensuring each namespace has access to a certain amount of CPU and memory resources. This enables separating cluster resources among several projects and ensuring each project has the resources it needs, leaving sufficient resources for other projects.
Initial namespaces
Kubernetes starts with four initial namespaces:
Default:
Kubernetes includes this namespace so that you can start using your new cluster without first creating a namespace.
kube-node-lease:
This namespace holds Lease objects associated with each node. Node leases allow the kubelet to send heartbeats so that the control plane can detect node failure.
kube-public:
This namespace is readable by all clients (including those not authenticated). This namespace is mostly reserved for cluster usage, in case that some resources should be visible and readable publicly throughout the whole cluster. The public aspect of this namespace is only a convention, not a requirement.
kube-system:
The namespace for objects created by the Kubernetes system.
Creating a new namespace
Note: Avoid creating namespace with prefix kube-
, since it is reserved for Kubernetes system namespaces.
Create a new YAML file called my-namespace.yaml with the contents:
apiVersion: v1
kind: Namespace
metadata:
name: <insert-namespace-name-here>
Then run:
kubectl create -f ./my-namespace.yaml
Alternatively, you can create namespace using below command:
kubectl create namespace my-namespace
Viewing namespaces
List the current namespaces in a cluster using:
kubectl get namespace
NAME STATUS AGE
default Active 1d
kube-node-lease Active 1d
kube-public Active 1d
kube-system Active 1d
Deleting a namespace
Delete a namespace with
kubectl delete namespaces <insert-some-namespace-name>
Creating Resources in the Namespace
When you create a resource in Kubernetes without specifying a namespace, it is automatically created in the current namespace.
For example, the following pod specification does not specify a namespace:
apiVersion: v1
kind: Pod
metadata:
name: mypod
labels:
name: mypod
spec:
containers:
—name: mypod
image: nginx
When you apply this pod specification, the following will happen:
If you did not create any namespaces in your cluster, the pod will be created in the default namespace If you created a namespace and are currently running in it, the pod will be created in that namespace.
How can you explicitly create a resource in a specific namespace?
There are two ways to do this:
Use the –namespace flag when creating the resource, like this:
kubectl apply -f pod.yaml --namespace=mynamespace
Specify a namespace in the YAML specification of the resource. Here is what it looks like in a pod specification:
apiVersion: v1 kind: Pod metadata: name: mypod namespace: mynamespace labels: name: mypod ...