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
- Check:
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
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
Dele quotas
❯ kubectl delete resourcequota/compute-resources resourcequota/object-counts resourcequota "compute-resources" deleted resourcequota "object-counts" deleted
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
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
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'
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
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
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
Setting boundary values for cpu and memory
Use the LimitRange
resource
Top comments (1)
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