Git, CI/CD & GitOpsXXVII · Infrastructure Repository ArchitectureRepoArch
Kubernetes repository layout — base plus per-environment, Kustomize versus Helm
What you'll learn
- Distinguish a directory-per-environment layout from a base-plus-overlays layout
- Apply the base-plus-per-environment pattern with Kustomize and with Helm
- Compare the Kustomize and Helm trade-offs for templating, environment drift, and review surface
- Recognise what to commit (sources) versus what to render (output of the templater)
Prerequisites
Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x
The Kubernetes manifest repository holds every workload that runs in a cluster. The unit of reuse is the workload, the unit of execution is the environment, and the split is base plus per-environment - common manifests plus overlays that describe how each environment differs.
Two layouts
flowchart TB
subgraph BASE["Base + overlays"]
B1["base/ (common)"]
O1["overlays/dev/"]
O2["overlays/staging/"]
O3["overlays/prod/"]
B1 --> O1
B1 --> O2
B1 --> O3
end
A directory-per-environment layout has one full set of
manifests per environment. A base-plus-overlays layout has
a base/ directory and a set of overlays/<env>/ directories
that describe what each environment changes.
The base-plus-overlays layout is the one the Kustomize and Helm ecosystems assume. The directory-per-environment layout is the one a team invents before it has heard of either tool, and it produces the worst drift: every environment’s copy of the same Deployment drifts independently.
The base-plus-per-environment pattern
The base directory holds the common manifests:
base/
deployment.yaml
service.yaml
configmap.yaml
kustomization.yaml
Each overlay is a small directory that points at the base and adds the environment-specific changes:
overlays/prod/
kustomization.yaml
replica-patch.yaml
ingress-patch.yaml
The kustomization.yaml in each overlay lists the base as a
resources: entry, then lists the patches the overlay applies.
The base holds the workload’s structure (the Deployment exists, the Service exposes port 80) and the overlays hold the variation (how many replicas, what hostname, what config values). A change to the workload is a change to the base; a change to an environment is a change to one overlay.
Kustomize versus Helm
The base-plus-overlays pattern can be implemented with either Kustomize or Helm:
flowchart LR
subgraph KZ["Kustomize"]
KB[base] --> KP[patch]
KP --> KR[rendered YAML]
end
subgraph HM["Helm"]
HC[chart] --> HV[values.yaml]
HV --> HT[Go template]
HT --> HR[rendered YAML]
end
Kustomize is patch-based. The base is plain YAML; the
overlays are patches that say “in the Deployment named web,
set replicas: 10”. There is no template language; the patch
is a structural edit. The review surface is small. Kustomize
is bundled with kubectl (kubectl apply -k overlays/prod).
Helm is template-based. The chart is YAML with Go-template
directives ({ .Values.replicas }); the values file supplies
the environment-specific values. Helm is the natural choice
when the chart is being published as a reusable artifact.
Worktrees for parallel overlay edits
The per-environment overlays are a natural fit for git worktree: a single working tree cannot hold two checked-out
versions of the same file, but two worktrees can. When a change
to the base requires simultaneous edits to the dev, staging, and
prod overlays, a worktree per overlay makes the work parallel:
git worktree add ../dev-wt -b fix/dev-overlay
git worktree add ../staging-wt -b fix/staging-overlay
git worktree add ../prod-wt -b fix/prod-overlay
Each worktree has its own branch and its own working tree, so the three overlay changes are three parallel branches.
Production discipline
- Use the base-plus-overlays layout, not directory-per-environment. The base is the unit of reuse; the overlays are the unit of variation.
- Choose the templater by team size. A small team with no external chart consumers starts on Kustomize; a large team that publishes charts uses Helm.
- Never commit rendered output. The render is a build artifact; the source of truth is the base plus the overlays.
- Pin every image by digest, not by tag. A
latesttag resolves to whatever the registry served most recently. The Kustomize patch orvalues.yamlshould pin by@sha256:...for every workload. - Use a worktree per parallel overlay edit. Two engineers editing the same overlay in the same working tree collide; two worktrees on two branches do not.
Cross-course references
- Kubernetes for Production Sysadmins - Part X (Manifests) covers the Kustomize and Helm mechanics this layout assumes.
- GitOps for Production Engineers - Part V (ArgoCD/Flux) covers the GitOps controller that consumes the overlays.
- Git Internals for Production Engineers - Part XXX covers
the
git worktree addmechanics for parallel overlay edits.
Quiz
Knowledge check · 4 questions
Q1. A Kubernetes manifest repository has a `base/` directory with the common workload, and `overlays/dev/`, `overlays/staging/`, `overlays/prod/` directories. The team is choosing between Kustomize and Helm. Which tool fits the layout the team has chosen, and what is the trade-off?
Q2. It is acceptable to commit the rendered output of `kustomize build` to the repository as a record of what was applied to production, because the render is a deterministic function of the inputs.
Q3. Name the two practical layouts for a Kubernetes manifest repository and state the layout the Kustomize and Helm ecosystems assume.
Q4. Recommend the right layout for a Kubernetes manifest repository with three environments and a small number of overlays, and explain the worktree pattern that lets two engineers edit the same overlay in parallel.
A small platform team maintains a Kubernetes manifest repository with a `base/` directory and three overlays (dev, staging, prod). Two engineers are about to edit the `overlays/prod/` overlay at the same time, one to bump a replica count and one to add a new Ingress. The team is using Kustomize.
Passing score: 75%. Answers are checked in this browser.