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 😉
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.