K8s by Example: Kustomize Overlays

Overlays customize a base for different environments. Base contains shared config. Overlays add environment-specific patches, replicas, and images.

directory-structure

Standard layout: base directory with shared manifests, overlays directory with environment-specific customizations. Each overlay references the base.

k8s/
├── base/
│   ├── kustomization.yaml
│   ├── deployment.yaml
│   └── service.yaml
└── overlays/
    ├── staging/
    │   ├── kustomization.yaml
    │   └── namespace.yaml
    └── production/
        ├── kustomization.yaml
        └── namespace.yaml
base/kustomization.yaml

Base kustomization with shared resources. Contains the common configuration that all environments inherit.

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - deployment.yaml
  - service.yaml
  - configmap.yaml

commonLabels:
  app.kubernetes.io/name: my-app
overlays/production/kustomization.yaml

Overlay references base and adds customizations. Different replica counts, images, and config per environment. Namespace scopes all resources.

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - ../../base
  - namespace.yaml

namespace: production

images:
  - name: my-app
    newTag: v1.5.0

replicas:
  - name: my-app
    count: 5
overlays/production/increase-resources.yaml

Strategic merge patches modify specific fields. First section shows kustomization.yaml referencing the patch. Second section is the patch file itself (increase-resources.yaml). Only specify what changes, the rest inherits from base.

patches:
  - path: increase-resources.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  template:
    spec:
      containers:
        - name: app
          resources:
            requests:
              memory: 1Gi
            limits:
              memory: 2Gi
kustomization-jsonpatch.yaml

JSON patches for precise modifications. Use op (add, replace, remove) and path for exact field targeting. More explicit than strategic merge.

patches:
  - target:
      kind: Deployment
      name: my-app
    patch: |-
      - op: replace
        path: /spec/replicas
        value: 10
      - op: add
        path: /metadata/annotations/environment
        value: production
terminal

Deploy different environments by pointing to the overlay directory. Compare rendered output to see differences between environments.

$ kubectl apply -k overlays/staging
namespace/staging created
configmap/app-config-abc123 created
deployment.apps/my-app created
service/my-app created

$ kubectl apply -k overlays/production
namespace/production created
configmap/app-config-def456 created
deployment.apps/my-app created
service/my-app created

$ diff <(kubectl kustomize overlays/staging) \
       <(kubectl kustomize overlays/production)

Index | GitHub | Use arrow keys to navigate |