ЁЯПл The SchoolтА║тШ╕я╕П KubernetesтА║ЁЯН╜я╕П рдзрдбрд╛ 23 тАФ QoS classes рдЖрдгрд┐ evictions: рдЬреЗрд╡рдг рдХрдореА рдкрдбрд▓реЗ рдХреА рдХреЛрдг рдЬрд╛рддреЗ
ЁЯЦ╝я╕П See the drawing + lab ЁЯПа Course home ЁЯМ┐ Branch on GitHub тЬПя╕П View source
ЁЯЦ╝я╕П рдЖрдХреГрддреА рдЖрдгрд┐ labThe drawing + lab рдкреВрд░реНрдг рдкрд╛рдирд╛рд╡рд░ рдЙрдШрдбрд╛ тЖЧOpen full page тЖЧ

ЁЯН╜я╕П рдзрдбрд╛ 23 тАФ QoS classes рдЖрдгрд┐ evictions: рдЬреЗрд╡рдг рдХрдореА рдкрдбрд▓реЗ рдХреА рдХреЛрдг рдЬрд╛рддреЗ

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: рдзрдбрд╛ 23 / 26 ┬╖ рдорд╛рдЧреАрд▓: lesson-22-statefulsets ┬╖ рдкреБрдвреАрд▓: lesson-24-cluster-upgrades


ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ

рдЖрдзреАрдЪреЗ рд╕рдЧрд│реЗ, рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ pod рдирдХрд│рдд рдЖрдзреАрдЪ рдЬреНрдпрд╛ рдЙрддрд░рдВрдбреАрдд рдЖрд╣реЗ рддреА тАФ QoS classes тАФ рдЖрдгрд┐ рдмрд╛рдХрд╛рд╡рд░рдЪреА memory рд╕рдВрдкрд▓реА рдХреА рдХрд╛рдп рд╣реЛрддреЗ: evictions.

ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ

рдзрдбрд╛ 08 рдЪреНрдпрд╛ рдХреЕрдиреНрдЯреАрдирдордзреНрдпреЗ рд╡рдЪрди рджрд┐рд▓реЗрд▓реА рддрд╛рдЯреЗ (requests) рдЖрдгрд┐ рд╡рд╛рдврдкреНрдпрд╛рдЪреА рдорд░реНрдпрд╛рджрд╛ (limits) рд╣реЛрддреА. рдЖрддрд╛ рддреЛ рднрд╛рдЧ, рдЬреНрдпрд╛рдмрджреНрджрд▓ рдЬреЗрд╡рдг рдЦрд░реЛрдЦрд░ рд╕рдВрдкреЗрдкрд░реНрдпрдВрдд рдХреЛрдгреАрдЪ рдмреЛрд▓рдд рдирд╛рд╣реА: рд╕реНрд╡рдпрдВрдкрд╛рдХрдШрд░ рдореБрд▓рд╛рдВрдирд╛ рдХреНрд░рдорд╛рдВрдХ рджреЗрддреЗ. ЁЯН╜я╕П

рдмрд╛рдХрд╛рд╡рд░рдЪреА memory рдХрдореА рдкрдбрд▓реА рдХреА (node pressure), kubelet evict рдХрд░рд╛рдпрд▓рд╛ рд╕реБрд░реБрд╡рд╛рдд рдХрд░рддреЛ: рдЖрдзреА BestEffort, рдордЧ рд╡рдЪрдирд╛рдкреЗрдХреНрд╖рд╛ рдЬрд╛рд╕реНрдд рдЦрд╛рдгрд╛рд░реЗ Burstable, рд╢реЗрд╡рдЯреА Guaranteed. Eviction рдмрд▒реНрдпрд╛рдкреИрдХреА рд╕рднреНрдп рдЕрд╕рддреЗ (pod рджреБрд╕рд░реАрдХрдбреЗ reschedule рд╣реЛрддреЛ тАФ рдзрдбрд╛ 03 рдЪрд╛ monitor рддреЗ рд╕рд╛рдВрднрд╛рд│рддреЛ); рддреНрдпрд╛рдЪрд╛ рдЕрд╕рднреНрдп рдЪреБрд▓рдд рднрд╛рдК рдореНрд╣рдгрдЬреЗ рддрд╛рддреНрдХрд╛рд│ рд╣реЛрдгрд╛рд░рд╛ OOMKill (рдзрдбрд╛ 08), рдЬреЗрд╡реНрд╣рд╛ рдПрдЦрд╛рджрд╛ container рд╕реНрд╡рддрдГрдЪреА рдорд░реНрдпрд╛рджрд╛ рдУрд▓рд╛рдВрдбрддреЛ.

