ЁЯПл The SchoolтА║тШ╕я╕П KubernetesтА║ЁЯОл рдзрдбрд╛ 20 тАФ Taints, tolerations рдЖрдгрд┐ affinity: рдард░рд╡реВрди рджрд┐рд▓реЗрд▓реА рдмреИрдардХ
ЁЯЦ╝я╕П See the drawing + lab ЁЯПа Course home ЁЯМ┐ Branch on GitHub тЬПя╕П View source
ЁЯЦ╝я╕П рдЖрдХреГрддреА рдЖрдгрд┐ labThe drawing + lab рдкреВрд░реНрдг рдкрд╛рдирд╛рд╡рд░ рдЙрдШрдбрд╛ тЖЧOpen full page тЖЧ

ЁЯОл рдзрдбрд╛ 20 тАФ Taints, tolerations рдЖрдгрд┐ affinity: рдард░рд╡реВрди рджрд┐рд▓реЗрд▓реА рдмреИрдардХ

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: рдзрдбрд╛ 20 / 26 ┬╖ рдорд╛рдЧреАрд▓: lesson-19-network-policies ┬╖ рдкреБрдвреАрд▓: lesson-21-daemonsets


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

рдЖрдзреАрдЪреЗ рд╕рдЧрд│реЗ, рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ pod рдХреЛрдгрддреНрдпрд╛ рдмрд╛рдХрд╛рд╡рд░ рдмрд╕реЗрд▓ рддреЗ рдард░рд╡рдгреЗ: taints рдиреЗ рджреВрд░ рд▓реЛрдЯрд╛, tolerations рдиреЗ рдкрд░рд╡рд╛рдирдЧреА рджреНрдпрд╛, affinity рдиреЗ рдЖрдХрд░реНрд╖рд┐рдд рдХрд░рд╛, anti-affinity рдиреЗ рд╡реЗрдЧрд│реЗ рдХрд░рд╛.

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

рдЖрддреНрддрд╛рдкрд░реНрдпрдВрдд рд╡реЗрд│рд╛рдкрддреНрд░рдХ рдмрдирд╡рдгрд╛рд░рд╛ рдореБрд▓рд╛рдВрдирд╛ рдХреЛрдгрддреНрдпрд╛рд╣реА рдореЛрдХрд│реНрдпрд╛ рдмрд╛рдХрд╛рд╡рд░ рдмрд╕рд╡рдд рдЕрд╕реЗ. рдЦрд▒реНрдпрд╛ рд╢рд╛рд│рд╛рдВрдордзреНрдпреЗ рдмрд╕рдгреНрдпрд╛рдЪреЗ рдирд┐рдпрдо рдЕрд╕рддрд╛рдд тАФ рджреЛрди рдкреНрд░рдХрд╛рд░рдЪреЗ:

рдмрд╛рдХрд╛рдВрд╡рд░рдЪреНрдпрд╛, рдореБрд▓рд╛рдВрдирд╛ рджреВрд░ рд▓реЛрдЯрдгрд╛рд▒реНрдпрд╛ рдкрд╛рдЯреНрдпрд╛ ЁЯЪл (taints): рд╢рд┐рдХреНрд╖рд┐рдХреЗрдЪреНрдпрд╛ рдмрд╛рдХрд╛рд╡рд░ рдкрд╛рдЯреА рдЖрд╣реЗ: "рд╡рд┐рджреНрдпрд╛рд░реНрдереНрдпрд╛рдВрд╕рд╛рдареА рдирд╛рд╣реА!" рддрд┐рдереЗ рдХреЛрдгрддреЗрд╣реА рдореВрд▓ рдмрд╕реВ рд╢рдХрдд рдирд╛рд╣реАтАж рдЬреЛрдкрд░реНрдпрдВрдд рддреНрдпрд╛рдЪреНрдпрд╛рдХрдбреЗ рдЬреБрд│рдгрд╛рд░реА рдкрд░рд╡рд╛рдирдЧреАрдЪреА рдЪрд┐рдареНрдареА ЁЯОл (toleration) рдирд╛рд╣реА. рдпрд╛рдЪ рдкрджреНрдзрддреАрдиреЗ Kubernetes рд╕рд╛рдзреЗ pods рдЦрд╛рд╕ nodes рдкрд╛рд╕реВрди рджреВрд░ рдареЗрд╡рддреЗ: GPU рдмрд╛рдХ (gpu=true:NoSchedule тАФ рдлрдХреНрдд ML pods рдХрдбреЗ рдЪрд┐рдареНрдареА рдЕрд╕рддреЗ), рдирд╛рд╣реАрд╕реЗ рд╣реЛрдК рд╢рдХрдгрд╛рд░реЗ spot рдмрд╛рдХ (рддрд┐рдереЗ рдлрдХреНрдд рд╡реНрдпрддреНрдпрдп рд╕рд╣рди рдХрд░рдгрд╛рд░реЗ pods рдмрд╕рддрд╛рдд тАФ рдзрдбрд╛ 15!), рдЖрдгрд┐ рдЖрдЬрд╛рд░реА рдмрд╛рдХ (NoExecute рдЖрдзреАрдЪ рдмрд╕рд▓реЗрд▓реНрдпрд╛ рдореБрд▓рд╛рдВрдирд╛рд╣реА рдмрд╛рд╣реЗрд░ рдХрд╛рдврддреЛ).

