Sergey Nivens - Fotolia

A Kubernetes namespaces tutorial to manage cluster resources

Namespaces in Kubernetes serve several purposes -- from allowing teams to share a single cluster to enforcing resource quotas. Use this tutorial to get started with this important Kubernetes feature.

Kubernetes namespaces partition a Kubernetes cluster into logical isolations. This enables IT teams to organize Kubernetes infrastructure resources so that various users and teams can collaborate, while maintaining clear and isolated boundaries.

For example, with Kubernetes namespaces, IT teams can logically isolate development, test and production environments. Namespaces also provide administrative control over resources, via resource quotas and limits.

When an IT admin first sets up a Kubernetes cluster, four namespaces are automatically created:

  • Default. All the resource deployments without a namespace are deployed under this namespace.
  • kube-system. This namespace holds Kubernetes system configurations and deployments crucial to the Kubernetes cluster.
  • kube-public. This namespace is open to all users with read-only access, but reserved for system usage.
  • kube-node-lease. All nodes have an associated Lease object in this namespace. A Lease boosts the performance of the node heartbeats -- messages that nodes send to the node controller to indicate availability -- as the Kubernetes cluster scales.

Let's dig deeper and understand how to work with namespaces. As a prerequisite, have a Kubernetes cluster up and running before attempting the commands.

Query namespaces

Run the following commands to receive the list of all namespaces, or a specific namespace in Kubernetes:

kubectl get namespaces
kubectl get namespaces <name of namespace>

This will produce an output similar to Figure 1.

Kubernetes namespaces
Figure 1. List Kubernetes namespaces

For more detailed information about a namespace, use the describe command:

kubectl describe namespaces <name of namespace>

This adds more verbosity to the output, with annotations, labels and resource quotas and limits.

Kubectl namespace description
Figure 2. Kubernetes namespace description

Create resources in namespaces

To create a resource in a specific namespace that already exists, pass the name of the namespace as an argument to the -n or --namespace parameter in the command:

kubectl create deployment my-nginx --image nginx --namespace webserver

The output should look similar to Figure 3.

Pass a Kubernetes namespace
Figure 3. Pass the namespace as an argument

List resources from all namespaces

The --all-namespaces switch parameter will list any resources in all the namespaces, as in the following command:

kubectl get pods --all-namespaces

This lists all the pods running in all namespaces in Kubernetes.

Resources in all namespaces
Figure 4. Resources in all namespaces

However, this method doesn't provide the exact list of all the resources in Kubernetes, because not all resources are organized in a namespace -- for example, low-level resources, such as nodes, cluster roles and persistent volumes, are not in any namespace. Issue the command below to list all such resources without a namespace:

kubectl api-resources --namespaced=false

The output should look similar to the screen in Figure 5, which also demonstrates that namespaces are -- themselves -- not in any namespace, either.

Resources outside namespaces
Figure 5. Resources outside namespaces

Set namespace preference

IT admins can set a namespace preference for all subsequently executed commands to remember. This eliminates the need to explicitly define namespace names with all kubectl commands:

kubectl config set-context --current --namespace=<name of namespace>

For example, see Figure 6, which features a webserver namespace.

Webserver namespace
Figure 6. Set a namespace preference

Create a new namespace

Namespace creation is simple: Run the kubectl create namespace <name of namespace> command, and insert the name of the namespace you want to create, as shown in Figure 7. Note that namespaces are non-hierarchal; you cannot create a namespace within another namespace.

Server namespace
Figure 7. Create a Kubernetes namespace

Alternatively, admins can use a YAML file to create a namespace. Set up a namespace.yml file with the following declarations.

Kubectl namespace creation via YAML file
Figure 8. Kubernetes namespace creation via YAML file

Delete a namespace

A namespace can be deleted asynchronously using the kubectl delete namespaces <name of namespace> command, which will also delete any Kubernetes resources under the namespace.

Delete a namespace
Figure 9. Delete a namespace

Configure resource quotas on namespaces

Kubernetes administrators can use namespaces to control resource allocation, such as to set hard limits on the number of pods that can be created in a namespace, or to enforce limits on the volume of memory and CPU that users can request. To configure a resource quota on a namespace, first create a YAML file, like the one below, and define hard limits to requests under the target namespace and maximum resource allocation of memory and CPU.

apiVersion: v1
kind: ResourceQuota
metadata:
  name: mem-cpu-quota
spec:
  hard:
    requests.cpu: "1"
    requests.memory: 1Gi
    limits.cpu: "2"
    limits.memory: 2Gi

Then, apply this resource quota configuration to the namespace, using the following command:

kubectl apply -f quota.yml --namespace demo
kubectl describe resourcequota mem-cpu-quota --namespace demo

The output should look as seen in Figure 10.

Namespace resource quotas
Figure 10. Apply resource quotas to namespace

Now, to create a pod in this demo namespace and assign some resources, create a YAML file called pods.yml with the following configurations:

apiVersion: v1
kind: Pod
metadata:
  name: demo-pod
spec:
  containers:
  - name: demo-container-1
    image: nginx
    resources:
      limits:
        memory: "900Mi"
        cpu: "900m"
      requests:
        memory: "700Mi"
        cpu: "600m"

To apply this pod configuration, run the following commands:

kubectl apply -f pods.yml --namespace demo
kubectl describe resourcequota mem-cpu-quota --namespace demo

Some of the resources from the quota we defined are already allocated to the newly created pod.

Pod configuration
Figure 11. Apply the pod configuration

After we set the resource quota on a namespace and create the nodes that consume most of the resources under that quota, we attempt to create another pod with a resource that exceeds the possible limit, using the pod2.yml file below:

apiVersion: v1
kind: Pod
metadata:
  name: demo-pod-2
spec:
  containers:
  - name: demo-container-1
    image: nginx
    resources:
      limits:
        memory: "900Mi"
        cpu: "900m"
      requests:
        memory: "700Mi"
        cpu: "600m"

As you can see, the request will fail, with the message "exceeded quota."

Exceeded quota
Figure 12. Exceeded quota

Dig Deeper on Systems automation and orchestration