Learning Center
Kubernetes

Kubernetes Requests and Limits

29 Jan 2025
Hostman Team
Hostman Team

When working with the Kubernetes containerization platform, it is important to control resource usage for cluster objects such as pods. The requests and limits parameters allow you to configure resource consumption limits, such as how many resources a pod can use in a Kubernetes cluster. This article will explore the use of requests and limits in Kubernetes through practical examples.

Prerequisites
Copy link

To work with requests and limits in a Kubernetes cluster, we need:

  1. A Kubernetes cluster (you can create one in the Hostman control panel). For testing purposes, a cluster with two nodes will suffice. The cluster can also be deployed manually by renting the necessary number of cloud or dedicated (physical) servers, setting up the operating system, and installing the required packages.

  2. Lens or kubectl for connecting to and managing your Kubernetes clusters.

Connecting to a Kubernetes Cluster Using Lens
Copy link

  1. First, go to the cluster management page in your Hostman panel. Download the Kubernetes cluster configuration file (the kubeconfig file).

4cb03fea 995a 43c2 A035 870d6505acda.png

  1. Once Lens is installed on your system, launch the program, and from the left menu, go to the Catalog (app) section:

Image9

  1. Select Clusters and click the blue plus button at the bottom right.

Image2

  1. Choose the directory where you downloaded the Kubernetes configuration file by clicking the Sync button at the bottom right.

  2. After this, our cluster will appear in the list of available clusters. Click on the cluster's name to open its dashboard:

Image21

What are Requests and Limits in Kubernetes
Copy link

First, let's understand what requests and limits are in Kubernetes.

Requests are a mechanism in Kubernetes that is responsible for allocating physical resources, such as memory and CPU cores, to the container being launched. In simple terms, requests in Kubernetes are the minimum system requirements for an application to function properly.

Limits are a mechanism in Kubernetes that limits the physical resources (memory and CPU cores) allocated to the container being launched. In other words, limits in Kubernetes are the maximum values for physical resources, ensuring that the launched application cannot consume more resources than specified in the limits. The container can only use resources up to the limit specified in the Limits.

The request and limit mechanisms apply only to objects of type pod and are defined in the pod configuration files, including deployment, StatefulSet, and ReplicaSet files.

Requests are added in the containers block using the resources parameter. In the resources section, you need to add the requests block, which consists of two values: cpu (CPU resource request) and memory (memory resource request). The syntax for requests is as follows:

containers:
  ...
  resources:
    requests:
      cpu: "1.0"
      memory: "150Mi"

In this example, for the container to be launched on a selected node in the cluster, at least one free CPU core and 150 megabytes of memory must be available.

Limits are set in the same way. For example:

containers:
  ...
  resources:
    limits:
      cpu: "2.0"
      memory: "500Mi"

In this example, the container cannot use more than two CPU cores and no more than 500 megabytes of memory.

The units of measurement for requests and limits are as follows:

  • CPU — in millicores (milli-cores)
  • RAM — in bytes

For CPU resources, cores are used. For example, if we need to allocate one physical CPU core to a container, the manifest should specify 1.0. To allocate half a core, specify 0.5. A core can be logically divided into millicores, so you can allocate, for example, 100m, which means one-thousandth of a core (1 full CPU core contains 1000 millicores).

For RAM, we specify values in bytes. You can use numbers with the suffixes E, P, T, G, M, k. For example, if a container needs to be allocated 1 gigabyte of memory, you should specify 1G. In megabytes, it would be 1024M, in kilobytes, it would be 1048576k, and so on.

The requests and limits parameters are optional; however, it is important to note that if both parameters are not set, the container will be able to run on any available node in the cluster regardless of the free resources and will consume as many resources as are physically available on each node. Essentially, the cluster will allocate excess resources. This practice can negatively affect the stability of the entire cluster, as it significantly increases the risk of errors such as OOM (Out of Memory) and OutOfCPU (lack of CPU resources). To prevent these errors, Kubernetes introduced the request and limit mechanisms.

To understand how request and limit choices impact service performance, apply the techniques from Load Balancing in Kubernetes, which covers tracking pods in Kubernetes, balancing via Ingress, external and intra-cluster balancing—ensuring your resource constraints don’t inadvertently throttle critical traffic.

Practical Use of Requests and Limits in Kubernetes
Copy link

Let's look at the practical use of requests and limits. First, we will deploy a deployment file with an Nginx image where we will set only the requests.

In the configuration below, to launch a pod with a container, the node must have at least 100 millicores of CPU (1/1000 of a CPU core) and 150 megabytes of free memory:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-test-deployment
  namespace: ns-for-nginx
  labels:
    app: nginx-test
spec:
  selector:
    matchLabels:
      app: nginx-test
  template:
    metadata:
      labels:
        app: nginx-test
    spec:
      containers:
        - name: nginx-test
          image: nginx:1.25
          resources:
            requests:
              cpu: "100m"
              memory: "150Mi"

