Skip to main content

Command Palette

Search for a command to run...

K8S-Pod: Resource allocation and QoS

Updated
•3 min read•View as Markdown

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 requests and limits set, 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 requests and limits set, 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 requests or limits set.

  • 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.

15 views

More from this blog

Clarence's Blog

56 posts

I share insights on programming, web development, cloud computing, computer networks, and AI, alongside financial knowledge, reading notes, and reflections on business and entrepreneurship.