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

ЁЯОТ рдзрдбрд╛ 01 тАФ рд╣рд╛рддрд╛рдиреЗ deploy: рддреБрдореНрд╣реАрдЪ deploy system рдЖрд╣рд╛рдд

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 01 ┬╖ рдкреБрдвреЗ: lesson-02-drift-problem


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

рд╕рдВрдкреВрд░реНрдг рдХреЛрд░реНрд╕рдЪреА рд╕реБрд░реБрд╡рд╛рдд: demo app рдкреНрд░рддреНрдпреЗрдХрдЬрдг рдЬрд╕рд╛ рд╕реБрд░реБрд╡рд╛рдд рдХрд░рддреЛ рддрд╕рд╛ deploy рдХрд░рдгреЗ тАФ рд╣рд╛рддрд╛рдиреЗ, kubectl рд╡рд╛рдкрд░реВрди, рддреБрдордЪреНрдпрд╛ laptop рд╡рд░реВрди. рддреЗ рдЪрд╛рд▓рддреЗ! рдЖрдгрд┐ рд╣рд╛ рдзрдбрд╛ рд╕рдВрдкреЗрдкрд░реНрдпрдВрдд рддреБрдореНрд╣рд╛рд▓рд╛ рдиреЗрдордХреЗ рджрд┐рд╕реЗрд▓ рдХреА рддреЗ рдЕрд╕реЗрдЪ рдХрд╛ рд░рд╛рд╣реВ рд╢рдХрдд рдирд╛рд╣реА. рдЦрд▒реНрдпрд╛ files:

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

рддреБрдореНрд╣рд╛рд▓рд╛ рдЧреГрд╣рдкрд╛рда рдЬрдорд╛ рдХрд░рд╛рдпрдЪрд╛ рдЖрд╣реЗ. рдореНрд╣рдгреВрди рддреБрдореНрд╣реА рддреЛ рд╕реНрд╡рддрдГ рд╢рд╛рд│реЗрдд рдШреЗрдКрди рдЬрд╛рддрд╛ ЁЯОТ тАФ рдЖрдд рдЬрд╛рддрд╛, рд╢рд┐рдХреНрд╖рд┐рдХреЗрдЪреНрдпрд╛ рдЯреЗрдмрд▓рд╛рд╡рд░ рдареЗрд╡рддрд╛, рдЭрд╛рд▓реЗ. рдЕрдЧрджреА рдареАрдХ!

рдЖрддрд╛ рдХрд▓реНрдкрдирд╛ рдХрд░рд╛ рдХреА рд╣реЗ рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рд╖рдпрд╛рд╕рд╛рдареА, рд░реЛрдЬ, рд╕рдВрдкреВрд░реНрдг рд╡рд░реНрдЧрд╛рд╕рд╛рдареА рдХрд░рд╛рд╡реЗ рд▓рд╛рдЧрддреЗ, рдХрд╛рд░рдг рдХрд╕реЗ рдХреЛрдг рдЬрд╛рдгреЗ рддреБрдореНрд╣реАрдЪ рдЧреГрд╣рдкрд╛рда рдкреЛрд╣реЛрдЪрд╡рдгрд╛рд░реЗ рдореВрд▓ рдмрдирд▓рд╛ рдЖрд╣рд╛рдд:

рд╣рд╛рддрд╛рдиреЗ рдкреЛрд╣реЛрдЪрд╡рдгреЗ рдЪреБрдХреАрдЪреЗ рдирд╛рд╣реА тАФ рддреНрдпрд╛рддреВрдирдЪ рддреБрдореНрд╣реА рд░рд╕реНрддрд╛ рд╢рд┐рдХрддрд╛. рдкрдг рд╢реЗрд╡рдЯреА рд╣рд╛ рд░рд╕реНрддрд╛ рддреБрдордЪреНрдпрд╛рд╢рд┐рд╡рд╛рдп рдЪрд╛рд▓рд╛рдпрд▓рд╛ рд╣рд╡рд╛.

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

flowchart LR
    you["ЁЯзСтАНЁЯТ╗ your laptop<br/>YAML + kubeconfig ЁЯФС"]
    cluster["ЁЯПл cluster<br/>ЁЯкСЁЯкС hello-school pods"]
    later["ЁЯУЕ one week later<br/>тЭУ which version is live?<br/>тЭУ who changed what?<br/>ЁЯШ▒ only your memory knows"]
    you -->|"1 kubectl apply -f k8s/"| cluster
    cluster -.->|"2 works today! ЁЯОЙ"| later

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

ЁЯдФ рдХрд╛ (рд╣рд╛ рдзрдбрд╛ рдХрд╛ рдЖрд╣реЗ)

