DEV Community

Cover image for Resource quotas to manage namespaces better
Ashok Nagaraj
Ashok Nagaraj

Posted on • Edited on

Resource quotas to manage namespaces better

Resource quotas prevent resource contention issues by rationing available resources (cpu, memory, gpu ..). Without these controls one rogue application can potentially make the cluster crawl.

Resource quotas provide constraints that limit resource consumption.
They can be applied only at the namespace level, which means they can be applied to computing resources and limit the number of objects inside the namespace.

In Kubernetes quotas are implemented with a ResourceQuota object. It can be used to limit/control the following objects:

  • ConfigMaps
  • Persistent Volume Claims (PVCs)
  • Pods
  • Secrets
  • Services

Create quotas
Apply quota to a namespace
❯ kubectl create -f compute-resources.yaml -n test-ns resourcequota/compute-resources created ❯ kubectl create -f object-counts.yaml -n test-ns resourcequota/object-counts created 
Enter fullscreen mode Exit fullscreen mode
Get quota details and status
❯ kubectl get resourcequotas -n test-ns NAME AGE REQUEST LIMIT compute-resources 22s requests.cpu: 0/10, requests.memory: 0/40Gi, requests.nvidia.com/gpu: 0/2 limits.cpu: 0/15, limits.memory: 0/60Gi object-counts 11s configmaps: 1/20, persistentvolumeclaims: 0/20, pods: 0/50, replicationcontrollers: 0/20, secrets: 1/20, services: 0/20, services.loadbalancers: 0/4, services.nodeports: 0/4 
Enter fullscreen mode Exit fullscreen mode
Dele quotas
❯ kubectl delete resourcequota/compute-resources resourcequota/object-counts resourcequota "compute-resources" deleted resourcequota "object-counts" deleted 
Enter fullscreen mode Exit fullscreen mode
Tests
❯ for i in $(seq 1 5); do kubectl create deployment test-dep-${i} --image=alpine --replicas=1 -n test-ns kubectl expose deployment test-dep-${i} --type=NodePort --port=80 -n test-ns done deployment.apps/test-dep-1 created service/test-dep-1 exposed deployment.apps/test-dep-2 created service/test-dep-2 exposed deployment.apps/test-dep-3 created service/test-dep-3 exposed deployment.apps/test-dep-4 created service/test-dep-4 exposed deployment.apps/test-dep-5 created Error from server (Forbidden): services "test-dep-5" is forbidden: exceeded quota: object-counts, requested: services.nodeports=1, used: services.nodeports=4, limited: services.nodeports=4 
Enter fullscreen mode Exit fullscreen mode

Side effect:
Even the pods are also not created as there are no memory, cpu requirements given

❯ kubectl get deployments.apps test-dep-1 -n test-ns NAME READY UP-TO-DATE AVAILABLE AGE test-dep-1 0/1 0 0 5m17s ❯ kubectl get rs test-dep-1-85d7f5dcdb -n test-ns NAME DESIRED CURRENT READY AGE test-dep-1-85d7f5dcdb 1 0 0 5m44s ❯ kubectl describe rs test-dep-1-85d7f5dcdb -n test-ns | tail -2 Warning FailedCreate 4m40s replicaset-controller Error creating: pods "test-dep-1-85d7f5dcdb-jh62r" is forbidden: failed quota: compute-resources: must specify limits.cpu,limits.memory,requests.cpu,requests.memory Warning FailedCreate 118s (x7 over 4m39s) replicaset-controller (combined from similar events): Error creating: pods "test-dep-1-85d7f5dcdb-6679m" is forbidden: failed quota: compute-resources: must specify limits.cpu,limits.memory,requests.cpu,requests.memory 
Enter fullscreen mode Exit fullscreen mode

We add resource limits:

... spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 resources: limits: memory: '1Gi' cpu: '800m' requests: memory: '256Mi' cpu: '100m' 
Enter fullscreen mode Exit fullscreen mode

Rerun the deployments (replicaCount=3)

❯ for i in $(seq 1 5); do sed -e "s/nginx-dep/nginx-dep-${i}/" /tmp/dep.yaml | kubectl apply -f - done deployment.apps/nginx-dep-1 created deployment.apps/nginx-dep-2 created deployment.apps/nginx-dep-3 created deployment.apps/nginx-dep-4 created deployment.apps/nginx-dep-5 created ❯ k get deployments.apps -n test-ns NAME READY UP-TO-DATE AVAILABLE AGE nginx-dep-1 3/3 3 3 102s nginx-dep-2 3/3 3 3 102s nginx-dep-3 3/3 3 3 102s nginx-dep-4 3/3 3 3 101s nginx-dep-5 3/3 3 3 101s ❯ k get resourcequotas -n test-ns NAME AGE REQUEST LIMIT compute-resources 22m requests.cpu: 1500m/10, requests.memory: 3840Mi/40Gi, requests.nvidia.com/gpu: 0/2 limits.cpu: 12/15, limits.memory: 15Gi/60Gi object-counts 22m configmaps: 1/20, persistentvolumeclaims: 0/20, pods: 15/50, replicationcontrollers: 0/20, secrets: 1/20, services: 0/20, services.loadbalancers: 0/4, services.nodeports: 0/4 
Enter fullscreen mode Exit fullscreen mode

Let us push beyond cpu limits

❯ for i in $(seq 6 10); do sed -e "s/nginx-dep/nginx-dep-${i}/" /tmp/dep.yaml | kubectl apply -f - deployment.apps/nginx-dep-6 created deployment.apps/nginx-dep-7 created deployment.apps/nginx-dep-8 created deployment.apps/nginx-dep-9 created deployment.apps/nginx-dep-10 created done ❯ k get rs -n test-ns NAME DESIRED CURRENT READY AGE ... nginx-dep-6-7fbd56f7d8 3 3 3 7m35s nginx-dep-7-7fbd56f7d8 3 0 0 3m51s nginx-dep-8-7fbd56f7d8 3 0 0 3m39s nginx-dep-9-7fbd56f7d8 3 0 0 3m39s 
Enter fullscreen mode Exit fullscreen mode

It creates 6 deployments and stalls for deployment-7 .. 10

❯ kubectl describe rs nginx-dep-7-7fbd56f7d8 -n test-ns | tail -2 Warning FailedCreate 4m14s replicaset-controller Error creating: pods "nginx-dep-7-7fbd56f7d8-bv7hb" is forbidden: exceeded quota: compute-resources, requested: limits.cpu=800m, used: limits.cpu=14400m, limited: limits.cpu=15 Warning FailedCreate 92s (x7 over 4m13s) replicaset-controller (combined from similar events): Error creating: pods "nginx-dep-7-7fbd56f7d8-54shl" is forbidden: exceeded quota: compute-resources, requested: limits.cpu=800m, used: limits.cpu=14400m, limited: limits.cpu=15 
Enter fullscreen mode Exit fullscreen mode

Setting boundary values for cpu and memory

Use the LimitRange resource

References

Top comments (1)

Collapse
 
miguelcort22 profile image
MiguelCort22

Namespaces create virtual clusters within a physical Kubernetes cluster to help users avoid resource naming conflicts and manage capacity, among others. Prayer to separate two people