ЁЯПл The SchoolтА║ЁЯдЦ ArgoCDтА║ЁЯЪк рдзрдбрд╛ 04 тАФ Push рдЪреНрдпрд╛ рдорд░реНрдпрд╛рджрд╛: courier рдкреЛрд╣реЛрдЪрд╡рддреЛтАж рдЖрдгрд┐ рдирд┐рдШреВрди рдЬрд╛рддреЛ
ЁЯЦ╝я╕П See the drawing + lab ЁЯПа Course home ЁЯМ┐ Branch on GitHub тЬПя╕П View source
ЁЯЦ╝я╕П рдЖрдХреГрддреА рдЖрдгрд┐ labThe drawing + lab рдкреВрд░реНрдг рдкрд╛рдирд╛рд╡рд░ рдЙрдШрдбрд╛ тЖЧOpen full page тЖЧ

ЁЯЪк рдзрдбрд╛ 04 тАФ Push рдЪреНрдпрд╛ рдорд░реНрдпрд╛рджрд╛: courier рдкреЛрд╣реЛрдЪрд╡рддреЛтАж рдЖрдгрд┐ рдирд┐рдШреВрди рдЬрд╛рддреЛ

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 04 тАФ рднрд╛рдЧ 1 рдЪрд╛ рд╢реЗрд╡рдЯ ┬╖ рдорд╛рдЧреЗ: lesson-03-cicd-push ┬╖ рдкреБрдвреЗ: lesson-05-gitops-idea


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

рдзрдбреЗ 01тАУ03, рдЖрдгрд┐ рддреНрдпрд╛рд╕реЛрдмрдд push model рдЪреЗ рдкреНрд░рд╛рдорд╛рдгрд┐рдХ рдкрд░реАрдХреНрд╖рдг тАФ рдЕрд╕реЗ рдЪрд╛рд░ рдЦрдбреНрдбреЗ рдЬреЗ рдХрд┐рддреАрд╣реА рдЪрд╛рдВрдЧрд▓реА pipeline рдмрдирд╡рд▓реА рддрд░реА рдмреБрдЬрдд рдирд╛рд╣реАрдд. рд╣реЗрдЪ рднрд╛рдЧ 2 рдордзреНрдпреЗ рдЬрд╛рдгреНрдпрд╛рдЪреЗ рджрд╛рд░ рдЖрд╣реЗ.

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