VIP passes рд╕реБрджреНрдзрд╛ рдЕрд╕рддрд╛рдд: PriorityClasses тАФ system pods рдХрдбреЗ system-node-critical рдЕрд╕рддреЛ, рдореНрд╣рдгрдЬреЗ рд╢рд╛рд│реЗрдЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ рдХрд░реНрдордЪрд╛рд▒реНрдпрд╛рдВрдирд╛ рд╡рд┐рджреНрдпрд╛рд░реНрдереНрдпрд╛рдВрдЪреНрдпрд╛ рдЖрдзреА рдХрдзреАрдЪ рдЬрд╛рдпрд▓рд╛ рд╕рд╛рдВрдЧрд┐рддрд▓реЗ рдЬрд╛рдд рдирд╛рд╣реА.

ЁЯЧ║я╕П рдЖрдХреГрддреА

flowchart TB
    pressure["ЁЯЦея╕П desk under memory pressure<br/>kubelet must free space"]
    be["ЁЯеЙ BestEffort<br/>no requests/limits<br/>EVICTED FIRST"]
    bu["ЁЯеИ Burstable<br/>requests < limits<br/>next тАФ biggest over-promise first"]
    g["ЁЯеЗ Guaranteed<br/>requests == limits<br/>evicted last"]
    sys["ЁЯСо PriorityClass: system-critical<br/>the school's own staff тАФ basically never"]
    pressure -->|"1"| be
    pressure -->|"2"| bu
    pressure -->|"3"| g
    pressure -.->|"4"| sys
    be -.->|"rescheduled elsewhere<br/>by the monitor (L03)"| be

тЭУ рдХрд╛рдп

ЁЯдФ рдХрд╛

"рдЧрд░реНрджреАрдЪреНрдпрд╛ рд╡реЗрд│реА рдХреЛрдгрддрд╛рд╣реА pod рдирд╛рд╣реАрд╕рд╛ рдЭрд╛рд▓рд╛" рдореНрд╣рдгрдЬреЗ рд╣рд╛рдЪ рдзрдбрд╛, рджрд░ рд╡реЗрд│реА. QoS рд╣рд╛ рдзрдбрд╛ 08 рдЪрд╛ рд╣рд░рд╡рд▓реЗрд▓рд╛ рджреБрд╕рд░рд╛ рдЕрд░реНрдзрд╛ рднрд╛рдЧрд╕реБрджреНрдзрд╛ рдЖрд╣реЗ: requests рдлрдХреНрдд pods рдареЗрд╡рдд рдирд╛рд╣реАрдд тАФ рдкрд░рд┐рд╕реНрдерд┐рддреА рддрдВрдЧ рдЭрд╛рд▓реНрдпрд╛рд╡рд░ рддреНрдпрд╛ рдЯрд┐рдХрдгреНрдпрд╛рдЪрд╛ рдХреНрд░рдо рдЕрд╕рддрд╛рдд. рдкреНрд░рд╛рдорд╛рдгрд┐рдХ requests рдард░рд╡рдгреНрдпрд╛рдд рдШрд╛рд▓рд╡рд▓реЗрд▓реА рдкрд╛рдЪ рдорд┐рдирд┐рдЯреЗ рд╕рд░реНрд╡рд╛рдд рд╡рд╛рдИрдЯ рджрд┐рд╡рд╢реА рдЕрдВрджрд╛рдЬ рдмрд╛рдВрдзрддрд╛ рдпреЗрдгрд╛рд░реЗ рд╡рд░реНрддрди рдорд┐рд│рд╡реВрди рджреЗрддрд╛рдд.

ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛

