Chapter 23 of 47 · Resource management, part 2

Namespaces, ResourceQuotas and LimitRanges

Requests and limits are set by whoever writes the Deployment. But what if a team forgets them, or asks for 50 CPUs? Cluster admins set rules per namespace: a ResourceQuota caps the namespace's total, and a LimitRange sets defaults and bounds for each container.

Namespaces in two minutes

A namespace is a folder inside the cluster. Names only have to be unique within one, and many rules, quotas and permissions included, apply per namespace.

One cluster, several namespaces cluster defaultwhere you have worked so far team-aposts, comments …quota: 2 CPU, 4Gi team-bpayments …quota: 8 CPU, 16Gi
$ kubectl create namespace team-a
$ kubectl apply -f all.yaml -n team-a        # deploy into it
$ kubectl get pods -n team-a                 # look inside it
$ kubectl get pods -A                        # every namespace
$ kubectl config set-context --current --namespace=team-a   # make it your default

Services in another namespace are reached as http://posts-srv.team-a (chapter 11). kube-system holds Kubernetes' own components; leave it alone.

Three levels of rules

ObjectApplies toAnswersWritten by
resources (chapter 22)One container"This container needs 250m and may use 500m"App developer
LimitRangeEach container (or Pod) in a namespace"If you forget, you get 250m. Nobody may ask for more than 2 CPU."Admin
ResourceQuotaThe namespace's total"All of team-a together: at most 2 CPU, 4Gi and 10 Pods."Admin

ResourceQuota

A budget for the whole namespace. Every new object is checked against it; anything that would go over is refused at creation, not killed later.

apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-quota
  namespace: team-a
spec:
  hard:
    requests.cpu: "2"
    requests.memory: 4Gi
    limits.cpu: "4"
    limits.memory: 8Gi
    pods: "10"
    services: "5"
    configmaps: "10"
    secrets: "10"
    services.loadbalancers: "1"
    persistentvolumeclaims: "4"
    requests.storage: 20Gi

Compute

Caps the sum of requests and limits of all Pods in the namespace. Important side effect: once a quota covers requests.cpu, every new Pod must declare a CPU request, or it is rejected. A LimitRange with defaults fixes that.

Deployments do not fail loudly. When a quota blocks a Pod created by a Deployment, kubectl apply still says "created". The ReplicaSet just cannot create Pods. Look with kubectl describe rs or kubectl get events:
Warning  FailedCreate  replicaset/posts-depl-7d9f8  Error creating: pods "posts-depl-7d9f8-x2k" is forbidden:
exceeded quota: team-quota, requested: requests.cpu=500m, used: requests.cpu=1800m, limited: requests.cpu=2

LimitRange

Rules for each container in the namespace: fill in what is missing, and refuse what is out of bounds.

apiVersion: v1
kind: LimitRange
metadata:
  name: container-defaults
  namespace: team-a
spec:
  limits:
    - type: Container
      defaultRequest:
        cpu: 250m
        memory: 256Mi
      default:
        cpu: 500m
        memory: 512Mi
      min:
        cpu: 50m
        memory: 64Mi
      max:
        cpu: "2"
        memory: 2Gi

defaultRequest

A container with no request gets this one, filled in automatically when the Pod is created. Your YAML stays unchanged; kubectl get pod -o yaml shows the injected values.

Try them together

Namespace team-a has a quota of 2 CPU, 4Gi and 4 Pods. First add Pods with "not set" requests and the LimitRange off, then turn it on:

Checking with kubectl

$ kubectl describe resourcequota team-quota -n team-a
Name:            team-quota
Namespace:       team-a
Resource         Used   Hard
--------         ----   ----
pods             3      10
requests.cpu     1500m  2
requests.memory  2Gi    4Gi
limits.cpu       3      4
limits.memory    4Gi    8Gi
services         2      5

Used versus allowed: the first place to look when Pods will not appear.

Recap

Quick check

You apply a Deployment with 3 replicas in team-a. kubectl get deploy shows READY 1/3 and only one Pod exists, not even Pending ones. What do you check?
Show answer

The quota. Pods that would exceed it are never created, so they do not even appear as Pending. kubectl describe resourcequota -n team-a and kubectl get events -n team-a will show "exceeded quota".

ResourceQuota and LimitRange: common questions

What is the difference between ResourceQuota and LimitRange?

A ResourceQuota caps the total resources and objects in a namespace. A LimitRange sets default requests and limits, and minimum and maximum values, for each container.