Courier robot ЁЯУо рдЦрд░реЛрдЦрд░рдЪ рдЫрд╛рди рдЖрд╣реЗ. рдкрдг 14:04 рд▓рд╛ рдХрд╛рдп рд╣реЛрддреЗ рддреЗ рдкрд╛рд╣рд╛, рдореНрд╣рдгрдЬреЗ рддреЛ рдкреЛрд╣реЛрдЪрд╡реВрди рдирд┐рдШреВрди рдЧреЗрд▓реНрдпрд╛рд╡рд░ рдПрдХрд╛ рдорд┐рдирд┐рдЯрд╛рдиреЗ:

  1. рдЦреЛрд▓реАрд╡рд░ рдХреЛрдгреАрдЪ рд▓рдХреНрд╖ рдареЗрд╡рдд рдирд╛рд╣реА. ЁЯкС 15:00 рд▓рд╛ рдПрдХ рдореВрд▓ рдЦреБрд░реНрдЪреНрдпрд╛рдВрдЪреА рдЬрд╛рдЧрд╛ рдмрджрд▓рддреЗ (drift, рдзрдбрд╛ 02!). Courier? рддреЛ рдХрдзреАрдЪ рдЧреЗрд▓рд╛. рдХреЛрдгреА рдирд╡рд╛ рдЧреГрд╣рдкрд╛рда рдЯрдкрд╛рд▓рд╛рдд рдЯрд╛рдХрд▓рд╛ рддрд░рдЪ рддреЛ рдкрд░рдд рдпреЗрддреЛ тАФ рдХрджрд╛рдЪрд┐рдд рдкреБрдврдЪреНрдпрд╛ рдордВрдЧрд│рд╡рд╛рд░реА. рддреЛ рдкрд╕рд╛рд░рд╛ рдХрд┐рддреНрдпреЗрдХ рджрд┐рд╡рд╕ рдХреЛрдгрд╛рдЪреНрдпрд╛ рд▓рдХреНрд╖рд╛рдд рди рдпреЗрддрд╛ рддрд╕рд╛рдЪ рдкрдбреВрди рд░рд╛рд╣рддреЛ.
  2. Courier рд▓рд╛ рдмрд╛рд╣реЗрд░реВрди рдЖрдд рдпреЗрдгреНрдпрд╛рдЪрд╛ рдорд╛рд░реНрдЧ рд▓рд╛рдЧрддреЛ. ЁЯФС рдкреЛрд╣реЛрдЪрд╡рдгреНрдпрд╛рд╕рд╛рдареА courier рд▓рд╛ deployment credentials рдорд┐рд│рд╡рд╛рд╡реЗ рд▓рд╛рдЧрддрд╛рдд тАФ рд╕рдЧрд│реНрдпрд╛рдд рд╡рд╛рдИрдЯ рдореНрд╣рдгрдЬреЗ рддреНрдпрд╛рдЪреНрдпрд╛ рдЧрд╛рдбреАрдд рдареЗрд╡рд▓реЗрд▓реА рдЪрд╛рд╡реАрдЪреА рдирдХреНрдХрд▓ (CI рдордзреНрдпреЗ рд╕рд╛рдард╡рд▓реЗрд▓реЗ kubeconfig), рд╕рдЧрд│реНрдпрд╛рдд рдЪрд╛рдВрдЧрд▓реЗ рдореНрд╣рдгрдЬреЗ рдереЛрдбреНрдпрд╛ рдХрд╛рд│рд╛рдЪрд╛ badge (OIDC, рдЬрд╕реЗ CI/CD рд╢рд╛рд│рд╛ рд╢рд┐рдХрд╡рддреЗ). рдереЛрдбреНрдпрд╛ рдХрд╛рд│рд╛рдЪреЗ рдЦреВрдкрдЪ рдЪрд╛рдВрдЧрд▓реЗ тАФ рдкрдг рд░рд╕реНрддреНрдпрд╛рдХрдбреВрди рдЙрдШрдбрдгрд╛рд░реЗ рджрд╛рд░ рддрд░реАрд╣реА рдЕрд╕реНрддрд┐рддреНрд╡рд╛рдд рдЕрд╕рд╛рд╡реЗрдЪ рд▓рд╛рдЧрддреЗ, рдорд░реНрдпрд╛рджрд┐рдд рдХрд░рд╛рд╡реЗ рд▓рд╛рдЧрддреЗ, рдЖрдгрд┐ рддреНрдпрд╛рд╡рд░ рд▓рдХреНрд╖ рдареЗрд╡рд╛рд╡реЗ рд▓рд╛рдЧрддреЗ.
  3. рджрд╣рд╛ рд╢рд╛рд│рд╛? рдЧрд╛рдбреАрдд рджрд╣рд╛ рдЪрд╛рд╡реНрдпрд╛. ЁЯПлЁЯПлЁЯПл рдкреНрд░рддреНрдпреЗрдХ рдирд╡рд╛ cluster = CI рдордзреНрдпреЗ рдЖрдгрдЦреА рдПрдХ credential, рдЖрдгрдЦреА рдПрдХ pipeline config, рдмрджрд▓рдд рд░рд╛рд╣рд╛рдпрдЪреА рдЖрдгрдЦреА рдПрдХ рдЧреЛрд╖реНрдЯ.
  4. рдкреЛрд╣реЛрдЪрд╡рдгреНрдпрд╛рдЪреА рдиреЛрдВрджрд╡рд╣реА рдЯрдкрд╛рд▓рдЦреЛрд▓реАрдд рдЖрд╣реЗ, рд╢рд╛рд│реЗрдд рдирд╛рд╣реА. ЁЯз╛ "рдЖрддреНрддрд╛ рдЦреЛрд▓реА 3B рдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ?" рдпрд╛рдЪреЗ рдЙрддреНрддрд░ рджреЗрддрд╛рдирд╛ CI history рдХрд╛рдп рдкрд╛рдард╡рд▓реЗ рддреЗ рджрд╛рдЦрд╡рддреЗ тАФ рдкреНрд░рддреНрдпрдХреНрд╖рд╛рдд рддрд┐рдереЗ рдХрд╛рдп рдЖрд╣реЗ рддреЗ рдирд╛рд╣реА (рдЦрдбреНрдбрд╛ #1 рдкрд╛рд╣рд╛).

рдпрд╛ рд╕рдВрдкреВрд░реНрдг рдХреЛрд░реНрд╕рдЪреЗ рдорд░реНрдо: рдЙрдкрд╛рдп рдореНрд╣рдгрдЬреЗ рдЕрдзрд┐рдХ рдЪрд╛рдВрдЧрд▓рд╛ courier рдирд╛рд╣реА. рддрд░ рд╢рд╛рд│реЗрддрдЪ рд░рд╛рд╣рдгрд╛рд░рд╛ рдкрд╣рд╛рд░реЗрдХрд░реА, рдЬреЛ рдЦреЛрд▓реНрдпрд╛рдВрдЪреА рдЖрд░рд╛рдЦрдбреНрдпрд╛рд╢реА рддреБрд▓рдирд╛ рдХрд░рдгреЗ рдХрдзреАрдЪ рдерд╛рдВрдмрд╡рдд рдирд╛рд╣реА.

ЁЯЪк Push рдЪреЗ рдЪрд╛рд░ рдЦрдбреНрдбреЗ тАФ рдХреНрд░рдорд╛рдВрдХ рд▓рдХреНрд╖рд╛рдд рдареЗрд╡рд╛; рднрд╛рдЧ 2 рддреЗ рдПрдХреЗрдХ рдХрд░реВрди рдмреБрдЬрд╡рддреЛ: рдЦрдбреНрдбрд╛ 1 тАФ рджреЛрди deploys рдордзрд▓рд╛ drift рдЕрджреГрд╢реНрдп рдЕрд╕рддреЛ тЖТ рдзрдбрд╛ 09 рдордзреНрдпреЗ рдмреБрдЬрддреЛ (selfHeal) рдЦрдбреНрдбрд╛ 2 тАФ deployment credentials рдмрд╛рд╣реЗрд░реВрди рдпрд╛рд╡реЗ рд▓рд╛рдЧрддрд╛рдд тЖТ рдзрдбрд╛ 07 рдордзреНрдпреЗ рдмреБрдЬрддреЛ (robot рдЖрддреВрди pull рдХрд░рддреЛ) рдЦрдбреНрдбрд╛ 3 тАФ рдкреНрд░рддреНрдпреЗрдХ рдЬрд╛рд╕реНрддреАрдЪрд╛ cluster keys рдЖрдгрд┐ pipelines рд╡рд╛рдврд╡рддреЛ тЖТ рдзрдбрд╛ 11 рдордзреНрдпреЗ рдмреБрдЬрддреЛ (рдПрдХ рд╡рд╣реА, рдкреНрд░рддреНрдпреЗрдХ cluster рд╕рд╛рдареА рдПрдХ robot) рдЦрдбреНрдбрд╛ 4 тАФ рдкреЛрд╣реЛрдЪрд╡рдгреНрдпрд╛рдЪреА рдиреЛрдВрджрд╡рд╣реА рдореНрд╣рдгрдЬреЗ live рд╕рддреНрдп рдирд╛рд╣реА тЖТ рдзрдбрд╛ 10 рдордзреНрдпреЗ рдмреБрдЬрддреЛ (Synced = рдЦреЛрд▓реА рдкрд╛рдирд╛рд╢реА рдЬреБрд│рддреЗ; sync history рдХрдзреА рддреЗ рд╕рд╛рдВрдЧрддреЗ)

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

flowchart LR
    ci["ЁЯУо pipeline run<br/>deploys at 14:03<br/>then EXITS"]
    cluster["ЁЯПл cluster at 14:04+<br/>unguarded until the next push"]
    ci -->|"1 delivery moment - all good"| cluster
    cluster -.-> d1["2 ЁЯкС drift creeps back<br/>nobody notices"]
    cluster -.-> d2["3 ЁЯФС deploy credentials needed<br/>from OUTSIDE - short-lived at best"]
    cluster -.-> d3["4 ЁЯПл├Ч10 clusters =<br/>10 keys, 10 configs"]

тЭУ рдХрд╛рдп (рдЪрд╛рд░ рдЦрдбреНрдбреЗ, рдиреЗрдордХреЗрдкрдгрд╛рдиреЗ)

# рдЦрдбреНрдбрд╛ Pipeline рддреЛ рдХрд╛ рдмреБрдЬрд╡реВ рд╢рдХрдд рдирд╛рд╣реА
1 рджреЛрди push рдЪреНрдпрд╛ рдордзреНрдпреЗ drift рдкрд░рдд рдпреЗрддреЛ Pipeline deploy рдЪреНрдпрд╛ рдХреНрд╖рдгреА рдЪрд╛рд▓рддреЗ; drift рдордзрд▓реНрдпрд╛ рдХрд╛рд│рд╛рдд рд╣реЛрддреЛ
2 Deployment credentials рдмрд╛рд╣реЗрд░реВрди рдорд┐рд│рд╡рд▓реЗ рдЬрд╛рддрд╛рдд Push рд▓рд╛ рд░рд╕реНрддреНрдпрд╛рд╡рд░реВрди рдЪрд╛рд▓рдгрд╛рд░реЗ credentials рд▓рд╛рдЧрддрд╛рдд тАФ OIDC рд╕рд╣ рдереЛрдбреНрдпрд╛ рдХрд╛рд│рд╛рдЪреЗ, рдкрдг рдмрд╛рд╣реЗрд░реВрди рдЖрдд рдЙрдШрдбрдгрд╛рд░реЗ рджрд╛рд░ рд╣реЗрдЪ рддрд░ model рдЖрд╣реЗ
3 рдЕрдиреЗрдХ clusters рдЪрд╛ рдкрд╕рд╛рд░рд╛ рдкреНрд░рддреНрдпреЗрдХ target рд▓рд╛ CI рдордзреНрдпреЗ рд╕реНрд╡рддрдГрдЪреА key + config рд▓рд╛рдЧрддреЗ
4 Live source of truth рдирд╛рд╣реА CI logs рдХрд╛рдп рдкрд╛рдард╡рд▓реЗ рддреЗ рд╕рд╛рдВрдЧрддрд╛рдд, рдЖрддреНрддрд╛ рдХрд╛рдп рдЪрд╛рд▓реВ рдЖрд╣реЗ рддреЗ рдирд╛рд╣реА

ЁЯдФ рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ рдЖрд╣реЗ

рдкреНрд░рддреНрдпреЗрдХ рдЦрдбреНрдбрд╛ рдПрдХрдЯрд╛ рддреНрд░рд╛рд╕рджрд╛рдпрдХ рдЖрд╣реЗ; рд╕рдЧрд│реЗ рдорд┐рд│реВрди "pipeline рд╣рд┐рд░рд╡реА рдЖрд╣реЗ рдкрдг prod рддреБрдЯрд▓реЗрд▓реЗ рдЖрд╣реЗ" рд╣рд╛ meme рдХрд╛ рдмрдирд▓рд╛ рддреНрдпрд╛рдЪреЗ рдХрд╛рд░рдг рдЖрд╣реЗрдд. рдЦрдбреНрдбрд╛ #1 рдореНрд╣рдгрдЬреЗ рдкреБрдиреНрд╣рд╛ рдзрдбрд╛ 02 тАФ automation рдиреЗ drift рд╕рдВрдкрд╡рд▓рд╛ рдирд╛рд╣реА, рдлрдХреНрдд deploys рдЫрд╛рди рдХреЗрд▓реЗ. рдЦрдбреНрдбрд╛ #2 рдореБрд│реЗ security teams рдЪреА рдЭреЛрдк рдЙрдбрддреЗ. рдЖрдгрд┐ рдЦрдбреНрдбрд╛ #4 рдореНрд╣рдгрдЬреЗ incident рджрд░рдореНрдпрд╛рди рддреБрдореНрд╣реА рдЕрд╢рд╛ рджреЛрди sources of truth рдЪрд╛ debugging рдХрд░рдд рдЕрд╕рддрд╛ рдЬреНрдпрд╛ рджреЛрдиреНрд╣реА рдЦреЛрдЯреЗ рдмреЛрд▓рдд рдЕрд╕реВ рд╢рдХрддрд╛рдд.

ЁЯФз рдХрд╕реЗ (рдЦрдбреНрдбрд╛ #1 рдЖрддреНрддрд╛рдЪ рдЕрдиреБрднрд╡рд╛)

# the "pipeline" (you, lesson 03) deployed replicas: 2. Now, at "15:00":
kubectl -n gitops-school scale deployment hello-school --replicas=1

# question: what will tell you about this? answer: NOTHING.
# no alert, no status, no robot. It sits like this until the next push.
kubectl -n gitops-school get deploy hello-school     # 1/1 тАФ silently degraded

рднрд╛рдЧ 2 рдЖрдзреА рддреЗ рдкрд░рдд рджреБрд░реБрд╕реНрдд рдХрд░рд╛: kubectl apply -f k8s/

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

scale --replicas=1 рдирдВрддрд░: kubectl -n gitops-school get deploy hello-school 1/1 рджрд╛рдЦрд╡рддреЗ рдЖрдгрд┐ рдмрд╛рдХреА рдХрд╛рд╣реАрдЪ рдШрдбрдд рдирд╛рд╣реА тАФ рдХреЛрдгрддрд╛рд╣реА event, alert, status рдХреБрдареЗрд╣реА "рд╣реЗ git рд╕рд╛рдВрдЧрддреЗ рддрд╕реЗ рдирд╛рд╣реА" рдЕрд╕реЗ рдореНрд╣рдгрдд рдирд╛рд╣реА. рддреА рд╢рд╛рдВрддрддрд╛рдЪ рдкреБрд░рд╛рд╡рд╛ рдЖрд╣реЗ.

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

kubectl apply -f k8s/ рднрд╛рдЧ 2 рдЖрдзреА replicas: 2 рдкрд░рдд рдЖрдгрддреЗ (рддрд╕реЗрд╣реА рдзрдбрд╛ 07 namespace delete рдХрд░рддреЛ).

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

ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ рдЖрд╣реЗ: teams рд╡рд░реНрд╖рд╛рдиреБрд╡рд░реНрд╖реЗ process рдЬреЛрдбреВрди рд╣реЗ рдЪрд╛рд░ рдЦрдбреНрдбреЗ рд╕рд╣рди рдХрд░рдд рдЬрдЧрддрд╛рдд: change tickets, deploy windows, kubeconfig рдХреЛрдгрд╛рдХрдбреЗ рдЖрд╣реЗ рдпрд╛рдЪреА spreadsheet. рдкреНрд░рддреНрдпреЗрдХ рдореНрд╣рдгрдЬреЗ рд░рдЪрдиреЗрддрд▓реНрдпрд╛ рднреЛрдХрд╛рд╡рд░ рдорд╛рдгрд╕рд╛рдиреЗ рд▓рд╛рд╡рд▓реЗрд▓реЗ рдард┐рдЧрд│. рдард┐рдЧрд│ рд╡рд┐рдХрдд рдШреЗрдгреНрдпрд╛рдЖрдзреА рдЦрдбреНрдбреНрдпрд╛рд▓рд╛ рдирд╛рд╡ рджреНрдпрд╛.

тПня╕П рдкреБрдвреЗ тАФ рднрд╛рдЧ 2 рд╕реБрд░реВ рд╣реЛрддреЛ

рдЖрддрдЪ рд░рд╛рд╣рдгрд╛рд░рд╛, рдмрд╛рд╣реЗрд░рдЪреА рдХреЛрдгрддреАрд╣реА key рди рдмрд╛рд│рдЧрдгрд╛рд░рд╛, рдЖрдгрд┐ рдЦреЛрд▓реНрдпрд╛рдВрдЪреА рдЖрд░рд╛рдЦрдбреНрдпрд╛рд╢реА рддреБрд▓рдирд╛ рджрд░ рдХрд╛рд╣реА рдорд┐рдирд┐рдЯрд╛рдВрдиреА, рдХрд╛рдпрдо рдХрд░рдгрд╛рд░рд╛ рдкрд╣рд╛рд░реЗрдХрд░реА. рдЖрдзреА, рдирд╛рд╡ рдЕрд╕рд▓реЗрд▓реА рдХрд▓реНрдкрдирд╛: GitOps. (рдЧреБрдгрдкрддреНрд░рдХ рдЖрддреНрддрд╛рдЪ рд╣рд╡реЗ? рдХреЛрд░реНрд╕рдЪреНрдпрд╛ рдореБрдЦреНрдп рдкрд╛рдирд╛рд╡рд░ push-рд╡рд┐рд░реБрджреНрдз-pull рдЧреБрдгрдкрддреНрд░рдХ рдЖрд╣реЗ; рдзрдбрд╛ 12 рд╢реЗрд╡рдЯрдЪрд╛ рд╕реНрддрдВрдн рдЯрд┐рдкреНрдкрдгреАрд╕рд╣ рднрд░рддреЛ.)

git checkout lesson-05-gitops-idea

ЁЯЪк Lesson 04 тАФ Limits of push: the courier deliversтАж and LEAVES

ЁЯУН You are here: Lesson 04 of 12 тАФ end of Part 1 ┬╖ Previous: lesson-03-cicd-push ┬╖ Next: lesson-05-gitops-idea


ЁЯУж What's in this branch

Lessons 01тАУ03, plus the honest audit of the push model тАФ the four gaps that no amount of better pipeline fixes. This is the door into Part 2.

ЁЯзТ Explain like I'm 5

The courier robot ЁЯУо is genuinely great. But watch what happens at 14:04, one minute after it delivered and drove away:

  1. Nobody is watching the room. ЁЯкС A kid rearranges the chairs at 15:00 (drift, lesson 02!). The courier? Already gone. It only comes back when someone mails new homework тАФ maybe next Tuesday. The mess sits there unnoticed for days.
  2. The courier needs a way in from outside. ЁЯФС To deliver, the courier must obtain deployment credentials тАФ a copied key kept in its van at worst (a kubeconfig stored in CI), a short-lived badge at best (OIDC, as the CI/CD school teaches). Short-lived is much better тАФ but a door that opens from the street still has to exist, be scoped, and be watched.
  3. Ten schools? Ten keys in the van. ЁЯПлЁЯПлЁЯПл Every new cluster = another credential in CI, another pipeline config, another thing to rotate.
  4. The delivery log is in the mailroom, not the school. ЁЯз╛ To answer "what's in Room 3B right now?", CI history shows what was sent тАФ not what's actually there (see gap #1).

The insight of this whole course: the fix is not a better courier. It's a guard who lives in the school and never stops comparing rooms to the plan.

ЁЯЪк The four gaps of push тАФ memorise the numbers; Part 2 closes them one by one: Gap 1 тАФ drift between deploys is invisible тЖТ closed in lesson 09 (selfHeal) Gap 2 тАФ deployment credentials must come from outside тЖТ closed in lesson 07 (the robot pulls from inside) Gap 3 тАФ every extra cluster multiplies keys and pipelines тЖТ closed in lesson 11 (one book, one robot per cluster) Gap 4 тАФ the delivery log is not the live truth тЖТ closed in lesson 10 (Synced = room matches page; sync history says when)

ЁЯЧ║я╕П Diagram

flowchart LR
    ci["ЁЯУо pipeline run<br/>deploys at 14:03<br/>then EXITS"]
    cluster["ЁЯПл cluster at 14:04+<br/>unguarded until the next push"]
    ci -->|"1 delivery moment - all good"| cluster
    cluster -.-> d1["2 ЁЯкС drift creeps back<br/>nobody notices"]
    cluster -.-> d2["3 ЁЯФС deploy credentials needed<br/>from OUTSIDE - short-lived at best"]
    cluster -.-> d3["4 ЁЯПл├Ч10 clusters =<br/>10 keys, 10 configs"]

тЭУ What (the four gaps, precisely)

# Gap Why the pipeline can't fix it
1 Drift returns between pushes The pipeline runs at deploy moments; drift happens in the gaps
2 Deployment credentials obtained from outside Push needs credentials that work from the street тАФ short-lived with OIDC, but the outside-in door is the model
3 Multi-cluster sprawl Each target needs its own key + config in CI
4 No live source of truth CI logs say what was sent, not what's running now

ЁЯдФ Why this matters

Each gap is annoying alone; together they're why "the pipeline is green but prod is broken" is a meme. Gap #1 is lesson 02 all over again тАФ automation didn't kill drift, it just made deploys nicer. Gap #2 is the one security teams lose sleep over. And gap #4 means that during an incident, you're debugging two sources of truth that both might be lying.

ЁЯФз How (feel gap #1 right now)

# the "pipeline" (you, lesson 03) deployed replicas: 2. Now, at "15:00":
kubectl -n gitops-school scale deployment hello-school --replicas=1

# question: what will tell you about this? answer: NOTHING.
# no alert, no status, no robot. It sits like this until the next push.
kubectl -n gitops-school get deploy hello-school     # 1/1 тАФ silently degraded

Fix it back before Part 2: kubectl apply -f k8s/

тЬЕ Verify тАФ what you should see

After scale --replicas=1: kubectl -n gitops-school get deploy hello-school shows 1/1 and nothing else happens тАФ no event, no alert, no status anywhere says "this is not what git says". That silence is the exhibit.

ЁЯз╣ Clean up

kubectl apply -f k8s/ restores replicas: 2 before Part 2 (lesson 07 deletes the namespace anyway).

тЪая╕П Common mistakes

ЁЯПн Why this matters in production: teams live with these four gaps for years by adding process: change tickets, deploy windows, a spreadsheet of who holds the kubeconfig. Each is a human patch over a structural hole. Name the gap before buying the patch.

тПня╕П Next тАФ Part 2 begins

A guard who lives inside, holds no outside key, and compares the rooms to the plan every few minutes, forever. First, the idea with a name: GitOps. (Want the scorecard now? The course home has the push-vs-pull scorecard; lesson 12 fills in the last column with commentary.)

git checkout lesson-05-gitops-idea
тЖР Previouscicd pushNext тЖТgitops idea

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