Kubernetes create new namespace with quotas

Posted by

There are times when projects and team members accessing the projects grow.  In order to keep these environments isolated we incorporate namespaces and to ensure these projects don’t exceed their resource limits we can impose quotas.  

In this article I will provide a couple definitions followed by a two-step process.  In step 1, I will initially have my deployment resources request more resources in the newly deployed namespace causing all the pods to not get deployed.  In step 2, I will show how to deploy a new namespace with quotas after proper resource planning has been done.

Namespaces are intended for use in environments with many users spread across multiple teams, or projects. For clusters with a few to tens of users, you should not need to create or think about namespaces at all. 

Namespaces provide a scope for names. Names of resources need to be unique within a namespace, but not across namespaces. Namespaces cannot be nested inside one another and each Kubernetes resource can only be in one namespace.

****WARNING: the first portion of this walkthrough will fail because I will show in step 1 that the hard limits won’t be exceeded.  If you just want to know how to perform the tasks from beginning to end without any troubleshooting then skip to step 2.

Step 1. Create new quotas, namespace & deployment that will fail due to quota limits and how to troubleshoot.

As you can see I have three yaml files needed for this demo

apiVersion: v1
kind: Namespace
metadata:
  name: namespace-demo
---
apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: namespace-demo
spec:
  hard:
    requests.cpu: "1"
    requests.memory: 1Gi
    limits.cpu: "2"
    limits.memory: 2Gi
---
apiVersion: v1
kind: ResourceQuota
metadata:
  name: object-quota
  namespace: namespace-demo
spec:
  hard:
    configmaps: "5"
    persistentvolumeclaims: "2"
    replicationcontrollers: "10"
    secrets: "5"
    services: "5"
    services.loadbalancers: "1"

From the above you can see I have created a yaml file for my new namespace of myspace-demo along with resource quotas and object quotas for this namespace.

*****remember, when you create a namespace and specify quotas and when we apply our pods they must meet the specs provided

apiVersion: apps/v1
kind: Deployment
metadata:
  name: helloworld-deployment
  namespace: namespace-demo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: helloworld
  template:
    metadata:
      labels:
        app: helloworld
    spec:
      containers:
      - name: k8s-demo
        image: vmpebryant/k8s-demo
        ports:
        - name: nodejs-port
          containerPort: 3000
        resources:
          requests:
            cpu: 200m
            memory: 0.5Gi
          limits:
            cpu: 400m
            memory: 1Gi

From the above you can see we are going to deploy a hello-world app (nothing fancy) and we are going to deploy it into the namespace myspace-demo

$ kubectl apply -f <config file>

Deploy both yaml files.

$ kubectl get pods

This should not show the new pods running because it only returns the pods for the default namespace not newly created namespaces

$ kubectl get pods –namespace=<new namespace>

As you can see the two pods created earlier have been successfully deployed.

As you can see only 2 out of the 3 pods were successfully created but we set the replica set to 3 so what is wrong with the third pod?

$ kubectl get rs –namespace=<namespace>

This isn’t good but still, why?

$ kubectl rs/<name of rs> –namespace=<namespace>

As you can see from above I could not create the third pod because I have exceeded quota limits.

$ kubectl describe quota/compute-quota –namespace=<namespace>

As you can see we have hit our hard limits on memory

This shows the hard quotas set won’t be violated.  However, what if you require those three pods, allocate the additional resources to the cluster or resource pool and want that third pod?

Step 2. Deploying quotas, namespace, deployment within the quota limits set.

apiVersion: v1
kind: Namespace
metadata:
  name: namespace-demo
---
apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: namespace-demo
spec:
  hard:
    requests.cpu: "4"
    requests.memory: 4Gi
    limits.cpu: "4"
    limits.memory: 4Gi
---
apiVersion: v1
kind: ResourceQuota
metadata:
  name: object-quota
  namespace: namespace-demo
spec:
  hard:
    configmaps: "5"
    persistentvolumeclaims: "2"
    replicationcontrollers: "10"
    secrets: "5"
    services: "5"
    services.loadbalancers: "1"

As you can see above I have changed the hard limits to be more than the resources being requested.

As you can see all three pods deployed as expected.

FYI; I could have easily gone into the helloworld-deployment config file and changed the resourced requested to fit within the quotas but more often than not I am asked to increase the quotas not shrink the requested resources 😉

Summary:
Playing around with quotas in a namespace can be tricky as you saw.  It is very easy to stop a deployment in your tracks without proper planning.  That is why in step 1 we made mistakes and quickly troubleshot to discover why all the expected pods did not deploy.  Anyways, I hope y’all found this useful.

One comment

Leave a Reply