Namespace resource policy in Kubernetes keeps CPU and memory expectations close to the workloads that enter the namespace. A LimitRange supplies default requests and limits for Pods that omit them, and it rejects objects that sit outside the allowed bounds.
LimitRange admission runs when an object is created or updated in the namespace. Defaults are injected before constraint checks, so a Pod with no resource block can receive policy values, while a Pod with limits above the maximum is refused by the API server.
Apply the policy before tenant workloads are created, because existing Pods are not rewritten just because a namespace policy changes. Choose CPU and memory values from workload measurements and platform policy, then use a server-side dry run to test the rejection path before handoff.
Steps to configure a Kubernetes LimitRange:
- Create the namespace that will receive the policy.
$ kubectl create namespace team-a namespace/team-a created
Use an existing namespace when the tenant namespace already exists. A LimitRange affects new and updated API objects in that namespace, not Pods that were already admitted.
Related: How to create a Kubernetes namespace
- Save the container LimitRange manifest.
- team-a-limits.yaml
apiVersion: v1 kind: LimitRange metadata: name: team-a-container-defaults spec: limits: - type: Container default: cpu: 500m memory: 256Mi defaultRequest: cpu: 100m memory: 128Mi min: cpu: 50m memory: 64Mi max: cpu: "1" memory: 512Mi
defaultRequest values become missing container requests, and default values become missing container limits. min and max values bound accepted container resource settings.
- Apply the LimitRange to the namespace.
$ kubectl apply -f team-a-limits.yaml --namespace team-a limitrange/team-a-container-defaults created
- Inspect the saved LimitRange policy.
$ kubectl describe limitrange team-a-container-defaults --namespace team-a Name: team-a-container-defaults Namespace: team-a Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio ---- -------- --- --- --------------- ------------- ----------------------- Container cpu 50m 1 100m 500m - Container memory 64Mi 512Mi 128Mi 256Mi -
- Create a Pod without explicit resource requests or limits.
$ kubectl run defaulted --image=nginx --restart=Never --namespace team-a pod/defaulted created
The Pod does not need to reach Running for this admission check. The API server stores the resource fields before the kubelet pulls the image.
- Check the admitted Pod resources.
$ kubectl get pod defaulted -n team-a --output=jsonpath='{.spec.containers[0].resources}' {"limits":{"cpu":"500m","memory":"256Mi"},"requests":{"cpu":"100m","memory":"128Mi"}}The output shows the default request and limit values injected into the container specification.
- Save a Pod manifest that exceeds the CPU maximum.
- too-large-pod.yaml
apiVersion: v1 kind: Pod metadata: name: too-large spec: containers: - name: too-large image: nginx resources: requests: cpu: 100m memory: 128Mi limits: cpu: "2" memory: 256Mi
- Run a server-side dry run for the over-limit Pod.
$ kubectl apply --dry-run=server -f too-large-pod.yaml --namespace team-a Error from server (Forbidden): error when creating "too-large-pod.yaml": pods "too-large" is forbidden: maximum cpu usage per Container is 1, but limit is 2
--dry-run=server sends the object through API validation and admission without saving it.
- Remove the temporary verification Pod.
$ kubectl delete pod defaulted --namespace team-a --ignore-not-found pod "defaulted" deleted from team-a namespace
- Delete the over-limit test manifest if it was created only for verification.
$ rm too-large-pod.yaml
Keep team-a-limits.yaml in source control or the platform configuration repo so the namespace policy can be reviewed and reapplied.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.