Kustomize Overlays

After defining the base configuration with kustomization.yaml, resources, transformers, and patches, the real power of Kustomize comes from Overlays. Overlays are used to manage environment-specific configurations, such as staging, production, or development.

Instead of duplicating manifests for every environment, overlays allow us to reuse the base and only apply changes (patches, transformers, or additional manifests) where needed.


What Are Overlays?

  • An overlay is a directory that points to the base and contains a kustomization.yaml.
  • Inside this file, you can:

  • Modify base resources (e.g., scale replicas, change images).

  • Add environment-specific resources (e.g., a monitoring tool like Grafana in production).
  • Apply patches for environment-specific changes.
  • Each environment has its own overlay (e.g., /overlays/dev, /overlays/staging, /overlays/prod).

Example Directory Structure

my-app/
├── base/
│   ├── deployment.yaml
│   ├── service.yaml
│   └── kustomization.yaml
└── overlays/
    ├── dev/
    │   ├── kustomization.yaml
    │   └── dev-config.yaml      # unique to dev
    ├── staging/
    │   ├── kustomization.yaml
    │   └── ingress.yaml         # staging-specific resource
    └── prod/
        ├── kustomization.yaml
        └── grafana.yaml         # unique to prod only

Example Overlay kustomization.yaml

Production Overlay:

# Warning: 'bases' is deprecated. Please use 'resources' instead.
resources:
  - ../../base          # reference to the base
  - grafana.yaml        # unique to prod, not in base

patches:
  - target:
      kind: Deployment
      name: my-app
    patch: |-
      - op: replace
        path: /spec/replicas
        value: 5

Here:

  • The base resources are imported.
  • Grafana is added because it is only required in production.
  • A patch scales replicas from the base value to 5 in production.

Deploying with Overlays

Once overlays are defined, you can deploy environment-specific configs with one command:

kubectl apply -k overlays/dev
kubectl apply -k overlays/staging
kubectl apply -k overlays/prod

Key Points About Overlays

  • They are environment-specific configurations.
  • They can add new manifests that don’t exist in the base.
  • They can modify base manifests using patches or transformers.
  • They keep your repo organized and DRY (Don’t Repeat Yourself) by reusing the base.

Real-Time Example: Managing Multiple Environments

Imagine you are deploying a web application that has:

  • A Deployment (for the app pods)
  • A Service (to expose the app)

You need to run this app in three environments: dev, staging, and prod.

Step 1: Folder Structure

my-app/
├── base/
   ├── deployment.yaml
   ├── service.yaml
   └── kustomization.yaml
├── overlays/
   ├── dev/
      ├── kustomization.yaml
      └── dev-configmap.yaml        # only for dev
   ├── staging/
      ├── kustomization.yaml
      └── ingress.yaml              # only for staging
   └── prod/
       ├── kustomization.yaml
       └── secret.yaml               # only for prod

Step 2: Base Definition

base/deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-app
          image: nginx:latest
          ports:
            - containerPort: 80

base/service.yaml

apiVersion: v1
kind: Service
metadata:
  name: my-app-service
spec:
  selector:
    app: my-app
  ports:
    - port: 80
      targetPort: 80
  type: ClusterIP

base/kustomization.yaml

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

resources:
  - deployment.yaml
  - service.yaml

Step 3: Overlays with Unique Manifests

Dev Overlay

overlays/dev/kustomization.yaml

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

resources:
  - ../../base           # reference the base directory 
  - dev-configmap.yaml   # unique to dev, environment-specific manifest 

patches:
  - target:
      kind: Deployment
      name: my-app
    patch: |-
      - op: replace
        path: /spec/replicas
        value: 1

overlays/dev/dev-configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: dev-config
data:
  ENV: development

Staging Overlay

overlays/staging/kustomization.yaml

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

resources:
  - ../../base     # reference the base directory 
  - ingress.yaml   # unique to staging

patches:
  - target:
      kind: Deployment
      name: my-app
    patch: |-
      - op: replace
        path: /spec/replicas
        value: 2

overlays/staging/ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: staging-ingress
spec:
  rules:
    - host: staging.my-app.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-app-service
                port:
                  number: 80

Prod Overlay

overlays/prod/kustomization.yaml

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

resources:
  - ../../base    # reference the base directory
  - secret.yaml   # unique to prod

patches:
  - target:
      kind: Deployment
      name: my-app
    patch: |-
      - op: replace
        path: /spec/replicas
        value: 5

overlays/prod/secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: prod-secret
type: Opaque
data:
  DB_PASSWORD: cGFzc3dvcmQ=   # base64 encoded

Step 4: Deploying with Kustomize

To deploy in dev:

kubectl apply -k overlays/dev

To deploy in staging:

kubectl apply -k overlays/staging

To deploy in prod:

kubectl apply -k overlays/prod

👉 In summary: Overlays are the main feature of Kustomize for managing multiple environments. They let you extend or override base configurations while keeping everything centralized and maintainable.