ЁЯПл The SchoolтА║тШ╕я╕П KubernetesтА║ЁЯПЧя╕П рдзрдбрд╛ 24 тАФ Cluster upgrades: рд╢рд╛рд│рд╛ рдЪрд╛рд▓реВ рдЕрд╕рддрд╛рдирд╛ рдиреВрддрдиреАрдХрд░рдг
ЁЯЦ╝я╕П See the drawing + lab ЁЯПа Course home ЁЯМ┐ Branch on GitHub тЬПя╕П View source
ЁЯЦ╝я╕П рдЖрдХреГрддреА рдЖрдгрд┐ labThe drawing + lab рдкреВрд░реНрдг рдкрд╛рдирд╛рд╡рд░ рдЙрдШрдбрд╛ тЖЧOpen full page тЖЧ

ЁЯПЧя╕П рдзрдбрд╛ 24 тАФ Cluster upgrades: рд╢рд╛рд│рд╛ рдЪрд╛рд▓реВ рдЕрд╕рддрд╛рдирд╛ рдиреВрддрдиреАрдХрд░рдг

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: рдзрдбрд╛ 24 / 26 ┬╖ рдорд╛рдЧреАрд▓: lesson-23-qos-evictions ┬╖ рдкреБрдвреАрд▓: lesson-25-crds-operators


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

рдЖрдзреАрдЪреЗ рд╕рдЧрд│реЗ, рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ cluster рдорд╛рд▓рдХрд╛рд▓рд╛ рд╡рд░реНрд╖рд╛рддреВрди ~3 рд╡реЗрд│рд╛ рдХрд░рд╛рд╡реЗ рд▓рд╛рдЧрдгрд╛рд░реЗ рдХрд╛рдо: рд╢рд╛рд│рд╛ рдмрдВрдж рди рдХрд░рддрд╛ Kubernetes рд╕реНрд╡рддрдГрдЪ upgrade рдХрд░рдгреЗ.

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