# what class are OUR pods? (requests<limits тЖТ Burstable)
kubectl -n school get pods -o custom-columns='NAME:.metadata.name,QOS:.status.qosClass'

# make one of each and compare:
kubectl -n school run best --image=busybox -- sleep 3600
kubectl -n school run guar --image=busybox \
  --overrides='{"spec":{"containers":[{"name":"guar","image":"busybox","command":["sleep","3600"],
    "resources":{"requests":{"cpu":"50m","memory":"64Mi"},"limits":{"cpu":"50m","memory":"64Mi"}}}]}}'
kubectl -n school get pods best guar -o custom-columns='NAME:.metadata.name,QOS:.status.qosClass'
# best тЖТ BestEffort ЁЯеЙ ┬╖ guar тЖТ Guaranteed ЁЯеЗ

kubectl -n school delete pod best guar
# (real evictions need real node pressure тАФ don't simulate on your laptop;
#  instead read any prod cluster's story: kubectl get events -A | grep -i evict)

ЁЯФз рдпрд╛ рдзрдбреНрдпрд╛рд╕рд╛рдареА kubectl

kubectl get pod -o jsonpath ┬╖ kubectl describe node (Conditions: MemoryPressure)

ЁЯФЧ рдпрд╛рд╡рд░ рдЖрдзрд╛рд░рд┐рдд: ЁЯкк AWS L08 (рддрд╛рдЯ рд░рд╛рдЦреВрди рдареЗрд╡рд╛)

тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд▓реЗ рдкрд╛рд╣рд┐рдЬреЗ

kubectl get pod POD -o jsonpath='{.status.qosClass}' Guaranteed / Burstable / BestEffort рдЫрд╛рдкрддреЗ; рджрдмрд╛рд╡рд╛рдЦрд╛рд▓реА BestEffort pod рд╕рд░реНрд╡рд╛рдд рдЖрдзреА evict рд╣реЛрддреЛ.

ЁЯз╣ рд╕рд╛рдлрд╕рдлрд╛рдИ

local cluster: kubectl delete -f k8s/ (рдХрд┐рдВрд╡рд╛ рддреБрдореНрд╣реА apply рдХреЗрд▓реЗрд▓реА file) тАФ EKS рд╡рд░ рдЪрд╛рд▓реВ рд░рд╛рд╣рд┐рд▓реЗрд▓реНрдпрд╛ рдХрд╢рд╛рдЪреЗрд╣реА рддрд╛рд╕рд╛рдкреНрд░рдорд╛рдгреЗ рдмрд┐рд▓ рдпреЗрддреЗ

тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛

тПня╕П рдкреБрдвреЗ

рд╢рд╛рд│рд╛ рдЪрд╛рд▓реВ рдареЗрд╡реВрди рд╡рд░реНрдЧрдЦреЛрд▓реНрдпрд╛рдВрдЪреЗ рдиреВрддрдиреАрдХрд░рдг: cluster upgrades тАФ рдЬрд┐рдереЗ cordon, drain, рдЖрдгрд┐ рдзрдбрд╛ 15 рдЪреЗ PDBs рдЕрдЦреЗрд░ рдПрдХрддреНрд░ рдХрд╛рдо рдХрд░рддрд╛рдд.

git checkout lesson-24-cluster-upgrades

ЁЯН╜я╕П Lesson 23 тАФ QoS classes & evictions: who leaves when lunch runs short

ЁЯУН You are here: Lesson 23 of 26 ┬╖ Previous: lesson-22-statefulsets ┬╖ Next: lesson-24-cluster-upgrades


ЁЯУж What's in this branch

