Kubernetes uses Quality of Service (QoS) classes to decide pod eviction under resource pressure. Assigning correct requests and limits controls reliability and node stability. You can tune pods as Guaranteed, Burstable, or BestEffort by defining CPU and memory constraints in the Pod spec.
TL;DR
- Pod QoS classes derive from requests and limits on CPU and memory.
- Guaranteed pods must set equal CPU and memory request and limit.
- Burstable pods set requests lower than limits; they gain priority under pressure.
- BestEffort pods omit requests and limits and suffer first eviction.
- Node eviction and OOM killer remove pods in BestEffort → Burstable → Guaranteed order.
- Monitor QoS via kubectl describe pod and metric-server metrics.
Pod QoS Classes Explained
When you create a pod, kubelet inspects resource requests and limits on containers. It assigns a QoS class among Guaranteed, Burstable, BestEffort. Kubernetes uses that class to rank pods during eviction or out-of-memory (OOM) events. This behaviour helps maintain node stability and ensures critical workloads survive resource contention.
Guaranteed Pod QoS Classes
A pod qualifies as Guaranteed when every container sets identical CPU and memory values for resources.requests
and resources.limits
. Kubernetes reserves the exact resources requested on the node. The pod never shares or overcommits those resources with other pods. This yields the highest eviction priority (lowest eviction risk).
apiVersion: v1
kind: Pod
metadata:
name: guaranteed-pod
spec:
containers:
- name: app
image: nginx:latest
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "500m"
memory: "512Mi"
This definition ensures the pod stays in the Guaranteed class.
Burstable Pod QoS Classes
If a container sets a request lower than its limit for any resource, the pod moves into Burstable. Kubernetes reserves the request amount but allows the pod to burst up to the limit when node capacity permits. Burstable pods have moderate eviction priority.
apiVersion: v1
kind: Pod
metadata:
name: burstable-pod
spec:
containers:
- name: app
image: nginx:latest
resources:
requests:
cpu: "200m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
This pod reserves 200m CPU and 256Mi memory but may use up to 500m CPU and 512Mi memory if available.
BestEffort Pod QoS Classes
When a pod omits both requests
and limits
for CPU and memory across all containers, it joins the BestEffort class. Kubernetes applies no reservation. BestEffort pods face eviction first under pressure. They share node resources without guarantee.
apiVersion: v1
kind: Pod
metadata:
name: besteffort-pod
spec:
containers:
- name: app
image: nginx:latest
Use BestEffort for non-critical batch jobs or testing. Avoid it for production services.
Pod QoS Classes Assignment Rules
Kubelet calculates QoS class by scanning each container’s requests
and limits
fields. It applies this logic in priority order:
- Guaranteed: For every resource,
requests == limits
. - Burstable: If any
requests != limits
but at least onerequest
is set. - BestEffort: If no
requests
orlimits
are set.
This assignment persists until you update the pod spec or restart the container.
Eviction and OOM Behavior for Pod QoS Classes
Eviction triggers when node resources exceed available capacity. Kubernetes orders eviction by QoS class: BestEffort pods exit first, followed by Burstable, then Guaranteed. Within the same class, kubelet evicts the pod consuming the most resources relative to its request.
Out-of-Memory (OOM) events also respect QoS. The kernel OOM killer dispatches signals to processes in pods with the lowest QoS ranking first.
Use Cases for Pod QoS Classes
Guaranteed class suits latency-sensitive services like databases or real-time analytics. Burstable works for web servers, microservices, and event-driven workloads that tolerate occasional throttling. BestEffort fits batch jobs and background tasks with minimal service-level objectives.
You can mix QoS classes in a Deployment or StatefulSet to optimize resource costs. Reserve Guaranteed for critical pods and assign Burstable to scalable replicas. Use BestEffort under a separate node pool for ephemeral compute tasks.
Monitoring and Debugging Pod QoS Classes
To inspect a pod’s QoS class, run: kubectl describe pod <pod-name>
. Look under “QoS Class”. You can also query metrics-server or Prometheus to view usage vs requests.
kubectl top pod burstable-pod --containers
If eviction occurs, check node events: kubectl describe node <node-name>
. Spectrum of “Evicted” events appears in the pod status.
Limitations and Best Practices for Pod QoS Classes
Do not set arbitrarily high limits without corresponding requests. That misplaces pods into Burstable and weakens eviction guarantees. Always align requests with expected baseline throughput. Reserve Guaranteed for stateful services that cannot restart frequently. Regularly review node pressure and adjust resource quotas at namespace level to prevent noisy neighbours.
References
Suggested Reading
PostHashID: a9e84622f6e72eb158cb51df9ecfdae87a3aaac8395a689e9f9f78a13d63fa5d