Kubernetes рд╡рд░реНрд╖рд╛рддреВрди рддреАрди рд╡реЗрд│рд╛ рдирд╡реА version рдЖрдгрддреЗ, рдЖрдгрд┐ рдЬреБрдиреНрдпрд╛ versions рдирд╛ patches рдорд┐рд│рдгреЗ рдмрдВрдж рд╣реЛрддреЗ тАФ рдореНрд╣рдгреВрди upgrade рдХрд░рдгреЗ рдРрдЪреНрдЫрд┐рдХ рдирд╛рд╣реА, рддреЗ рдард░рд▓реЗрд▓реЗ рдиреВрддрдиреАрдХрд░рдг рдЖрд╣реЗ ЁЯПЧя╕П. рдиреВрддрдиреАрдХрд░рдгрд╛рдЪреЗ рдирд┐рдпрдо:

  1. рдЖрдзреА office, рдордЧ рд╡рд░реНрдЧрдЦреЛрд▓реНрдпрд╛. ЁЯПв control plane upgrade рдХрд░рд╛ (EKS: рдПрдХ API call/Terraform рдмрджрд▓ тАФ AWS рд╕реНрд╡рддрдГрдЪреНрдпрд╛ office рдЪреЗ рдиреВрддрдиреАрдХрд░рдг рди рджрд┐рд╕рддрд╛ рдХрд░рддреЗ), рдордЧ рдмрд╛рдХ. рдХрдзреАрдЪ рдЙрд▓рдЯреЗ рдирд╛рд╣реА: kubelets office рдкреЗрдХреНрд╖рд╛ рдереЛрдбреЗ рдЬреБрдиреЗ рдЕрд╕реВ рд╢рдХрддрд╛рдд, рдХрдзреАрдЪ рдирд╡реЗ рдирд╛рд╣реАрдд ("version skew" рдирд┐рдпрдо).
  2. рдПрдХрд╛ рд╡реЗрд│реА рдПрдХ рд╡рд░реНрдЧрдЦреЛрд▓реА, рдореБрд▓рд╛рдВрдирд╛ рд╕рднреНрдпрдкрдгреЗ рд╣рд▓рд╡рд╛. рдкреНрд░рддреНрдпреЗрдХ рдмрд╛рдХрд╛рд╕рд╛рдареА:
    • cordon ЁЯЪз тАФ рджрд╛рд░рд╛рд╡рд░ рдкрдЯреНрдЯреА: "рдЗрдереЗ рдирд╡реА рдореБрд▓реЗ рдмрд╕рд╡рд╛рдпрдЪреА рдирд╛рд╣реАрдд" (kubectl cordon тАФ рдмрд╕рд▓реЗрд▓реА рдореБрд▓реЗ рдЬрд╛рдЧреАрдЪ рд░рд╛рд╣рддрд╛рдд);
    • drain ЁЯЪЪ тАФ рдореБрд▓рд╛рдВрдирд╛ рджреБрд╕рд▒реНрдпрд╛ рдмрд╛рдХрд╛рдВрдХрдбреЗ рдШреЗрдКрди рдЬрд╛ (kubectl drain тАФ pods reschedule рд╣реЛрддрд╛рдд; рдзрдбрд╛ 03 рдЪрд╛ monitor рддреНрдпрд╛рдВрдирд╛ рджреБрд╕рд░реАрдХрдбреЗ рдкреБрдиреНрд╣рд╛ рдмрдирд╡рддреЛ);
    • рдмрд╛рдХ рдмрджрд▓рд╛ (managed node groups: рдирд╡реНрдпрд╛ kubelet рд╕рд╣ рдирд╡рд╛ EC2 рдмрд╛рдХ тАФ рдЧреБрд░реЗ, рдиреВрддрдиреАрдХрд░рдг рдХреЗрд▓реЗрд▓реЗ рд▓рд╛рдбрдХреЗ рдкреНрд░рд╛рдгреА рдирд╛рд╣реАрдд! AWS рдХреЛрд░реНрд╕ L12);
    • uncordon тАФ рдкрдЯреНрдЯреА рдХрд╛рдврд╛, рдкреБрдврдЪреА рд╡рд░реНрдЧрдЦреЛрд▓реА.
  3. PDBs рдЕрдЦреЗрд░ рдХрд╛рдорд╛рд▓рд╛ рдпреЗрддрд╛рдд. ЁЯН╜я╕П рдзрдбрд╛ 15 рдЪрд╛ PodDisruptionBudget рд╣рд╛рдЪ drain рд╕реБрд░рдХреНрд╖рд┐рдд рдмрдирд╡рддреЛ: "school-api рдЪреА рджреЛрдиреНрд╣реА рдореБрд▓реЗ рдХрдзреАрдЪ рдПрдХрджрдо рдмрд╛рд╣реЗрд░ рдирд╛рд╣реАрдд" тАФ рд╡рд░реНрдЧ рд╕рд╛рдВрднрд╛рд│рд▓рд╛ рдЬрд╛рдИрдкрд░реНрдпрдВрдд drain рдкреНрд░рддреНрдпреЗрдХ рдкрд╛рдпрд░реАрд╡рд░ рдерд╛рдВрдмрддреЛ. PDB рдирд╛рд╣реА = drain рдХреНрд╖рдгрднрд░рд╛рд╕рд╛рдареА рддреБрдордЪреЗ app рд░рд┐рдХрд╛рдореЗ рдХрд░реВ рд╢рдХрддреЛ. рдЖрддрд╛ рдХрд│рд▓реЗ рдЖрдкрдг рддреЛ рдХрд╛ рдареЗрд╡рд▓рд╛.
  4. рдлрдХреНрдд рдЫреЛрдЯреА рдкрд╛рд╡рд▓реЗ: рдПрдХрд╛ рд╡реЗрд│реА рдПрдХрдЪ minor version (1.31тЖТ1.32тЖТ1.33), рдЖрдзреА staging cluster, рдХрд╛рдвреВрди рдЯрд╛рдХрд▓реЗрд▓реНрдпрд╛ APIs рд╕рд╛рдареА release notes рд╡рд╛рдЪрд╛ (рдХреНрд▓рд╛рд╕рд┐рдХ рдмрд┐рдШрд╛рдб: рдирд╛рд╣реАрд╢реА рдЭрд╛рд▓реЗрд▓реА apiVersion рд╡рд╛рдкрд░рдгрд╛рд░рд╛ manifest).

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

flowchart LR
    plan["ЁЯУЛ read release notes<br/>check deprecated APIs"]
    office["ЁЯПв 1 upgrade the office<br/>EKS control plane - one call"]
    subgraph desks["2 then desk by desk"]
        c["ЁЯЪз cordon<br/>no new kids"]
        d["ЁЯЪЪ drain<br/>kids walk out politely<br/>PDB guards the minimum ЁЯН╜я╕П"]
        r["ЁЯЦея╕П replace desk<br/>fresh EC2, new kubelet"]
        u["тЬЕ uncordon<br/>next classroom"]
        c --> d --> r --> u
    end
    plan --> office --> desks
    u -.->|"repeat per node,<br/>school never closes"| c

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

ЁЯдФ рдХрд╛

