In Kubernetes, we can specify CPU and memory requests and limits for each containers using the resources field in your Deployment or Pod specification.
Why is it important?
If we don't specify a CPU and Memory resource limit, The Container has no upper bound on the resources it can use. The Container could use all of the CPU and Memory resources available on the Node where it is running.
If The Container is running in a namespace that has a default CPU or Memory limit. The Container is automatically assigned the default limit. Cluster administrators can use a LimitRange to specify a default value for the CPU and Memory limit.
Imagine that we have multiple services, and one of our service currently have DDoS attack. If we are not limiting the resources that service's pods will consume all available resource and disrupting other services that we have on that node.
Enabling Metrics Server
First we need to enable minikube metric server by using this command.
➜ minikube addons enable metrics-server
💡 metrics-server is an addon maintained by Kubernetes. For any concerns contact minikube on GitHub.
You can view the list of minikube maintainers at: https://github.com/kubernetes/minikube/blob/master/OWNERS
â–ª Using image registry.k8s.io/metrics-server/metrics-server:v0.7.2
🌟 The 'metrics-server' addon is enabled
Wait few second until the metrics data populated. We can check the pod resource used by using this command.
➜ kubectl top pod
NAME CPU(cores) MEMORY(bytes)
simple-go-685974475c-7484x 1m 2Mi
simple-go-685974475c-87ccm 1m 2Mi
simple-go-685974475c-d2kdv 1m 2Mi
Specify Resources Limit
You define resource requests and limits in the container spec within a Pod or Deployment. Let's open our deployment file deployment.yaml. Add resources section in containers server like this.
Kubernetes guarantees this amount of resources to the container.
Used for Pod scheduling (i.e., to decide which node can run the Pod).
resources.limits
Defines the maximum resources the container can use.
If the container tries to exceed these limits:
Memory: The container is terminated with an OutOfMemory (OOM) error.
CPU: The container is throttled (limited to the specified CPU).
Apply and Validate
Let's apply our deployment again using kubectl apply -f deployment.yaml. New sets of pods should be running. An then we can validate if our pods has correct limit by using describe command.
➜ kubectl describe pods simple-go-685974475c-7484x
Name: simple-go-685974475c-7484x
Namespace: default
Priority: 0
Service Account: default
Node: minikube/192.168.49.2
Start Time: Mon, 27 Jan 2025 21:41:50 +0700
Labels: app=simple-go
pod-template-hash=685974475c
Annotations: <none>
Status: Running
IP: 10.244.0.35
IPs:
IP: 10.244.0.35
Controlled By: ReplicaSet/simple-go-685974475c
Containers:
server:
Container ID: docker://abcf9833e078e1af850ffd2e26ffcc32edd42b48ba653fe0e9c0861b769a9f6b
Image: simple-go:latest
Image ID: docker://sha256:534128017b433fa09e637cb2d943f7057a809c244632390bc75378a32dc3b12e
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Mon, 27 Jan 2025 21:41:52 +0700
Ready: True
Restart Count: 0
Limits:
cpu: 30m
memory: 64Mi
Requests:
cpu: 10m
memory: 16Mi
Environment:
DEFAULT_MESSAGE: <set to the key 'DEFAULT_MESSAGE' of config map 'simple-go-config'> Optional: false
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-rznfx (ro)
Conditions:
Type Status
PodReadyToStartContainers True
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-rznfx:
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: <none>
We can see above that resources request and limit are properly set. Next we will learn about horizontal pod scaling (HPA) so our service can spin up new pods if we got increasing traffic that existing pod cannot handle.
In Kubernetes version v1.32 (still in alpha) we can specify resource allocation in Pod level instead of Container. This is very useful if we have multiple containers, so we only need to specify resource allocation once on Pod level. You can read more about it .