рдореБрд▓рд╛рдВрд╡рд░рдЪреНрдпрд╛, рддреНрдпрд╛рдВрдирд╛ рдХреБрдареЗ рдмрд╕рд╛рдпрдЪреЗ рдЖрд╣реЗ рддреНрдпрд╛рдмрджреНрджрд▓рдЪреНрдпрд╛ рдиреЛрдВрджреА ЁЯз▓ (affinity):

рдмрд╛рдХрд╛рдХрдбреВрди рдврдХрд▓рдгреЗ, рдореБрд▓рд╛рдХрдбреВрди рдУрдврдгреЗ. Taints рдЗрдЪреНрдЫрд╛рдВрд╡рд░ рдорд╛рдд рдХрд░рддрд╛рдд: рдЪрд┐рдареНрдареА рдирд╛рд╣реА, рддрд░ рдЬрд╛рдЧрд╛ рдирд╛рд╣реА, рдХрдзреАрдЪ.

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

flowchart TB
    subgraph desks["ЁЯЦея╕П the desks"]
        gpu["GPU desk ЁЯТО<br/>taint: gpu=true:NoSchedule"]
        spot["spot desk ЁЯОЯя╕П<br/>taint: spot=true:NoSchedule"]
        norm["normal desks"]
    end
    ml["ЁЯдЦ ML pod<br/>toleration: gpu ЁЯОл<br/>+ nodeAffinity: WANTS gpu"]
    web["ЁЯкС school-api ├Ч2<br/>podAntiAffinity:<br/>never both on one desk"]
    other["ЁЯкС ordinary pod<br/>no chit"]
    ml -->|"1 allowed + attracted"| gpu
    other -.->|"2 repelled тЭМ"| gpu
    other --> norm
    web -->|"3 spread across desks"| norm

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

ЁЯдФ рдХрд╛

рдПрдХрд╕рд╛рд░рдЦреНрдпрд╛ рдмрд╛рдХрд╛рдВрдЪрд╛ рдПрдХрдЪ pool, рдЬреНрдпрд╛ рджрд┐рд╡рд╢реА рддреБрдореНрд╣реА GPUs, spot instances, рдХрд┐рдВрд╡рд╛ latency-sensitive API рд╢реЗрдЬрд╛рд░реА рдЧреЛрдВрдЧрд╛рдЯ рдХрд░рдгрд╛рд░рд╛ batch workload рдЬреЛрдбрддрд╛, рддреНрдпрд╛ рджрд┐рд╡рд╢реА рдЪрд╛рд▓рдгреЗ рдмрдВрдж рд╣реЛрддреЛ. рдмрд╕рдгреНрдпрд╛рдЪреНрдпрд╛ рдирд┐рдпрдорд╛рдВрдореБрд│реЗрдЪ рдПрдХрдЪ cluster рд╡реЗрдЧрд╡реЗрдЧрд│реА рдЕрд░реНрдерд╡реНрдпрд╡рд╕реНрдерд╛ (spot vs on-demand), рд╡реЗрдЧрд╡реЗрдЧрд│реЗ hardware, рдЖрдгрд┐ рдПрдХрдореЗрдХрд╛рдВрдирд╛ рддреНрд░рд╛рд╕ рджреЗрдгрд╛рд░реЗ tenants рд╕рд╛рдВрднрд╛рд│реВ рд╢рдХрддреЛ тАФ рд╡реЗрдЧрд│реНрдпрд╛ рд╢рд╛рд│рд╛ рд╡рд┐рдХрдд рди рдШреЗрддрд╛.

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

NODE=$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')

# put a "wet paint" sign on the desk:
kubectl taint node $NODE wetpaint=true:NoSchedule

# ordinary pod тЖТ Pending (lesson 16 drill: describe tells you exactly why!)
kubectl -n school run nochit --image=nginxdemos/hello:plain-text
kubectl -n school describe pod nochit | grep -A3 Events | tail -3

# pod WITH the chit тЖТ seated happily:
kubectl -n school run haschit --image=nginxdemos/hello:plain-text \
  --overrides='{"spec":{"tolerations":[{"key":"wetpaint","operator":"Equal","value":"true","effect":"NoSchedule"}]}}'
kubectl -n school get pods -o wide | grep chit

# clean the sign and the kids:
kubectl taint node $NODE wetpaint=true:NoSchedule-
kubectl -n school delete pod nochit haschit

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

kubectl taint ┬╖ kubectl describe node (Taints) ┬╖ kubectl get pods -o wide

ЁЯФЧ рдпрд╛рд╡рд░ рдЖрдзрд╛рд░рд┐рдд: ЁЯкк AWS L08 (instance types тАФ GPU рдмрд╛рдХ)

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