Before deploying the deployment, let's create a new namespace named ns-for-nginx:

kubectl create ns ns-for-nginx

After creating the namespace, we will deploy the deployment file using the following command:

kubectl apply -f nginx-test-deployment.yml

Now, let's check if the deployment was successfully created:

kubectl get deployments -A

Image22

Also, check the status of the pod:

kubectl get po -n ns-for-nginx

Image5

The deployment file and the pod have been successfully launched. To ensure that the minimum resource request was set for the Nginx pod, we will use the kubectl describe pod command (where nginx-test-deployment-786d6fcb57-7kddf is the name of the running pod):

kubectl describe pod nginx-test-deployment-786d6fcb57-7kddf -n ns-for-nginx

In the output of this command, you can find the requests block, which contains the previously set minimum requirements for our container to run:

Image10

In the example above, we created a deployment that sets only the minimum required resources for deployment. Now, let's add limits for the container to run with 1 full CPU core and 1 gigabyte of RAM by creating a new deployment file:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-test-deployment-2
  namespace: ns-for-nginx
  labels:
    app: nginx-test2
spec:
  selector:
    matchLabels:
      app: nginx-test2
  template:
    metadata:
      labels:
        app: nginx-test2
    spec:
      containers:
        - name: nginx-test2
          image: nginx:1.25
          resources:
            requests:
              cpu: "100m"
              memory: "150Mi"
            limits:
              cpu: "1.0"
              memory: "1G"

Let's create the deployment in the cluster:

kubectl apply -f nginx-test-deployment2.yml

Using the kubectl describe command, let's verify that both requests and limits have been applied (where nginx-test-deployment-2-6d5df6c95c-brw8n is the name of the pod):

kubectl describe pod nginx-test-deployment-2-6d5df6c95c-brw8n -n ns-for-nginx

Image24

In the screenshot above, both requests and limits have been set for the container. With these quotas, the container will be scheduled on a node with at least 150 megabytes of RAM and 100 milli-CPU. At the same time, the container will not be allowed to consume more than 1 gigabyte of RAM and 1 CPU core.

Using ResourceQuota
Copy link

In addition to manually assigning resources for each container, Kubernetes provides a way to allocate quotas to specific namespaces in the cluster. The ResourceQuota mechanism allows setting resource usage limits within a particular namespace. ResourceQuota is intended to limit resources such as CPU and memory.

The practical use of ResourceQuota looks like this:

  1. Create a new namespace with quota settings:

kubectl create ns ns-for-resource-quota
  1. Create a ResourceQuota object:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: resource-quota-test
  namespace: ns-for-resource-quota
spec:
  hard:
    pods: "2"
    requests.cpu: "0.5"
    requests.memory: "800Mi"
    limits.cpu: "1"
    limits.memory: "1G"

In this example, for all objects created in the ns-for-resource-quota namespace, the following limits will apply:

    • A maximum of 2 pods can be created.
    • The minimum CPU resources required for starting the pods is 0.5 milliCPU.
    • The minimum memory required for starting the pods is 800MB.
    • CPU limits are set to 1 core (no more can be allocated).
    • Memory limits are set to 1GB (no more can be allocated).
  1. Apply the configuration file:

kubectl apply -f test-resource-quota.yaml
  1. Check the properties of the ResourceQuota object:

kubectl get resourcequota resource-quota-test -n ns-for-resource-quota

Image18

As you can see, resource quotas have been set.

Also, verify the output of the kubectl describe ns command:

kubectl describe ns ns-for-resource-quota

Image25

The previously created namespace ns-for-resource-quota will have the corresponding resource quotas.

  1. Example of an Nginx pod with the following configuration:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-with-quota
  namespace: ns-for-resource-quota
  labels:
    app: nginx-with-quota
spec:
  selector:
    matchLabels:
      app: nginx-with-quota
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx-with-quota
    spec:
      containers:
      - name: nginx
        image: nginx:1.22.1
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
          limits:
            cpu: 100m
            memory: 100Mi

Here we define 3 replicas of the Nginx pod to test the quota mechanism. We also set minimum resource requests for the containers and apply limits to ensure the containers don't exceed the defined resources.

  1. Apply the configuration file:
kubectl apply -f nginx-deployment-with-quota.yaml
kubectl get all -n ns-for-resource-quota

Image23

As a result, only two of the three replicas of the pod will be successfully created. The deployment will show an error message indicating that the resource quota for pod creation has been exceeded (in this case, we're trying to create more pods than allowed):

Image4

However, the remaining two Nginx pods were successfully started:

Image6

Conclusion
Copy link

Requests and limits are critical mechanisms in Kubernetes that allow for flexible resource allocation and control within the cluster, preventing unexpected errors in running applications and ensuring the stability of the cluster itself.

We offer an affordable Kubernetes hosting platform, with transparent and scalable pricing for all workloads.