> For the complete documentation index, see [llms.txt](https://bagus-cahyono.gitbook.io/programming-notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bagus-cahyono.gitbook.io/programming-notes/cka/06_limit_range.md).

# Limit Range

By default, containers run with unbounded compute resources on a Kubernetes cluster.

LimitRange is a Kubernetes resource that enforces resource constraints (CPU, memory) at the namespace level. It ensures that every pod/container in the namespace has a default resource request and limit. Containers cannot exceed the specified limits. Using this will prevents excessive resource consumption by a single pod/container.

## Define LimitRange

Lets create new file `limitrange.yaml` and put below definition there. This configuration will limit CPU and Memory in container level.

```yaml
apiVersion: v1
kind: LimitRange
metadata:
  name: resource-limits
  namespace: limited
spec:
  limits:
  - type: Container
    defaultRequest:
      cpu: "100m"
      memory: "64Mi"
    default:
      cpu: "100m"
      memory: "64Mi"
    max:
      cpu: "250m"
      memory: "128Mi"
```

* `defaultRequest`: Define the default request for each containers.
  * `cpu: "100m"`: Set container's `resource.request.cpu` to `100m` if not explicitly specified.
  * `memory: "64Mi"`: Set container's `resource.request.memory` to `64Mi` if not explicitly specified.
* `default`: Define the default limit for each containers.
  * `cpu: "100m"`: Set container's `resource.limits.cpu` to `100m` if not explicitly specified.
  * `memory: "64Mi"`: Set container's `resource.limits.memory` to `64Mi` if not explicitly specified.
* `max`: Define the default request for each containers. The limits for configured in each containers cannot exceed this value.

## Apply and Validate

Let's apply the configuration file using `kubectl apply` command.

```bash
➜ kubectl apply -f limitrange.yaml 
limitrange/resource-limits created
```

We can validate it using `kubectl describe limitranges` command with specific namespace.

```bash
➜ kubectl -n limited describe limitranges 
Name:       resource-limits
Namespace:  limited

Type        Resource  Min  Max    
----        --------  ---  ---    
Container   cpu       -    250m   
Container   memory    -    128Mi  

Default Request  Default Limit  Max Limit/Request Ratio
---------------  -------------  -----------------------
100m             100m           -
64Mi             64Mi           -
```

## Test LimitRange

To test if our configuration work as expected we can run pod without any resource specified.

```bash
➜ kubectl -n limited run nginx --image=nginx          
pod/nginx created
```

Lets get the pod details using `kubectl describe` command.

```bash
➜ kubectl -n limited describe pod nginx  
Name:             nginx
Namespace:        limited
Priority:         0
Service Account:  default
Node:             minikube/192.168.49.2
Start Time:       Wed, 05 Feb 2025 17:49:07 +0700
Labels:           run=nginx
Annotations:      kubernetes.io/limit-ranger: LimitRanger plugin set: cpu, memory request for container nginx; cpu, memory limit for container nginx
Status:           Pending
IP:               
IPs:              <none>
Containers:
  nginx:
    Container ID:   
    Image:          nginx
    Image ID:       
    Port:           <none>
    Host Port:      <none>
    State:          Waiting
      Reason:       ContainerCreating
    Ready:          False
    Restart Count:  0
    Limits:
      cpu:     100m
      memory:  64Mi
    Requests:
      cpu:        100m
      memory:     64Mi
    Environment:  <none>
...
```

As you can see above if we don't specify the `resource.request` and `resource.limits` it will set to default that we just configure.

Now let's try to create a new pod that will exceed the `max` configuration of our LimitRange. Create new file named `limitrange-pod.yaml` and put below definition there.

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: over-limit-pod
  namespace: limited
spec:
  containers:
  - name: over-limit-container
    image: nginx
    resources:
      limits:
        cpu: "1"  # Exceeds the 250m limit
        memory: "512Mi"  # Exceeds the 128Mi limit
```

Lets apply and see what happens.

```bash
➜ kubectl apply -f limitrange-pod.yaml

Error from server (Forbidden): error when creating "limitrange-pod.yaml": pods "over-limit-pod" is forbidden: [maximum cpu usage per Container is 250m, but limit is 1, maximum memory usage per Container is 128Mi, but limit is 512Mi]
```

As you can see we got error creating pods `"over-limit-pod"` is forbidden because the CPU and Memory limits exceed the LimitRange.

## References

* <https://kubernetes.io/docs/concepts/policy/limit-range/>
* <https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/>
