Skip to content

Kubernetes Level 01 Day 04: Controlling Resource Usage with Requests and Limits

This document explains how to define CPU and memory constraints for a Kubernetes Pod in order to control resource consumption and prevent one workload from affecting others in the cluster. The objective was to create a Pod running the httpd:latest image while enforcing specific CPU and memory requests and limits.

The required configuration is:

  • Pod Name: httpd-pod
  • Container Name: httpd-container
  • Image: httpd:latest
  • Memory Request: 15Mi
  • CPU Request: 100m
  • Memory Limit: 20Mi
  • CPU Limit: 100m

This task introduces the concept of resource guarantees and enforcement inside Kubernetes.






Why Resource Limits Matter Before Writing YAML

In a shared Kubernetes cluster, multiple Pods run on the same worker nodes. Each node has finite CPU and memory. If workloads are not controlled, one container may consume excessive memory or CPU, affecting other applications. This situation is commonly referred to as a noisy neighbor problem.

Kubernetes prevents this by using:

  • Requests: Used by the scheduler to decide where a Pod can run
  • Limits: Enforced by the container runtime to cap usage

Without requests and limits, scheduling decisions are less precise and runtime enforcement is not applied.




Step 1: Create the Pod Manifest with Resource Definitions

Create a YAML file named pod.yaml.

vi pod.yaml

Insert the following configuration.

apiVersion: v1
kind: Pod
metadata:
  name: httpd-pod
spec:
  containers:
  - name: httpd-container
    image: httpd:latest
    resources:
      requests:
        memory: "15Mi"
        cpu: "100m"
      limits:
        memory: "20Mi"
        cpu: "100m"



Understanding the resources Section

Under the container specification, the resources block defines how Kubernetes should treat this workload.

Requests

Requests represent the minimum resources the container is expected to need.

  • Memory request of 15Mi means the scheduler will only place the Pod on a node that has at least 15Mi of free allocatable memory.
  • CPU request of 100m means 100 millicores, which equals 0.1 CPU core.

The scheduler uses these values to make placement decisions.

Limits

Limits define the maximum amount of resources the container is allowed to consume.

  • Memory limit of 20Mi means if the container attempts to use more than 20Mi, it will be terminated with an Out Of Memory (OOM) event.
  • CPU limit of 100m means the container cannot exceed 0.1 CPU core. If it attempts to use more, it will be throttled.

Requests influence scheduling. Limits influence runtime enforcement.




Step 2: Apply the Configuration

Create the Pod in the cluster.

kubectl apply -f pod.yaml

Expected output:

pod/httpd-pod created

Kubernetes now stores the desired state in etcd, and the scheduler evaluates node availability based on the defined requests.




Step 3: Verify Resource Configuration and Status

Check Pod status:

kubectl get pods

Wait until the status becomes Running.

To confirm resource values were applied correctly:

kubectl describe pod httpd-pod

Inside the Containers section, verify:

Limits:
  cpu:     100m
  memory:  20Mi
Requests:
  cpu:     100m
  memory:  15Mi

To inspect using structured output:

kubectl get pod httpd-pod -o jsonpath='{.spec.containers[0].resources}'



Monitoring Resource Consumption

If metrics-server is installed, view live usage:

kubectl top pod httpd-pod

This displays current CPU and memory consumption, allowing comparison against limits.




What Happens Internally When Limits Are Reached

CPU limits are enforced using Linux control groups (cgroups). When CPU usage exceeds the defined limit, the kernel throttles execution time. The container continues running but cannot consume more CPU cycles than allowed.

Memory limits are also enforced by cgroups. If the container attempts to allocate memory beyond its limit, the kernel triggers an Out Of Memory kill event. Kubernetes marks the Pod as OOMKilled and restarts the container depending on restart policy.

You can inspect events with:

kubectl describe pod httpd-pod

Look for OOMKilled under container state if the memory limit is exceeded.




Quality of Service (QoS) Classes

Kubernetes assigns each Pod a QoS class based on requests and limits.

  • Guaranteed: Requests equal limits for all containers
  • Burstable: Requests defined but not equal to limits
  • BestEffort: No requests or limits defined

In this configuration, CPU request equals CPU limit, but memory request is less than memory limit. Therefore, the Pod receives the Burstable QoS class.

Check QoS class:

kubectl get pod httpd-pod -o jsonpath='{.status.qosClass}'

QoS affects eviction priority during node pressure situations.




Demonstrating Scheduling Behavior

To inspect node allocatable resources:

kubectl describe node <node-name>

Under the Allocatable section, you can observe total CPU and memory available for scheduling. Requests subtract from this allocatable pool when Pods are scheduled.




Updating Resource Limits

If changes are needed, edit the Pod.

kubectl edit pod httpd-pod

Standalone Pods cannot update resource fields without recreation. In real environments, resource adjustments are typically managed through Deployments instead of direct Pod definitions.




Cleanup

To remove the Pod:

kubectl delete pod httpd-pod



Final State After Completion

At the end of this task:

  • The Pod httpd-pod is running
  • CPU request and limit are set to 100m
  • Memory request is 15Mi
  • Memory limit is 20Mi
  • The scheduler used requests for placement
  • The runtime enforces limits via cgroups

This task establishes an essential principle in Kubernetes operations: defining resource boundaries is necessary to maintain predictable, stable, and fair cluster behavior.