Mastering Kubernetes Pod Configuration: Defining Resource Requirements
Defining an application's resource requirements using limits and requests
Walkthrough
Create a Pod manifest for a Pod that will consume a lot of CPU resources. The stress image runs a binary that can consume a varying amount of resources. The args instruct stress to attempt to consume two CPU cores, which is how many cores each node in the cluster has.
load.yaml
apiVersion: v1
kind: Pod
metadata:
name: load
spec:
containers:
- name: cpu-load
image: cloudacademydevops/stress
args:
- -cpus
- "2"
Create the Pod. The pod simulates a situation where you notice degraded performance in the cluster. When there are many pods and nodes in the cluster, it is difficult to determine which pod or pods are causing the degradation by inspecting each node and pod individually.
kubectl apply -f load.yaml
List the resource consumption of pods. The load pod is using nearly two full cores (1930milli-cores). Having such an unrestricted pod in your cluster could wreak havoc.
kubectl top pods

The Pod is using almost all the CPU for one of the nodes in the cluster.
kubectl top nodes

Create a similar Pod specification except with CPU and memory resource limits and requests. The resources key is added to specify the limits and requests. The Pod will only be scheduled on a Node with 0.35 CPU cores and 10MiB of memory available. It's important to note that the scheduler doesn't consider the actual resource utilization of the node. Rather, it bases its decision upon the sum of container resource requests on the node. For example, if a container requests all the CPU of a node but is actually 0% CPU, the scheduler would treat the node as not having any CPU available. In the context of this lab, the load Pod is consuming 2 CPUs on a Node but because it didn't make any request for the CPU, its usage doesn't impact following scheduling requests.
load-limited.yaml
apiVersion: v1
kind: Pod
metadata:
name: load-limited
spec:
containers:
- name: cpu-load-limited
image: cloudacademydevops/stress
args:
- -cpus
- "2"
resources:
limits:
cpu: "0.5" # half a core
memory: "20Mi" # 20 mebibytes
requests:
cpu: "0.35" # 35% of a core
memory: "10Mi" # 20 mebibytes
The nodes and output their non-terminated Pods tables to highlight how scheduling decisions are made based on the current workload. Although the Pod is using almost 2 CPUs, the resource table does not allocate any request or limit for the Pod so it does not impact the scheduling decision of the load-limited Pod.
kubectl describe nodes | grep --after-context=5 "Non-terminated Pods"

Create the Pod with the resource constraints.
kubectl apply -f load-limited.yaml
Get the Pods in wide output to display the Node running each Pod.
kubectl get pods -o wide

Wait a minute for the new Pod's metrics to be collected, and then display the Pod resource utilization. Notice the load-limited Pod is using almost half of a CPU core, which is the limit you set. The request is used for making scheduling decisions but the limit impacts the actual utilization. Using requests and limits for CPU and memory can prevent performance issues, and allow the scheduler to make the best use of the cluster's resources.
kubectl top pods

load.yaml - Updated #1
The value of 1.7 is chosen because there may not be a Node with a full 2 CPUs available considering some system Pods also make requests in addition to the Pods we create.
apiVersion: v1
kind: Pod
metadata:
name: load
spec:
containers:
- name: cpu-load
image: cloudacademydevops/stress
args:
- -cpus
- "2"
resources:
requests:
cpu: "1.7"
Apply the new Pod manifest
kubectl apply --force -f load.yaml
Confirm the Pods are running on separate Node
kubectl get pods -o wide

Last updated