By default, pods run with unbounded CPU and memory limits. This means that any pod in the system will be able to consume as much CPU and memory as is on the node that executes the pod.
This example demonstrates how limits can be applied to a Kubernetes namespace to control min/max resource limits per pod. In addition, this example demonstrates how you can apply default resource limits to pods in the absence of an end-user specified value.
You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using Minikube, or you can use one of these Kubernetes playgrounds:
This example will work in a custom namespace to demonstrate the concepts involved.
Let’s create a new namespace called limit-example:
$ kubectl create namespace limit-example
namespace "limit-example" created
Note that kubectl
commands will print the type and name of the resource created or mutated, which can then be used in subsequent commands:
$ kubectl get namespaces
NAME STATUS AGE
default Active 51s
limit-example Active 45s
Let’s create a simple limit in our namespace.
$ kubectl create -f https://k8s.io/docs/tasks/configure-pod-container/limits.yaml --namespace=limit-example
limitrange "mylimits" created
Let’s describe the limits that were imposed in the namespace.
$ kubectl describe limits mylimits --namespace=limit-example
Name: mylimits
Namespace: limit-example
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Pod cpu 200m 2 - - -
Pod memory 6Mi 1Gi - - -
Container cpu 100m 2 200m 300m -
Container memory 3Mi 1Gi 100Mi 200Mi -
In this scenario, the following limits were specified:
limits.yaml
(300m CPU and 200Mi memory).limits.yaml
(200m CPU and 100Mi memory).The limits enumerated in a namespace are only enforced when a pod is created or updated in the cluster. If you change the limits to a different value range, it does not affect pods that were previously created in a namespace.
If a resource (CPU or memory) is being restricted by a limit, the user will get an error at time of creation explaining why.
Let’s first spin up a Deployment that creates a single container Pod to demonstrate how default values are applied to each pod.
$ kubectl run nginx --image=nginx --replicas=1 --namespace=limit-example
deployment "nginx" created
Note that kubectl run
creates a Deployment named “nginx” on Kubernetes cluster >= v1.2. If you are running older versions, it creates replication controllers instead.
If you want to obtain the old behavior, use --generator=run/v1
to create replication controllers. See kubectl run
for more details.
The Deployment manages 1 replica of single container Pod. Let’s take a look at the Pod it manages. First, find the name of the Pod:
$ kubectl get pods --namespace=limit-example
NAME READY STATUS RESTARTS AGE
nginx-2040093540-s8vzu 1/1 Running 0 11s
Let’s print this Pod with yaml output format (using -o yaml
flag), and then grep
the resources
field. Note that your pod name will be different.
$ kubectl get pods nginx-2040093540-s8vzu --namespace=limit-example -o yaml | grep resources -C 8
resourceVersion: "57"
selfLink: /api/v1/namespaces/limit-example/pods/nginx-2040093540-ivimu
uid: 67b20741-f53b-11e5-b066-64510658e388
spec:
containers:
- image: nginx
imagePullPolicy: Always
name: nginx
resources:
limits:
cpu: 300m
memory: 200Mi
requests:
cpu: 200m
memory: 100Mi
terminationMessagePath: /dev/termination-log
volumeMounts:
Note that our nginx container has picked up the namespace default CPU and memory resource limits and requests.
Let’s create a pod that exceeds our allowed limits by having it have a container that requests 3 CPU cores.
$ kubectl create -f https://k8s.io/docs/tasks/configure-pod-container/invalid-pod.yaml --namespace=limit-example
Error from server: error when creating "http://k8s.io/docs/tasks/configure-pod-container/invalid-pod.yaml": Pod "invalid-pod" is forbidden: [Maximum cpu usage per Pod is 2, but limit is 3., Maximum cpu usage per Container is 2, but limit is 3.]
Let’s create a pod that falls within the allowed limit boundaries.
$ kubectl create -f https://k8s.io/docs/tasks/configure-pod-container/valid-pod.yaml --namespace=limit-example
pod "valid-pod" created
Now look at the Pod’s resources field:
$ kubectl get pods valid-pod --namespace=limit-example -o yaml | grep -C 6 resources
uid: 3b1bfd7a-f53c-11e5-b066-64510658e388
spec:
containers:
- image: gcr.io/google_containers/serve_hostname
imagePullPolicy: Always
name: kubernetes-serve-hostname
resources:
limits:
cpu: "1"
memory: 512Mi
requests:
cpu: "1"
memory: 512Mi
Note that this pod specifies explicit resource limits and requests so it did not pick up the namespace default values.
Note: The limits for CPU resource are enforced in the default Kubernetes setup on the physical node that runs the container unless the administrator deploys the kubelet with the following flag:
$ kubelet --help
Usage of kubelet
....
--cpu-cfs-quota[=true]: Enable CPU CFS quota enforcement for containers that specify CPU limits
$ kubelet --cpu-cfs-quota=false ...
To remove the resources used by this example, you can just delete the limit-example namespace.
$ kubectl delete namespace limit-example
namespace "limit-example" deleted
$ kubectl get namespaces
NAME STATUS AGE
default Active 12m
Users may want to impose restrictions on the amount of resources a single pod in the system may consume for a variety of reasons.
For example:
Cluster operators that want to restrict the amount of resources a single container or pod may consume are able to define allowable ranges per Kubernetes namespace. In the absence of any explicit assignments, the Kubernetes system is able to apply default resource limits and requests if desired in order to constrain the amount of resource a pod consumes on a node.