ЁЯПл The SchoolтА║ЁЯдЦ ArgoCDтА║ЁЯУЪ рдзрдбрд╛ 11 тАФ Helm, Kustomize рдЖрдгрд┐ environments: рдПрдХ recipe, рдЕрдиреЗрдХ рд╡рд░реНрдЧрдЦреЛрд▓реНрдпрд╛
ЁЯЦ╝я╕П See the drawing + lab ЁЯПа Course home ЁЯМ┐ Branch on GitHub тЬПя╕П View source
ЁЯЦ╝я╕П рдЖрдХреГрддреА рдЖрдгрд┐ labThe drawing + lab рдкреВрд░реНрдг рдкрд╛рдирд╛рд╡рд░ рдЙрдШрдбрд╛ тЖЧOpen full page тЖЧ

ЁЯУЪ рдзрдбрд╛ 11 тАФ Helm, Kustomize рдЖрдгрд┐ environments: рдПрдХ recipe, рдЕрдиреЗрдХ рд╡рд░реНрдЧрдЦреЛрд▓реНрдпрд╛

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 11 ┬╖ рдорд╛рдЧреАрд▓: lesson-10-rollback-history ┬╖ рдкреБрдвреАрд▓: lesson-12-secrets-and-compare


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

рдзрдбреЗ 01тАУ10, рдЖрдгрд┐ рддреНрдпрд╛рд╕реЛрдмрдд GitOps рдПрдХрд╛ namespace рдордзрд▓реНрдпрд╛ рдПрдХрд╛ app рдЪреНрдпрд╛ рдкрд▓реАрдХрдбреЗ рдХрд╕реЗ рд╡рд╛рдврддреЗ: templates (Helm / Kustomize), рдкреНрд░рддреНрдпреЗрдХ environment рдЪреНрдпрд╛ values, рдЖрдгрд┐ app-of-apps pattern.

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

рд╢рд╛рд│реЗрдд рдЖрддрд╛ рддреАрди рд╡рд░реНрдЧрдЦреЛрд▓реНрдпрд╛ рдЖрд╣реЗрдд рдЬреНрдпрд╛ рдЬрд╡рд│рдЬрд╡рд│ рд╕рд╛рд░рдЦреНрдпрд╛ рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реНрдпрд╛рдд: рд╕рд░рд╛рд╡рд╛рдЪреА рдЦреЛрд▓реА (dev), рд░рдВрдЧреАрдд рддрд╛рд▓рдореАрдЪреА рдЦреЛрд▓реА (staging), рдЖрдгрд┐ рдореЛрдард╛ рд░рдВрдЧрдордВрдЪ (prod). ЁЯЪкЁЯЪкЁЯЪк

рдЖрд░рд╛рдЦрдбреНрдпрд╛рдЪрд╛ рдЕрдзреНрдпрд╛рдп рддреАрдирджрд╛ copy рдХрд░рдгреЗ рд╣рд╛ рд╕рд╛рдкрд│рд╛ рдЖрд╣реЗ тАФ рдПрдХрд╛ copy рдордзрд▓реА рдЯрд╛рдпрдкрд┐рдВрдЧрдЪреА рдЪреВрдХ рджреБрд░реБрд╕реНрдд рдХрд░рд╛, рдмрд╛рдХреА рджреЛрди рд╡рд┐рд╕рд░рд╛, рдЖрдгрд┐ рдЦреЛрд▓реНрдпрд╛ рд╣рд│реВрд╣рд│реВ рдПрдХрдореЗрдХрд╛рдВрд╢реА рдЕрд╕рд╣рдордд рд╣реЛрддрд╛рдд (copy-paste drift!).

рддреНрдпрд╛рдкреЗрдХреНрд╖рд╛ рдЪрд╛рдВрдЧрд▓реЗ: рд░рд┐рдХрд╛рдореНрдпрд╛ рдЬрд╛рдЧрд╛ рдЕрд╕рд▓реЗрд▓реА рдПрдХ recipe рд▓рд┐рд╣рд╛ ЁЯУЪ:

