Meta/SRE/Containers & Kubernetes

How does Kubernetes manage resource limits and requests, and what are the implications for application stability and scheduling?

Meta SRE 3–5 Years Containers & Kubernetes

Kubernetes manages container resource consumption through two primary mechanisms: requests and limits. Resource requests define the minimum amount of CPU and memory a container needs to be scheduled onto a node. The Kubernetes scheduler uses these requests to determine which node has sufficient available resources to host the pod. If a node cannot satisfy a pod’s requests, the pod will not be scheduled there. Requests also serve as a guaranteed baseline; the container runtime ensures the container always has access to at least the requested resources.

Resource Management Principles

Resource limits, on the other hand, specify the maximum amount of CPU and memory a container is allowed to consume. For CPU, exceeding the limit results in throttling, where the container’s processes are slowed down to stay within the allocated CPU quota. For memory, exceeding the limit is more severe: the container will be immediately terminated by the kubelet with an OutOfMemory (OOM) error, and if configured, Kubernetes will attempt to restart it. This distinction is crucial because CPU is a “compressible” resource, while memory is “incompressible”. Requests are critical for efficient scheduling and ensuring baseline performance, while limits are essential for preventing resource starvation for other containers on the same node and maintaining overall node stability.

Best practice

A best practice is to always define both resource requests and limits for all containers in production workloads. Requests should be set to the typical expected resource usage, ensuring the application receives a stable amount of resources. Limits should be set slightly above the requests, reflecting the maximum acceptable resource spike the application might experience without impacting the node. This configuration places the pod in the “Burstable” Quality of Service (QoS) class, allowing it to use more resources than its request if available, but preventing it from consuming uncontrolled amounts. For critical applications, setting requests equal to limits creates a “Guaranteed” QoS class, providing the highest level of resource assurance.

Edge case interviewers probe for

Interviewers often probe for the behavior when limits are exceeded. If a container exceeds its CPU limit, it will be throttled. This means its execution will be paused until its CPU usage falls back within its allocated quota, leading to performance degradation. If a container exceeds its memory limit, the Linux kernel’s OOM killer will terminate the process. This leads to a crash and restart, which can cause service unavailability. Understanding this difference is key to diagnosing resource-related issues: CPU throttling typically means slowness, while memory OOMs mean restarts and potential data loss if not handled gracefully.

Common mistake

A common mistake is either not setting resource requests and limits at all, or setting them incorrectly. Not setting them makes pods “BestEffort,” meaning they get no guaranteed resources and are the first to be terminated under pressure, leading to instability. Setting requests too high can lead to inefficient cluster utilization and higher costs, as nodes may be underutilized but marked as full. Setting limits too low can cause constant throttling or OOMKills, making applications unreliable. Another mistake is failing to differentiate between CPU (measured in millicores) and memory (measured in bytes) and their distinct enforcement mechanisms.

What the interviewer is checking

The interviewer is checking your fundamental understanding of Kubernetes’ resource model and its direct impact on application stability, performance, and cluster efficiency. They want to see if you grasp the interplay between the scheduler, kubelet, and the underlying OS in enforcing these constraints. A strong answer demonstrates not only theoretical knowledge but also practical experience in configuring resources to build resilient and cost-effective containerized applications, a critical skill for an SRE role.

Imagine you’re at a popular restaurant, and you want to ensure you get a good meal without overeating or taking up too much space. Resource requests are like making a reservation for a table and telling the host how many seats you need. This guarantees you a spot, and the host won’t seat you unless there’s enough room. If you ask for a table of four, they reserve space for four, ensuring you have at least that much room to enjoy your meal comfortably.

Resource limits are like the restaurant telling you, “You can order up to five dishes, but no more.” Even if you have more money, they won’t let you exceed that. If you try to order a sixth dish, they’ll simply stop you. For CPU, it’s like they’ll serve your dishes slower if the kitchen is busy, but for memory, if you try to take up more space than your table can physically hold (or eat more than they allow), they’ll politely ask you to leave (terminate your dinner) to make room for other guests. It keeps everyone happy and ensures the restaurant doesn’t get overcrowded or run out of ingredients for other customers.

Why interviewers ask this

Interviewers ask this to gauge your operational maturity and understanding of fundamental Kubernetes concepts critical for production stability. It assesses your ability to prevent and troubleshoot performance issues, ensure fair resource distribution, and manage infrastructure costs effectively. It’s a key SRE responsibility.

What a strong answer signals

A strong answer signals a deep practical understanding of Kubernetes resource management, not just theoretical knowledge. It shows you can design resilient applications, diagnose complex issues related to resource contention, optimize cluster utilization, and make informed decisions about QoS classes. This demonstrates proactive SRE skills.

Common follow-ups

  • How do QoS classes (Guaranteed, Burstable, BestEffort) relate to requests and limits, and what are their practical implications?
  • Describe a scenario where exceeding a CPU limit vs. a memory limit would manifest differently, and how you would diagnose each.
  • How would you determine the optimal resource requests and limits for an application running in production?

Advanced variation

Design an autoscaling strategy for a stateless microservice in Kubernetes that accounts for both CPU and memory pressure, including how HorizontalPodAutoscaler (HPA) and VerticalPodAutoscaler (VPA) might be used together, and their respective trade-offs for scaling pods effectively.

Consider a web application’s backend microservice that periodically performs batch processing tasks, leading to spikes in CPU and memory usage. Initially, the service was deployed without any resource requests or limits. This led to unpredictable behavior: sometimes it would experience OutOfMemory (OOM) errors and restarts, especially when another “noisy neighbor” pod on the same node began consuming excessive resources. Other times, the entire node would become sluggish due to resource contention. The fix involved setting a CPU request of 500m (0.5 CPU cores) and a limit of 1000m (1 CPU core), along with a memory request of 256MiB and a limit of 512MiB. This configuration ensured the service always had enough resources for its baseline operation, prevented it from being starved by other pods, and capped its consumption to avoid destabilizing the entire node during peak load. The service’s stability and performance became predictable, and the node’s overall health improved significantly.

deployment.yaml
# Kubernetes Deployment manifest for a sample microservice
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-backend-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-backend-service
  template:
    metadata:
      labels:
        app: my-backend-service
    spec:
      containers:
      - name: backend-container
        image: myrepo/my-backend:v1.0.0
        resources: # Define resource requests and limits here
          requests: # Guaranteed minimum resources for scheduling
            memory: 256Mi
            cpu: 500m # 500 millicores (0.5 CPU)
          limits: # Hard cap on resource usage
            memory: 512Mi
            cpu: 1000m # 1 CPU core
        ports:
        - containerPort: 8080
Kubernetes Scheduler Worker Node A (Kubelet) My Pod (Container) Requests (Scheduling) Limits (Enforcement)
  1. 1Resource requests guarantee minimum resources for a pod, crucial for scheduling and baseline performance.
  2. 2Resource limits impose a maximum on container consumption, preventing “noisy neighbor” issues and node instability.
  3. 3Exceeding memory limits leads to immediate container termination (OOMKill), while exceeding CPU limits results in throttling.
  4. 4Properly configured requests and limits determine a pod’s Quality of Service (QoS) class: Guaranteed, Burstable, or BestEffort.
  5. 5Accurate resource configuration is fundamental for application stability, efficient cluster utilization, and cost management in Kubernetes.