ArgoCD рдкрд╛рд╕реВрдирдЪ рд╕реБрд░реБрд╡рд╛рдд рдХрд░реВрди рддреБрдореНрд╣рд╛рд▓рд╛ ArgoCD рдЪреА рдХрд┐рдВрдордд рдХрд│рдгрд╛рд░ рдирд╛рд╣реА тАФ рддреБрдореНрд╣реА рдлрдХреНрдд рдПрдЦрд╛рджрд╛ рд╡рд┐рдзреА рдкрд╛рд│рдд рд░рд╛рд╣рд╛рд▓. рд╣рд╛ рдХреЛрд░реНрд╕ рддреБрдореНрд╣рд╛рд▓рд╛ рдкреНрд░рддреНрдпреЗрдХ рдЙрдкрд╛рдп рднреЗрдЯрдгреНрдпрд╛рдЖрдзреА рддреНрдпрд╛рдЪреА рд╕рдорд╕реНрдпрд╛ рдЕрдиреБрднрд╡рд╛рдпрд▓рд╛ рд▓рд╛рд╡рддреЛ: рдзрдбрд╛ 02 рдореВрдХ рдорд╛рд░реЗрдХрд░реА (drift) рджрд╛рдЦрд╡рддреЛ, рдзрдбрд╛ 03 рдкреЛрд╣реЛрдЪрд╡рдгреЗ automate рдХрд░рддреЛ, рдзрдбрд╛ 04 рджрд╛рдЦрд╡рддреЛ рдХреА рдЕрдЬреВрдирд╣реА рдХрд╛рдп рддреБрдЯрд▓реЗрд▓реЗ рдЖрд╣реЗ, рдЖрдгрд┐ рднрд╛рдЧ 2 рддреЗ рдиреАрдЯ рджреБрд░реБрд╕реНрдд рдХрд░рддреЛ.

ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)

Demo app рдореБрджреНрджрд╛рдо рдЕрдЧрджреА рдЫреЛрдЯреЗ рдареЗрд╡рд▓реЗ рдЖрд╣реЗ тАФ nginxdemos/hello:plain-text рдЪрд╛рд▓рд╡рдгрд╛рд░реЗ рдПрдХ Deployment (рддреЗ рддреНрдпрд╛рдЪреНрдпрд╛ pod рдЪреНрдпрд╛ рдирд╛рд╡рд╛рдиреЗ рдЙрддреНрддрд░ рджреЗрддреЗ, рдореНрд╣рдгрдЬреЗ рдХреЛрдгрддреНрдпрд╛ pod рдиреЗ рдЙрддреНрддрд░ рджрд┐рд▓реЗ рддреЗ рддреБрдореНрд╣рд╛рд▓рд╛ рдкреНрд░рддреНрдпрдХреНрд╖ рджрд┐рд╕рддреЗ), рдПрдХ Service, рдПрдХ namespace. рдХреБрдареЗрд╣реА placeholders рдирд╛рд╣реАрдд тАФ k8s/ рдордзрд▓реЗ рд╕рдЧрд│реЗ рдХреЛрдгрддреНрдпрд╛рд╣реА local cluster рд╡рд░ рдЬрд╕реЗрдЪреНрдпрд╛ рддрд╕реЗ apply рд╣реЛрддреЗ.

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

# any local cluster: Docker Desktop's Kubernetes, minikube start, or kind
kubectl apply -f k8s/
kubectl -n gitops-school get pods          # 2 pods

# see WHICH pod answers (run it a few times тАФ the name changes!):
kubectl -n gitops-school run t --rm -it --image=curlimages/curl --restart=Never \
  -- curl -s http://hello-school

# now the uncomfortable questions:
kubectl -n gitops-school get deploy hello-school -o jsonpath='{.spec.template.spec.containers[0].image}'
# ...is that what YOU think is deployed? what would your teammate say?
history | grep "kubectl apply" | tail -3   # тЖР this is your entire audit trail ЁЯШм

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

kubectl -n gitops-school get deploy,svc,pods

тЖТ hello-school 2/2 READY рдЖрд╣реЗ, рдПрдХ ClusterIP Service, рджреЛрди Running pods. рдордЧ kubectl -n gitops-school port-forward deploy/hello-school 8080:80 рдЪрд╛рд▓рд╡рд╛ рдЖрдгрд┐ curl localhost:8080 pod рдЪреНрдпрд╛ рдирд╛рд╡рд╛рд╕рд╣ hello page рдЫрд╛рдкрддреЗ.

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

рдЕрдЬреВрди рдХрд╛рд╣реАрдЪ рдХрд╛рдврд╛рдпрдЪреЗ рдирд╛рд╣реА тАФ рдзрдбреЗ 02тАУ04 рд╣реЗрдЪ deployment рдкреБрдиреНрд╣рд╛ рд╡рд╛рдкрд░рддрд╛рдд. рдЗрдереЗрдЪ рдерд╛рдВрдмрддрд╛рдп? kubectl delete namespace gitops-school.

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

ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ рдЖрд╣реЗ: рд╣рд╛рддрд╛рдиреЗ deploy рдЕрдЬреВрдирд╣реА рд╣реЛрддрд╛рдд тАФ incidents рдЪреНрдпрд╛ рд╡реЗрд│реА, рд░рд╕реНрддрд╛ рдорд╛рд╣реАрдд рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рдПрдХрд╛рдЪ рд╡реНрдпрдХреНрддреАрдХрдбреВрди. рдкреБрдврдЪрд╛ рдкреНрд░рддреНрдпреЗрдХ рдзрдбрд╛ рддреНрдпрд╛ рд╡реНрдпрдХреНрддреАрдЪреА рдЧрд░рдЬ рд╕рдВрдкрд╡рдгреНрдпрд╛рд╕рд╛рдареА рдЖрд╣реЗ; рддреЛрдкрд░реНрдпрдВрдд рдирд┐рджрд╛рди рддреЛ рд░рд╕реНрддрд╛ runbook рдореНрд╣рдгреВрди рд▓рд┐рд╣реВрди рдареЗрд╡рд╛.

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