"___ рдЦреБрд░реНрдЪреНрдпрд╛, projector: ___, posters: ___"

тАжрдЖрдгрд┐ рддреАрди рдЫреЛрдЯреА рднрд░рд╛рдпрдЪреА рдкрд╛рдиреЗ: рд╕рд░рд╛рд╡рд╛рдЪреА рдЦреЛрд▓реА = 1 рдЦреБрд░реНрдЪреА; рддрд╛рд▓реАрдо = 2; рдореЛрдард╛ рд░рдВрдЧрдордВрдЪ = 5 рдЦреБрд░реНрдЪреНрдпрд╛ + рдЭрдЧрдордЧреАрдд рджрд┐рд╡реЗ. рдПрдХ recipe, рддреАрди рднрд░рд▓реЗрд▓реА рдкрд╛рдиреЗ, рддреАрди рдЦреЛрд▓реНрдпрд╛. Recipe рдПрдХрджрд╛ рджреБрд░реБрд╕реНрдд рдХрд░рд╛ тЖТ рддрд┐рдиреНрд╣реА рдЦреЛрд▓реНрдпрд╛ рд╕реБрдзрд╛рд░рддрд╛рдд.

рдЖрдгрд┐ рдЬреЗрд╡реНрд╣рд╛ рддреБрдордЪреНрдпрд╛рдХрдбреЗ рджрд╣рд╛ apps ├Ч рддреАрди рдЦреЛрд▓реНрдпрд╛ рдЕрд╕рддрд╛рдд? рдЗрддрд░ рдкрд╛рдирд╛рдВрдЪреА рдпрд╛рджреА рдХрд░рдгрд╛рд░реЗ рдПрдХ рдореБрдЦреНрдп рдкрд╛рди рд▓рд┐рд╣рд╛ ЁЯУЦ тАФ рдЕрд╕реЗ Application рдЬреНрдпрд╛рдЪреНрдпрд╛ рдЕрдзреНрдпрд╛рдпрд╛рдд рдЖрдгрдЦреА Application files рдЖрд╣реЗрдд. Robot рдЪреНрдпрд╛ рд╣рд╛рддрд╛рдд рдПрдХрдЪ рдкрд╛рди рджреНрдпрд╛; рдмрд╛рдХреАрдЪреА рддреЛ рд╕реНрд╡рддрдГ рд╢реЛрдзрддреЛ. рд╣реЗрдЪ app-of-apps тАФ рд╕рдВрдкреВрд░реНрдг platforms рдПрдХрд╛рдЪ kubectl apply рдордзреВрди рдХрд╕реЗ рдЙрднреЗ рд░рд╛рд╣рддрд╛рдд.

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

flowchart LR
    recipe["ЁЯУЪ one recipe<br/>Helm chart / Kustomize base<br/>replicas: ___ image: ___"]
    dev["ЁЯУЭ values-dev<br/>replicas: 1"]
    stg["ЁЯУЭ values-staging<br/>replicas: 2"]
    prod["ЁЯУЭ values-prod<br/>replicas: 5 + HPA"]
    rdev["ЁЯЪк dev room"]
    rstg["ЁЯЪк staging room"]
    rprod["ЁЯЪк prod room"]
    master["ЁЯУЦ app-of-apps<br/>one page lists all pages"]
    recipe -->|"1"| dev --> rdev
    recipe --> stg --> rstg
    recipe --> prod --> rprod
    master -.->|"2 one Application each"| rdev
    master -.-> rstg
    master -.-> rprod

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

ЁЯдФ рдХрд╛