upgrades рдЯрд╛рд│рдгрд╛рд░реЗ clusters patch рди рдХрд░рддрд╛ рдпреЗрдгрд╛рд░реА рд╕рдВрдЧреНрд░рд╣рд╛рд▓рдпреЗ рдмрдирддрд╛рдд, рдЖрдгрд┐ рд╢реЗрд╡рдЯреА рднрд╛рдЧ рдкрд╛рдбрдгрд╛рд░рд╛ рддрд┐рд╣реЗрд░реА-рдЙрдбреАрдЪрд╛ upgrade рдореНрд╣рдгрдЬреЗ рджрд╣рд╢рддреАрдЪрд╛ weekend. рд╡рд╛рд░рдВрд╡рд╛рд░ upgrade рдХрд░рдгрд╛рд▒реНрдпрд╛ teams рд╕рд╛рдареА рддреЗ рдХрдВрдЯрд╛рд│рд╡рд╛рдгреЗ рд╣реЛрддреЗ тАФ рдХрд╛рд░рдг рдпрд╛ рдХреЛрд░реНрд╕рдордзрд▓реА рдкреНрд░рддреНрдпреЗрдХ рдпрдВрддреНрд░рдгрд╛ (monitor, probes, PDB, multi-AZ, рдЧреБрд░рд╛рдВрд╕рд╛рд░рдЦреЗ рдмрд╛рдХ) рдиреЗрдордХреА рдпрд╛рд╕рд╛рдареАрдЪ рдЖрд╣реЗ рдХреА рдПрдЦрд╛рджрд╛ рдмрд╛рдХ рдХреЛрдгрддреНрдпрд╛рд╣реА рдХреНрд╖рдгреА рдореБрджреНрджрд╛рдо рдирд╛рд╣реАрд╕рд╛ рд╣реЛрдК рд╢рдХрд╛рд╡рд╛. Upgrade рдореНрд╣рдгрдЬреЗ рдлрдХреНрдд рдард░рд╡реВрди рдХреЗрд▓реЗрд▓рд╛ рдЧреЛрдВрдзрд│.

ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛ (рдХреЛрдгрддреНрдпрд╛рд╣реА local cluster рд╡рд░ рд╕реБрд░рдХреНрд╖рд┐рдд)

kubectl version | head -2                       # office vs desk versions
NODE=$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')

kubectl cordon $NODE                            # ЁЯЪз tape on the door
kubectl get nodes                               # SchedulingDisabled
kubectl -n school run newkid --image=busybox -- sleep 300
kubectl -n school get pod newkid                # Pending тАФ no desk accepts new kids!

kubectl uncordon $NODE                          # tape off
kubectl -n school get pod newkid -w             # seated ЁЯОЙ  (Ctrl+C)
kubectl -n school delete pod newkid

# multi-node clusters only тАФ feel a real drain (watch the PDB hold the line):
# kubectl drain $NODE --ignore-daemonsets --delete-emptydir-data
# kubectl uncordon $NODE

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

kubectl cordon/drain/uncordon ┬╖ kubectl get nodes

ЁЯФЧ рдпрд╛рд╡рд░ рдЖрдзрд╛рд░рд┐рдд: ЁЯкк AWS L12 (EKS node groups = рдмрд╛рдХрд╛рдВрдЪреЗ ASGs)

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

kubectl cordon NODE тЖТ SchedulingDisabled; kubectl drain PDB рд╕рд╛рдареА рдерд╛рдВрдмрддреЛ, рдордЧ pods рд╣рд▓рддрд╛рдд; uncordon рддреЛ рдкреБрдиреНрд╣рд╛ рдЙрдШрдбрддреЛ.

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

kubectl uncordon NODE тАФ рд╡рд░реНрдЧрдЦреЛрд▓реА рдкрдЯреНрдЯреА рд▓рд╛рд╡реВрди рдмрдВрдж рдареЗрд╡реВ рдирдХрд╛

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

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

Kubernetes рдкреВрд░реНрдгрдкрдгреЗ рдирд╡реЗ рд╢рдмреНрдж рдХрд╕реЗ рд╢рд┐рдХрддреЛ тАФ ArgoCD рдЪреНрдпрд╛ Application рдорд╛рдЧрдЪреА рдЖрдгрд┐ рдЕрд░реНрдзреНрдпрд╛ cloud-native рдЬрдЧрд╛рдорд╛рдЧрдЪреА рдпрдВрддреНрд░рдгрд╛: CRDs рдЖрдгрд┐ operators.

git checkout lesson-25-crds-operators

ЁЯПЧя╕П Lesson 24 тАФ Cluster upgrades: renovating while school stays open