App рдЪрд╛рд▓реВ рд░рд╛рд╣реВ рджреНрдпрд╛ тАФ рдзрдбрд╛ 02 рддреНрдпрд╛рдЪреА рдереЛрдбреА рдореЛрдбрддреЛрдб рдХрд░рдгрд╛рд░ рдЖрд╣реЗ, рд╣рд╛рддрд╛рдиреЗ рдЪрд╛рд▓рд╡рд▓реЗрд▓реНрдпрд╛ clusters рдЪрд╛ рдореВрдХ рдорд╛рд░реЗрдХрд░реА рджрд╛рдЦрд╡рдгреНрдпрд╛рд╕рд╛рдареА: drift.

git checkout lesson-02-drift-problem

ЁЯОТ Lesson 01 тАФ Deploy by hand: you ARE the deploy system

ЁЯУН You are here: Lesson 01 of 12 ┬╖ Next: lesson-02-drift-problem


ЁЯУж What's in this branch

The starting point of the whole course: deploying the demo app the way everyone starts тАФ by hand, with kubectl, from your laptop. It works! And by the end of this lesson you'll see exactly why it can't stay this way. Real files:

ЁЯзТ Explain like I'm 5

You have homework to hand in. So you carry it to school yourself ЁЯОТ тАФ walk in, put it on the teacher's desk, done. Perfectly fine!

Now imagine doing that for every subject, every day, for the whole class, because somehow you became the homework-delivery kid:

Hand-delivery isn't wrong тАФ it's how you learn the route. But the route must eventually run without you.

ЁЯЧ║я╕П Diagram

flowchart LR
    you["ЁЯзСтАНЁЯТ╗ your laptop<br/>YAML + kubeconfig ЁЯФС"]
    cluster["ЁЯПл cluster<br/>ЁЯкСЁЯкС hello-school pods"]
    later["ЁЯУЕ one week later<br/>тЭУ which version is live?<br/>тЭУ who changed what?<br/>ЁЯШ▒ only your memory knows"]
    you -->|"1 kubectl apply -f k8s/"| cluster
    cluster -.->|"2 works today! ЁЯОЙ"| later

тЭУ What

ЁЯдФ Why (this lesson exists)

You can't appreciate ArgoCD by starting with ArgoCD тАФ you'd just be following ceremony. This course makes you feel each problem before meeting its fix: lesson 02 shows the silent killer (drift), lesson 03 automates the delivery, lesson 04 shows what's still broken, and Part 2 fixes it properly.

ЁЯФз How (in this repo)

The demo app is deliberately tiny тАФ one Deployment running nginxdemos/hello:plain-text (it answers with its pod name, so you can SEE which pod replied), one Service, one namespace. No placeholders тАФ everything in k8s/ applies as-is on any local cluster.

ЁЯзк Try it

# any local cluster: Docker Desktop's Kubernetes, minikube start, or kind
kubectl apply -f k8s/
kubectl -n gitops-school get pods          # 2 pods

# see WHICH pod answers (run it a few times тАФ the name changes!):
kubectl -n gitops-school run t --rm -it --image=curlimages/curl --restart=Never \
  -- curl -s http://hello-school

# now the uncomfortable questions:
kubectl -n gitops-school get deploy hello-school -o jsonpath='{.spec.template.spec.containers[0].image}'
# ...is that what YOU think is deployed? what would your teammate say?
history | grep "kubectl apply" | tail -3   # тЖР this is your entire audit trail ЁЯШм

тЬЕ Verify тАФ what you should see

kubectl -n gitops-school get deploy,svc,pods

тЖТ hello-school is 2/2 READY, one ClusterIP Service, two Running pods. Then kubectl -n gitops-school port-forward deploy/hello-school 8080:80 and curl localhost:8080 prints the hello page with the pod's name in it.

ЁЯз╣ Clean up

Nothing to remove yet тАФ lessons 02тАУ04 reuse this deployment. Stopping here? kubectl delete namespace gitops-school.

тЪая╕П Common mistakes

ЁЯПн Why this matters in production: hand deploys still happen тАФ during incidents, by the one person who knows the route. Every later lesson exists to make that person unnecessary; until then, at least keep the route written down as a runbook.

тПня╕П Next

Leave the app running тАФ lesson 02 is going to vandalize it a little, to show you the silent killer of hand-run clusters: drift.

git checkout lesson-02-drift-problem
тЖР Course homeall lessonsNext тЖТdrift problem

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