рд╕рд╛рдзрд╛ pod tainted node рд╡рд░ Pending рд░рд╛рд╣рддреЛ; toleration + affinity рдЕрд╕рд▓реЗрд▓рд╛ pod рддреНрдпрд╛рд╡рд░ рдЬрд╛рдКрди рдмрд╕рддреЛ.

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

kubectl taint nodes NODE gpu- (рд╡рдЬрд╛ рдЪрд┐рдиреНрд╣ рдХрд╛рдвреВрди рдЯрд╛рдХрддреЗ)

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

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

рдХрд╛рд╣реА рдорджрддрдиреАрд╕ рдкреНрд░рддреНрдпреЗрдХ рдордЬрд▓реНрдпрд╛рд╡рд░ рдмрд╕рд▓реЗрдЪ рдкрд╛рд╣рд┐рдЬреЗрдд, рдЕрдкрд╡рд╛рдж рдирд╛рд╣реА тАФ log collectors, node agents: DaemonSets.

git checkout lesson-21-daemonsets

ЁЯОл Lesson 20 тАФ Taints, tolerations & affinity: assigned seating

ЁЯУН You are here: Lesson 20 of 26 ┬╖ Previous: lesson-19-network-policies ┬╖ Next: lesson-21-daemonsets


ЁЯУж What's in this branch

Everything before, plus steering WHICH desk each pod sits at: repel with taints, permit with tolerations, attract with affinity, separate with anti-affinity.

ЁЯзТ Explain like I'm 5

Until now the timetable-maker seated kids at any free desk. Real schools have seating rules тАФ two kinds:

Signs on DESKS that push kids away ЁЯЪл (taints): the teacher's desk has a sign: "not for students!" No kid may sit thereтАж unless they carry a matching permission chit ЁЯОл (a toleration). That's how Kubernetes keeps normal pods off special nodes: GPU desks (gpu=true:NoSchedule тАФ only ML pods carry the chit), spot desks that can vanish (only interruption-tolerant pods sit there тАФ lesson 15!), and sick desks (NoExecute even evicts the kids already sitting).

Notes on KIDS about where they want to sit ЁЯз▓ (affinity):

Push from the desk, pull from the kid. Taints beat wishes: no chit, no seat, ever.

ЁЯЧ║я╕П Diagram

flowchart TB
    subgraph desks["ЁЯЦея╕П the desks"]
        gpu["GPU desk ЁЯТО<br/>taint: gpu=true:NoSchedule"]
        spot["spot desk ЁЯОЯя╕П<br/>taint: spot=true:NoSchedule"]
        norm["normal desks"]
    end
    ml["ЁЯдЦ ML pod<br/>toleration: gpu ЁЯОл<br/>+ nodeAffinity: WANTS gpu"]
    web["ЁЯкС school-api ├Ч2<br/>podAntiAffinity:<br/>never both on one desk"]
    other["ЁЯкС ordinary pod<br/>no chit"]
    ml -->|"1 allowed + attracted"| gpu
    other -.->|"2 repelled тЭМ"| gpu
    other --> norm
    web -->|"3 spread across desks"| norm

тЭУ What

ЁЯдФ Why

One pool of identical desks stops working the day you add GPUs, spot instances, or a noisy batch workload next to a latency-sensitive API. Seating rules are how ONE cluster hosts different economics (spot vs on-demand), different hardware, and mutually-annoying tenants тАФ without buying separate schools.

ЁЯзк Try it

NODE=$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')

# put a "wet paint" sign on the desk:
kubectl taint node $NODE wetpaint=true:NoSchedule

# ordinary pod тЖТ Pending (lesson 16 drill: describe tells you exactly why!)
kubectl -n school run nochit --image=nginxdemos/hello:plain-text
kubectl -n school describe pod nochit | grep -A3 Events | tail -3

# pod WITH the chit тЖТ seated happily:
kubectl -n school run haschit --image=nginxdemos/hello:plain-text \
  --overrides='{"spec":{"tolerations":[{"key":"wetpaint","operator":"Equal","value":"true","effect":"NoSchedule"}]}}'
kubectl -n school get pods -o wide | grep chit

# clean the sign and the kids:
kubectl taint node $NODE wetpaint=true:NoSchedule-
kubectl -n school delete pod nochit haschit

ЁЯФз kubectl for this lesson

kubectl taint ┬╖ kubectl describe node (Taints) ┬╖ kubectl get pods -o wide

ЁЯФЧ Builds on: ЁЯкк AWS L08 (instance types тАФ the GPU desk)

тЬЕ Verify тАФ what you should see

the ordinary pod stays Pending on the tainted node; the pod with the toleration + affinity lands on it.

ЁЯз╣ Clean up

kubectl taint nodes NODE gpu- (minus removes)

тЪая╕П Common mistakes

тПня╕П Next

Some helpers must sit on EVERY floor, no exceptions тАФ log collectors, node agents: DaemonSets.

git checkout lesson-21-daemonsets
тЖР Previousnetwork policiesNext тЖТdaemonsets

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