Copy-paste рдореБрд│реЗрдЪ config рд╕рдбрддреЗ. Templates + рдкреНрд░рддреНрдпреЗрдХ env рдЪреЗ рдЫреЛрдЯреЗ diffs рд╣реЗрддреВ ("prod рдореНрд╣рдгрдЬреЗ base + 5 replicas + HPA") рд╡рд╛рдЪрддрд╛ рдпреЗрдИрд▓ рдЖрдгрд┐ review рдХрд░рддрд╛ рдпреЗрдИрд▓ рдЕрд╕рд╛ рдареЗрд╡рддрд╛рдд. рдЖрдгрд┐ app-of-apps рдореНрд╣рдгрдЬреЗ рд╕рдВрдкреВрд░реНрдг platform рдЪреЗ disaster recovery рдЗрддрдХреЗрдЪ: ArgoCD install рдХрд░рд╛, рдПрдХ file apply рдХрд░рд╛, рдерд╛рдВрдмрд╛. тШХ

тЬЕ рдЦрдбреНрдбрд╛ 3 рдмреБрдЬрд▓рд╛. рджрд╣рд╛ clusters рдореНрд╣рдгрдЬреЗ рдЖрддрд╛ CI рдордзреНрдпреЗ рджрд╣рд╛ keys рдирд╛рд╣реАрдд: рдкреНрд░рддреНрдпреЗрдХ cluster рддреНрдпрд╛рдЪрд╛ рд╕реНрд╡рддрдГрдЪрд╛ robot рдЪрд╛рд▓рд╡рддреЛ рдЬреЛ рддреАрдЪ рд╡рд╣реА pull рдХрд░рддреЛ (рдХрд┐рдВрд╡рд╛ рдПрдХрдЪ robot рдЕрдиреЗрдХ рд╕рд╛рдВрднрд╛рд│рддреЛ тАФ рдзрдбрд╛ 06 рдордзрд▓реА рддрдбрдЬреЛрдб), рдЖрдгрд┐ app-of-apps рдореБрд│реЗ рдирд╡рд╛ cluster рдЖрдгрдЦреА рдПрдХрд╛ pipeline рдиреЗ рдирд╡реНрд╣реЗ, рддрд░ рдПрдХрд╛ file рдордзреВрди рдЙрднрд╛ рд░рд╛рд╣рддреЛ.

ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдЪрд╛ рдПрдХ Kustomize рдЖрд░рд╛рдЦрдбрд╛)

k8s/
тФЬтФАтФА base/                    # the recipe: deployment + service + ns
тФВ   тФФтФАтФА kustomization.yaml
тФФтФАтФА overlays/
    тФЬтФАтФА dev/kustomization.yaml       # replicas: 1
    тФФтФАтФА prod/kustomization.yaml      # replicas: 5

рджреЛрди Applications, path: k8s/overlays/dev рд╡рд┐рд░реБрджреНрдз .../prod рдЖрдгрд┐ destination namespace рд╕реЛрдбреВрди рдЕрдЧрджреА рд╕рд╛рд░рдЦреА. (рд╣реЗ course рдЪрд╛ рдШрд░реА рдХрд░рд╛рдпрдЪрд╛ рд╕рд░рд╛рд╡ рдореНрд╣рдгреВрди рдареЗрд╡рд▓реЗ рдЖрд╣реЗ тАФ рд▓рд╛рдЧрдгрд╛рд░реЗ рдкреНрд░рддреНрдпреЗрдХ tool рддреБрдордЪреНрдпрд╛рдХрдбреЗ рдЖрд╣реЗ.)

ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛ (2 рдорд┐рдирд┐рдЯрд╛рдВрдд Kustomize рдЕрдиреБрднрд╡рд╛, ArgoCD рдЪреА рдЧрд░рдЬ рдирд╛рд╣реА)

mkdir -p /tmp/kdemo/base /tmp/kdemo/prod
cp k8s/deployment.yaml k8s/service.yaml /tmp/kdemo/base/
printf 'resources: [deployment.yaml, service.yaml]\n' > /tmp/kdemo/base/kustomization.yaml
printf 'resources: ["../base"]\nreplicas: [{name: hello-school, count: 5}]\n' > /tmp/kdemo/prod/kustomization.yaml

