K8S-Pod: Resource allocation and QoS
Intro
CPU: Kubernetes divides a single CPU core into 1000 units, each unit being 1m. Normally, we can allocate a container between 100m to 300m CPU, which corresponds to 0.1 to 0.3 CPU cores.
Memory: Kubernetes delivers memory resources in a standard manner. Normally, we can allocate a container between 500Mi to 1000Mi of memory. Since memory consumption can vary greatly, this value can be adjusted as needed.
Explain
$ kubectl explain pods.spec.containers.resources
KIND: Pod
VERSION: v1
RESOURCE: resources <Object>
DESCRIPTION:
Compute Resources required by this container. Cannot be updated. More info:
https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
ResourceRequirements describes the compute resource requirements.
FIELDS:
claims <[]Object>
Claims lists the names of resources, defined in spec.resourceClaims, that
are used by this container.
This is an alpha field and requires enabling the DynamicResourceAllocation
feature gate.
This field is immutable. It can only be set for containers.
limits <map[string]string>
Limits describes the maximum amount of compute resources allowed. More
info:
https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
requests <map[string]string>
Requests describes the minimum amount of compute resources required. If
Requests is omitted for a container, it defaults to Limits if that is
explicitly specified, otherwise to an implementation-defined value.
Requests cannot exceed Limits. More info:
https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
Demo
Let’s create a yaml file that specify the resource allocation for a pod:
apiVersion: v1
kind: Pod
metadata:
name: pod-resources
spec:
containers:
- name: nginx-web
image: nginx-k8s:latest
imagePullPolicy: Never
resources:
requests:
memory: "128Mi"
cpu: "500m"
limits:
memory: "256Mi"
cpu: "1000m"
volumeMounts:
- name: nginx-index
mountPath: /usr/share/nginx/html
volumes:
- name: nginx-index
emptyDir: {}
Apply the yaml file, we can describe the pod, and we will see the limits and requests there:
$ kubectl describe pod pod-resources
Name: pod-resources
Namespace: default
Priority: 0
Service Account: default
Node: kind-worker2/172.21.0.4
Start Time: Fri, 07 Feb 2025 13:29:51 +0000
Labels: <none>
Annotations: <none>
Status: Running
IP: 10.244.1.4
IPs:
IP: 10.244.1.4
Containers:
nginx-web:
Container ID: containerd://b90a95044bcf92857cd13c8c779fe1146af356bc4fa071ccc2a333b0a7ef5119
Image: nginx-k8s:latest
Image ID: docker.io/library/import-2025-02-06@sha256:9f55d994ed03ec97a72061ba366bc139ca77e5f160d79707ee8e5bc82210828a
Port: <none>
Host Port: <none>
State: Running
Started: Fri, 07 Feb 2025 13:29:52 +0000
Ready: True
Restart Count: 0
Limits:
cpu: 1
memory: 256Mi
Requests:
cpu: 500m
memory: 128Mi
Environment: <none>
Mounts:
/usr/share/nginx/html from nginx-index (rw)
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-hmsr7 (ro)
Conditions:
Type Status
PodReadyToStartContainers True
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
nginx-index:
Type: EmptyDir (a temporary directory that shares a pod's lifetime)
Medium:
SizeLimit: <unset>
kube-api-access-hmsr7:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: Burstable
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 18s default-scheduler Successfully assigned default/pod-resources to kind-worker2
Normal Pulled 18s kubelet Container image "nginx-k8s:latest" already present on machine
Normal Created 18s kubelet Created container: nginx-web
Normal Started 18s kubelet Started container nginx-web
QoS
QoS (Quality of Service) is a configuration applied at the Pod level. When Kubernetes creates a Pod, it assigns a QoS class to the Pod, which can be one of the following:
Guaranteed Level:
Every container in the Pod has both CPU and memory
requestsandlimitsset, and the values must be equal.In this case, the Pod has a stable resource guarantee during runtime.
Burstable Level:
At least one container in the Pod has either CPU or memory
requestsandlimitsset, but it does not meet the Guaranteed level requirements.In this case, the Pod has some resource guarantees during runtime, but there may be unexpected resource shortages.
BestEffort Level:
No container has
requestsorlimitsset.This means:
The default resource configuration is used, and the Pod may not run properly later due to resource limitations.
No resource guarantees are applied, and the Pod may not run due to resource contention.

