Full lesson
Explore the full explanation, examples, and visuals at your own pace.
No crash logs, no failed health checks
Your batch-report Pod says Evicted, but it never crashed. The app was healthy. The problem was the node. Its memory ran low, so the kubelet stepped in and terminated the Pod to protect the node, not because anything failed.
One node, three healthy Pods
Here's our setup: one node with 8 gibibytes of memory, running checkout, api, and batch-report. A request is the memory a Pod reserves so the scheduler can place it. Checkout requests 2, api requests 1, and batch-report requested nothing at all.
Actual usage nearly fills the node
Add up what's actually in use: 2, 2.5, 2, and 1.4 gigabytes. That's about 7.9 of the node's 8. Free memory falls below the kubelet's eviction threshold, so the node reports MemoryPressure, and it has to reclaim memory.
Chart values
| Consumer | GiB used |
|---|---|
| checkout | 2 |
| api | 2.5 |
| batch-report | 2 |
| system | 1.4 |
QoS classes from requests and limits
Kubernetes assigns each Pod a QoS class automatically from its requests and limits. checkout is Guaranteed, api is Burstable, and batch-report is BestEffort. With no reservation at all, any memory it uses counts as overspending.
- Guaranteed: checkout, requests equal limits
- Burstable: api, requests below usage
- BestEffort: batch-report, no requests
Who is using more than they reserved?
The kubelet's first question is simple: is this Pod using more than it requested? Checkout sits at zero over its 2 GiB, so it's safe for now. Api is 1.5 GiB over, and batch-report is 2 GiB over. Those two become candidates.
Chart values
| Pod | GiB over request |
|---|---|
| checkout | 0 |
| api | 1.5 |
| batch-report | 2 |
The kubelet's eviction ranking
Of the two over-request Pods, the kubelet looks at priority next. batch-report sits at priority 0, lower than api, so it goes first. Most over request only breaks ties. The lesson: the more you overspend your request, with low priority, the sooner you're evicted.
Suppose api's priority drops below batch-report's. Both still exceed their requests. Which Pod does the kubelet evict first?
Suppose api's priority drops below batch-report's. Both still exceed their requests. Which Pod does the kubelet evict first?
- api, now lowest priority among over-request Pods
- batch-report, because BestEffort always goes first
- checkout, because it reserved the most memory
Suppose api's priority drops below batch-report's. Both still exceed their requests. Which Pod does the kubelet evict first?
api, now lowest priority among over-request Pods. Both api and batch-report pass the first check by using more than they requested, so priority decides next. With api now lower, it goes first. QoS class is not a fixed order; it simply tends to match whether a Pod exceeds its request.
- api, now lowest priority among over-request Pods
- batch-report, because BestEffort always goes first
- checkout, because it reserved the most memory
Why the app seems to vanish
The kubelet terminates batch-report and reports status Evicted to the API Server. That's not a crash, and nothing restarts it in place. A controller, like a Deployment, can ask for a replacement, but it may sit Pending if no node has room. A bare Pod is simply gone.
Reserve honestly, prioritize what matters
Eviction protects the node, not any single app. Pods using more than they requested, with lower priority, go first. So set realistic memory requests and PriorityClasses, and checkout will be evicted last.