kubectl kustomize /tmp/kdemo/base | grep replicas     # тЖТ 2 (the recipe)
kubectl kustomize /tmp/kdemo/prod | grep replicas     # тЖТ 5 (base + one fill-in line!)

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

kubectl kustomize /tmp/kdemo/base | grep replicas тЖТ replicas: 2; /prod рд╕рд╛рдареА рддрд╕реЗрдЪ тЖТ replicas: 5. Prod overlay рдлрдХреНрдд рджреЛрди рдУрд│реАрдВрдЪрд╛ рдЖрд╣реЗ; рдмрд╛рдХреА рд╕рдЧрд│реЗ recipe рдордзреВрди рд╡рд╛рд░рд╕рд╛ рдореНрд╣рдгреВрди рдпреЗрддреЗ.

ЁЯз╣ рд╕реНрд╡рдЪреНрдЫрддрд╛

rm -rf /tmp/kdemo. Cluster рд╡рд░ рдХрд╛рд╣реАрд╣реА apply рдХреЗрд▓реЗ рдирд╡реНрд╣рддреЗ.

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

ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: рдЦрд░реЗ platforms рдореНрд╣рдгрдЬреЗ Kustomize overlays рд╡рд░ (рдХрд┐рдВрд╡рд╛ рдкреНрд░рддреНрдпреЗрдХ environment рдЪреНрдпрд╛ values рдЕрд╕рд▓реЗрд▓реНрдпрд╛ Helm charts рд╡рд░) app-of-apps рдХрд┐рдВрд╡рд╛ ApplicationSets, рдЖрдгрд┐ рдПрдХ tag рдмрджрд▓рдгрд╛рд▒реНрдпрд╛ PRs рдиреЗ promotion. рдордЧ рд╕рдВрдкреВрд░реНрдг cluster рдЪреА desired state рдлрдХреНрдд рдПрдХрд╛ git clone рдЪреНрдпрд╛ рдЕрдВрддрд░рд╛рд╡рд░ рдЕрд╕рддреЗ тАФ disaster-recovery plan рдореНрд╣рдгрдЬреЗ kubectl apply -f root-app.yaml.

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

рд╢реЗрд╡рдЯрдЪрд╛ рдПрдХ рдбреНрд░реЕрдЧрди: secrets тАФ рдПрдХрдореЗрд╡ рдЧреЛрд╖реНрдЯ рдЬреА рд╡рд╣реАрдд рдЙрдШрдбрдкрдгреЗ рд░рд╛рд╣рддрд╛ рдХрд╛рдорд╛ рдирдпреЗ тАФ рдЖрдгрд┐ рддреНрдпрд╛рд╕реЛрдмрдд рд╢реЗрд╡рдЯрдЪреЗ push-рд╡рд┐рд░реБрджреНрдз-pull рдЧреБрдгрдкрддреНрд░рдХ.

git checkout lesson-12-secrets-and-compare

ЁЯУЪ Lesson 11 тАФ Helm, Kustomize & environments: one recipe, many classrooms

ЁЯУН You are here: Lesson 11 of 12 ┬╖ Previous: lesson-10-rollback-history ┬╖ Next: lesson-12-secrets-and-compare


ЁЯУж What's in this branch

Lessons 01тАУ10, plus how GitOps scales past one app in one namespace: templates (Helm / Kustomize), per-environment values, and the app-of-apps pattern.

ЁЯзТ Explain like I'm 5

The school now has three classrooms that should look almost the same: the practice room (dev), the dress-rehearsal room (staging), and the big stage (prod). ЁЯЪкЁЯЪкЁЯЪк

Copying the plan chapter three times is a trap тАФ fix a typo in one copy, forget the other two, and the rooms slowly disagree (copy-paste drift!).

Better: write one recipe with blanks ЁЯУЪ:

"___ chairs, projector: ___, posters: ___"

тАжand three small fill-in pages: practice room = 1 chair; rehearsal = 2; big stage = 5 chairs + fancy lights. One recipe, three fill-ins, three rooms. Fix the recipe once тЖТ all three rooms improve.

