A Container in a Pod can be assigned memory and CPU request and limit. Request is the minimum amount of memory/CPU that Kubernetes will give to the container. Limit is the maximum amount of memory/CPU that a container will be allowed to use. The memory/CPU request/limit for the Pod is the sum of the memory/CPU requests/limits for all the Containers in the Pod. Request defaults to limit if not specified. Default value of the limit is the node capacity.
A Pod can be scheduled on a node if the Pod’s memory and CPU request can be met. Memory and CPU limits are not taken into consideration for scheduling.
Pod can continue to operate on the node if Containers in the Pod does not exceed the memory request. If Containers in the Pod exceeds the memory request then they become target of eviction whenever the node runs out of memory. If Containers in the Pod exceeds the memory limit then they are terminated. If the Pod can be restarted, then kubelet will restart it, just like any other type of runtime failure. A Container might or might not be allowed to exceed its CPU limit for extended periods of time. However, it will not be killed for excessive usage.
By default, a container in a pod is not allocated any requests or limits. This can be verified using the previously started pod:
$ kubectl get pod webserver -o jsonpath={.spec.containers[].resources}
We can limit the CPU and Memory usage of a container.
Lets create the nginx Pod with CPU and Memory limits. Create a manifest file resourcelimit.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
name: nginx
spec:
containers:
- image: nginx
name: nginx
resources:
limits:
cpu: 100m
memory: 123Mi
ports:
- containerPort: 80
kubectl apply -f resourcelimit.yaml
Resulting container will be allowed to use 100 millicores and 123 mebibyte (~128
Megabytes)
kubectl get pod nginx -o jsonpath={.spec.containers[].resources}
One CPU core is equivalent to 1000m
(one thousand millicpu or one thousand millicores)
CPU is always expressed as an absolute quantity, never as a relative quantity; 0.1 is the same amount of CPU
on a single-core, dual-core, or 48-core machine
You can express memory as a plain integer or as a fixed-point integer using one of these suffixes: E, P, T, G, M, K
. You can also use the power-of-two equivalents: Ei, Pi, Ti, Gi, Mi, Ki
. For example, the following represent roughly the same value:
128974848, 129e6, 129M, 123Mi
1 Megabyte (MB) = (1000)^2 bytes = 1000000 bytes.
1 Mebibyte (MiB) = (1024)^2 bytes = 1048576 bytes.
We can request a specific amount of CPU and Memory when the container starts up.
Suppose if a java application need at least 128MB
of memory during startup , we can use resource request in Pod spec.
This will help the scheduler to select a node with enough memory.
Request also can be made of CPU
as well.
Lets modify the Pod
spec and add request
in the above created file.
apiVersion: v1
kind: Pod
metadata:
labels:
name: nginx
spec:
containers:
- image: nginx
name: nginx
resources:
requests:
cpu: 100m
memory: 123Mi
limits:
cpu: 200m
memory: 356Mi
ports:
- containerPort: 80
kubectl apply -f resourcelimit.yaml
kubectl get pod nginx -o jsonpath={.spec.containers[].resources}
Kubernetes opportunistically scavenges the difference between request and limit if they are not used by the Containers. This allows Kubernetes to oversubscribe nodes, which increases utilization, while at the same time maintaining resource guarantees for the containers that need guarantees.
Kubernetes assigns one of the QoS classes to the Pod:
Guaranteed
Burstable
BestEffort
QoS class is used by Kubernetes for scheduling and evicting Pods.
When every Container in a Pod is given a memory and CPU limit, and optionally non-zero request, and they exactly match, then a Pod is scheduled with Guaranteed QoS. This is the highest priority.
A Pod is given Burstable QoS class if the Pod does not meet the Guaranteed QoS and at least one Container has a memory or CPU request. This is intermediate priority.
When no memory and CPU request or limit is assigned to any Container in the Pod, then a Pod is scheduled with BestEffort QoS. This the lowest and the default priority.
Pods that need to stay up can request Guaranteed QoS. Pods with less stringent requirement can use a weaker or no QoS.
kubectl get pod nginx -o jsonpath={.status.qosClass}
You can visit below URLs to understand storage and network limits.