Everything before, plus the pecking order every pod is already in without knowing it тАФ QoS classes тАФ and what happens when a desk runs out of memory: evictions.

ЁЯзТ Explain like I'm 5

Lesson 08's canteen had promised plates (requests) and portion caps (limits). Here's the part nobody mentions until the food actually runs out: the kitchen ranks the kids. ЁЯН╜я╕П

When a desk runs low on memory (node pressure), the kubelet starts evicting: BestEffort first, then Burstable eating over its promise, Guaranteed last. Eviction is polite-ish (pod rescheduled elsewhere тАФ lesson 03's monitor handles it); the impolite cousin is the instant OOMKill (lesson 08) when one container bursts past its own cap.

VIP passes exist too: PriorityClasses тАФ system pods carry system-node-critical so the school's own staff is never asked to leave before the students.

ЁЯЧ║я╕П Diagram

flowchart TB
    pressure["ЁЯЦея╕П desk under memory pressure<br/>kubelet must free space"]
    be["ЁЯеЙ BestEffort<br/>no requests/limits<br/>EVICTED FIRST"]
    bu["ЁЯеИ Burstable<br/>requests < limits<br/>next тАФ biggest over-promise first"]
    g["ЁЯеЗ Guaranteed<br/>requests == limits<br/>evicted last"]
    sys["ЁЯСо PriorityClass: system-critical<br/>the school's own staff тАФ basically never"]
    pressure -->|"1"| be
    pressure -->|"2"| bu
    pressure -->|"3"| g
    pressure -.->|"4"| sys
    be -.->|"rescheduled elsewhere<br/>by the monitor (L03)"| be

тЭУ What

ЁЯдФ Why

"Random pod disappeared at peak traffic" is this lesson, every time. QoS is also lesson 08's missing second half: requests don't just place pods тАФ they're the survival ranking when things get tight. Five minutes spent setting honest requests buys you predictable behavior on the worst day.

ЁЯзк Try it

# what class are OUR pods? (requests<limits тЖТ Burstable)
kubectl -n school get pods -o custom-columns='NAME:.metadata.name,QOS:.status.qosClass'

# make one of each and compare:
kubectl -n school run best --image=busybox -- sleep 3600
kubectl -n school run guar --image=busybox \
  --overrides='{"spec":{"containers":[{"name":"guar","image":"busybox","command":["sleep","3600"],
    "resources":{"requests":{"cpu":"50m","memory":"64Mi"},"limits":{"cpu":"50m","memory":"64Mi"}}}]}}'
kubectl -n school get pods best guar -o custom-columns='NAME:.metadata.name,QOS:.status.qosClass'
# best тЖТ BestEffort ЁЯеЙ ┬╖ guar тЖТ Guaranteed ЁЯеЗ

kubectl -n school delete pod best guar
# (real evictions need real node pressure тАФ don't simulate on your laptop;
#  instead read any prod cluster's story: kubectl get events -A | grep -i evict)

ЁЯФз kubectl for this lesson

kubectl get pod -o jsonpath ┬╖ kubectl describe node (Conditions: MemoryPressure)

ЁЯФЧ Builds on: ЁЯкк AWS L08 (reserve the plate)

тЬЕ Verify тАФ what you should see

kubectl get pod POD -o jsonpath='{.status.qosClass}' prints Guaranteed / Burstable / BestEffort; under pressure the BestEffort pod is evicted first.

ЁЯз╣ Clean up

local cluster: kubectl delete -f k8s/ (or the file you applied) тАФ on EKS, anything left running bills by the hour

тЪая╕П Common mistakes

тПня╕П Next

Renovating classrooms while school stays open: cluster upgrades тАФ where cordon, drain, and lesson 15's PDBs finally perform together.

git checkout lesson-24-cluster-upgrades
тЖР PreviousstatefulsetsNext тЖТcluster upgrades

This page is the lesson's README from the lesson-23-qos-evictions branch, shown here so the whole School stays on one site. Code files open on GitHub at the same branch.