And when you have ten apps ├Ч three rooms? Write a master page that lists the other pages ЁЯУЦ тАФ an Application whose chapter contains more Application files. Hand the robot ONE page; it discovers the rest itself. That's app-of-apps тАФ how whole platforms bootstrap from a single kubectl apply.

ЁЯЧ║я╕П Diagram

flowchart LR
    recipe["ЁЯУЪ one recipe<br/>Helm chart / Kustomize base<br/>replicas: ___ image: ___"]
    dev["ЁЯУЭ values-dev<br/>replicas: 1"]
    stg["ЁЯУЭ values-staging<br/>replicas: 2"]
    prod["ЁЯУЭ values-prod<br/>replicas: 5 + HPA"]
    rdev["ЁЯЪк dev room"]
    rstg["ЁЯЪк staging room"]
    rprod["ЁЯЪк prod room"]
    master["ЁЯУЦ app-of-apps<br/>one page lists all pages"]
    recipe -->|"1"| dev --> rdev
    recipe --> stg --> rstg
    recipe --> prod --> rprod
    master -.->|"2 one Application each"| rdev
    master -.-> rstg
    master -.-> rprod

тЭУ What

ЁЯдФ Why

Copy-paste is how config rots. Templates + tiny per-env diffs keep the intent ("prod is base + 5 replicas + HPA") readable and reviewable. And app-of-apps means disaster recovery for an entire platform is: install ArgoCD, apply one file, wait. тШХ

тЬЕ Gap 3 closed. Ten clusters no longer mean ten keys in CI: each cluster runs its own robot pulling the same book (or one robot manages many тАФ lesson 06's trade-off), and app-of-apps means a new cluster bootstraps from one file, not one more pipeline.

ЁЯФз How (a Kustomize sketch of THIS repo)

k8s/
тФЬтФАтФА base/                    # the recipe: deployment + service + ns
тФВ   тФФтФАтФА kustomization.yaml
тФФтФАтФА overlays/
    тФЬтФАтФА dev/kustomization.yaml       # replicas: 1
    тФФтФАтФА prod/kustomization.yaml      # replicas: 5

Two Applications, identical except path: k8s/overlays/dev vs .../prod and the destination namespace. (Left as the course's take-home exercise тАФ you have every tool needed.)

ЁЯзк Try it (feel Kustomize in 2 minutes, no ArgoCD needed)

mkdir -p /tmp/kdemo/base /tmp/kdemo/prod
cp k8s/deployment.yaml k8s/service.yaml /tmp/kdemo/base/
printf 'resources: [deployment.yaml, service.yaml]\n' > /tmp/kdemo/base/kustomization.yaml
printf 'resources: ["../base"]\nreplicas: [{name: hello-school, count: 5}]\n' > /tmp/kdemo/prod/kustomization.yaml

kubectl kustomize /tmp/kdemo/base | grep replicas     # тЖТ 2 (the recipe)
kubectl kustomize /tmp/kdemo/prod | grep replicas     # тЖТ 5 (base + one fill-in line!)

тЬЕ Verify тАФ what you should see

kubectl kustomize /tmp/kdemo/base | grep replicas тЖТ replicas: 2; the same for /prod тЖТ replicas: 5. The prod overlay is two lines; everything else is inherited from the recipe.

ЁЯз╣ Clean up

rm -rf /tmp/kdemo. Nothing was applied to the cluster.

тЪая╕П Common mistakes

ЁЯПн Why this matters in production: real platforms are app-of-apps or ApplicationSets over Kustomize overlays (or Helm charts with per-environment values), promoted by PRs that change one tag. The whole cluster's desired state is then a git clone away тАФ the disaster-recovery plan is kubectl apply -f root-app.yaml.

тПня╕П Next

One last dragon: secrets тАФ the one thing that must NOT live plainly in the book тАФ plus the final push-vs-pull scorecard.

git checkout lesson-12-secrets-and-compare
тЖР Previousrollback historyNext тЖТsecrets and compare

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