ЁЯУН You are here: Lesson 24 of 26 ┬╖ Previous: lesson-23-qos-evictions ┬╖ Next: lesson-25-crds-operators


ЁЯУж What's in this branch

Everything before, plus the chore every cluster owner meets ~3 times a year: upgrading Kubernetes itself without closing the school.

ЁЯзТ Explain like I'm 5

Kubernetes ships a new version three times a year, and old versions stop getting patches тАФ so upgrading isn't optional, it's scheduled renovation ЁЯПЧя╕П. The renovation rules:

  1. Office first, classrooms second. ЁЯПв Upgrade the control plane (EKS: one API call/Terraform change тАФ AWS renovates its own office invisibly), THEN the desks. Never the other way: kubelets may be a little OLDER than the office, never newer (the "version skew" rule).
  2. One classroom at a time, kids relocated politely. For each desk:
    • cordon ЁЯЪз тАФ tape on the door: "no NEW kids seated here" (kubectl cordon тАФ running kids stay put);
    • drain ЁЯЪЪ тАФ walk the kids out to other desks (kubectl drain тАФ pods rescheduled; lesson 03's monitor rebuilds them elsewhere);
    • replace the desk (managed node groups: a fresh EC2 desk with the new kubelet тАФ cattle, not renovated pets! AWS course L12);
    • uncordon тАФ tape off, next classroom.
  3. The PDBs finally perform. ЁЯН╜я╕П Lesson 15's PodDisruptionBudget is exactly what makes draining safe: "never both school-api kids out at once" тАФ the drain WAITS at each step until the class is covered. No PDB = a drain can empty your app for a moment. Now you know why we set one.
  4. Small steps only: one minor version at a time (1.31тЖТ1.32тЖТ1.33), staging cluster first, read the release notes for removed APIs (the classic breakage: a manifest using an apiVersion that's gone).

ЁЯЧ║я╕П Diagram

flowchart LR
    plan["ЁЯУЛ read release notes<br/>check deprecated APIs"]
    office["ЁЯПв 1 upgrade the office<br/>EKS control plane - one call"]
    subgraph desks["2 then desk by desk"]
        c["ЁЯЪз cordon<br/>no new kids"]
        d["ЁЯЪЪ drain<br/>kids walk out politely<br/>PDB guards the minimum ЁЯН╜я╕П"]
        r["ЁЯЦея╕П replace desk<br/>fresh EC2, new kubelet"]
        u["тЬЕ uncordon<br/>next classroom"]
        c --> d --> r --> u
    end
    plan --> office --> desks
    u -.->|"repeat per node,<br/>school never closes"| c

тЭУ What

ЁЯдФ Why

Clusters that skip upgrades become unpatchable museums, and the eventual forced triple-jump upgrade is a weekend of terror. Teams that upgrade often make it boring тАФ because every mechanism in this course (monitor, probes, PDB, multi-AZ, cattle-desks) exists precisely so that a desk can vanish at any moment on purpose. An upgrade is just scheduled chaos.

ЁЯзк Try it (safe on any local cluster)

kubectl version | head -2                       # office vs desk versions
NODE=$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')

kubectl cordon $NODE                            # ЁЯЪз tape on the door
kubectl get nodes                               # SchedulingDisabled
kubectl -n school run newkid --image=busybox -- sleep 300
kubectl -n school get pod newkid                # Pending тАФ no desk accepts new kids!

kubectl uncordon $NODE                          # tape off
kubectl -n school get pod newkid -w             # seated ЁЯОЙ  (Ctrl+C)
kubectl -n school delete pod newkid

# multi-node clusters only тАФ feel a real drain (watch the PDB hold the line):
# kubectl drain $NODE --ignore-daemonsets --delete-emptydir-data
# kubectl uncordon $NODE

ЁЯФз kubectl for this lesson

kubectl cordon/drain/uncordon ┬╖ kubectl get nodes

ЁЯФЧ Builds on: ЁЯкк AWS L12 (EKS node groups = ASGs of desks)

тЬЕ Verify тАФ what you should see

kubectl cordon NODE тЖТ SchedulingDisabled; kubectl drain waits for the PDB, then pods move; uncordon reopens it.

ЁЯз╣ Clean up

kubectl uncordon NODE тАФ don't leave a classroom taped shut

тЪая╕П Common mistakes

тПня╕П Next

How Kubernetes learns entirely NEW words тАФ the mechanism behind ArgoCD's Application and half the cloud-native world: CRDs & operators.

git checkout lesson-25-crds-operators
тЖР Previousqos evictionsNext тЖТcrds operators

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