Kustomize in Kubernetes: Managing Multiple Environments with Transformers

Introduction
One of the biggest challenges in Kubernetes is managing the same application across multiple environments such as Development, Staging, and Production.
At first, teams often solve this by maintaining separate YAML files for each environment:
dev-deployment.yaml
staging-deployment.yaml
prod-deployment.yaml
While this works initially, it quickly becomes difficult to maintain.
Imagine updating:
Container images
Labels
Resource limits
Replica counts
Namespaces
across dozens of files.
This leads to:
❌ Configuration drift
❌ Duplicate manifests
❌ Increased maintenance effort
❌ Higher risk of deployment mistakes
This is the problem Kustomize was built to solve.
Kustomize in Kubernetes: Base and Overlay Explained
As Kubernetes deployments grow, managing separate YAML files for Development, Staging, and Production quickly becomes difficult.
Imagine maintaining the same Deployment, Service, ConfigMap, and Secret definitions for multiple environments. The only difference might be:
Replica count
Image version
Resource limits
Configuration values
Copying and maintaining separate YAML files for every environment leads to duplication, configuration drift, and operational headaches.
This is the exact problem Kustomize was designed to solve.
What is Kustomize?
Kustomize is a Kubernetes-native configuration management tool that allows you to customize Kubernetes manifests without modifying the original YAML files.
Unlike Helm, Kustomize does not use templates.
Instead, it works with:
A shared Base
Environment-specific Overlays
The result is a clean, reusable, and easy-to-maintain Kubernetes configuration structure.
One major advantage is that Kustomize is built directly into kubectl, so no additional installation is required for most use cases.
kubectl apply -k .
The Problem Kustomize Solves
Consider an application deployed to three environments:
Development:
replicas: 1
Staging:
replicas: 2
Production:
replicas: 5
Without Kustomize, you would typically maintain three separate Deployment files.
That means if you update:
Container image
Labels
Ports
Resource limits
You must update all three files.
This duplication increases maintenance effort and introduces risk.
Kustomize eliminates this by keeping a single source of truth and applying only environment-specific changes where needed.
Base and Overlay Architecture
Kustomize follows a simple structure:
Base
The base contains common Kubernetes resources shared by all environments.
Example:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
component: nginx
template:
metadata:
labels:
component: nginx
spec:
containers:
- name: nginx
image: nginx
The base acts as the foundation.
Overlays
Overlays contain only the changes required for a specific environment.
Development
spec:
replicas: 1
Staging
spec:
replicas: 1
Production
spec:
replicas: 5
Each environment reuses the same base configuration while applying its own customizations.
Recommended Folder Structure
A common Kustomize project structure looks like:
k8s/
├── base/
│ ├── deployment.yaml
│ ├── service.yaml
│ └── kustomization.yaml
│
└── overlays/
├── dev/
│ └── kustomization.yaml
│
├── stg/
│ └── kustomization.yaml
│
└── prod/
└── kustomization.yaml
Base
Contains resources shared across environments.
Overlays
Contain environment-specific modifications.
This structure keeps Kubernetes manifests organized and scalable as applications grow.
Understanding the kustomization.yaml File
The heart of Kustomize is the kustomization.yaml file.
It tells Kustomize:
Which resources to manage
Which customizations to apply
Example:
resources:
- deployment.yaml
- service.yaml
commonLabels:
app: nginx
In this example:
Deployment and Service are included
A common label is added to all resources
Think of kustomization.yaml as the entry point for Kustomize processing.
Building Kubernetes Manifests
Kustomize does not directly deploy resources.
Instead, it generates the final YAML after applying all customizations.
kustomize build k8s/
This command outputs the fully rendered Kubernetes manifests.
Applying Kustomize Configurations
You can pipe the output to kubectl:
kustomize build k8s/ | kubectl apply -f -
Or use the built-in kubectl integration:
kubectl apply -k k8s/
This is the most common approach used in modern Kubernetes workflows.
Deleting Resources Managed by Kustomize
Just as easily, you can remove resources:
kubectl delete -k k8s/
or
kustomize build k8s/ | kubectl delete -f -
Managing Large Applications
As applications grow, a single folder becomes difficult to maintain.
Instead, resources can be organized by component.
Example:
k8s/
├── api/
├── db/
├── cache/
└── kafka/
Each directory contains its own manifests.
A top-level kustomization.yaml can then aggregate everything:
resources:
- api/
- db/
- cache/
- kafka/
This creates a modular and scalable structure for large Kubernetes applications.
Kustomize vs Helm
A common question is:
Why use Kustomize when Helm already exists?
Kustomize
✅ Built into kubectl
✅ Uses plain YAML
✅ Easier to read and review
✅ No templating language to learn
Helm
✅ Package manager for Kubernetes
✅ Supports loops and conditionals
✅ Supports chart repositories
✅ Better for distributing applications
A simple rule of thumb:
Use Kustomize when customizing existing manifests across environments.
Use Helm when packaging and distributing applications.
Many organizations actually use both together.
Kustomize Transformers
Once resources are organized, Kustomize provides Transformers to apply bulk changes across all resources.
Transformers eliminate the need to edit every manifest individually.
Common Labels Transformer
Labels are frequently used for:
Ownership
Cost allocation
Environment tracking
Governance
Instead of adding labels manually:
commonLabels:
org: my-company
Kustomize injects the label across all managed resources.
Result
metadata:
labels:
org: my-company
This also updates selectors where appropriate.
Namespace Transformer
Deploying resources into a namespace often requires editing every YAML file.
Kustomize can do this automatically.
namespace: production
Result
metadata:
namespace: production
Every resource receives the namespace.
CommonAnnotations Transformer
Annotations store metadata that is not used for resource selection.
Examples:
Git commit IDs
Build numbers
Deployment timestamps
Branch names
Configuration:
annotations:
branch: main
Result:
metadata:
annotations:
branch: main
A CI/CD pipeline can dynamically inject:
commonAnnotations:
build-number: "105"
git-commit: "abc123"
making deployments fully traceable.
Name Prefix Transformer
Add a common prefix to all resources.
Configuration:
namePrefix: company-
Before:
name: api-service
After:
name: company-api-service
Name Suffix Transformer
Add a common suffix to all resources.
Configuration:
nameSuffix: -prod
Before:
name: api-service
After:
name: api-service-prod
Combining Prefix and Suffix
Both can be combined:
namePrefix: company-
nameSuffix: -dev
Result:
name: company-api-service-dev
This is useful for enforcing naming standards across environments.
Image Transformer
One of the most powerful Kustomize features is image management.
Suppose your Deployment contains:
containers:
- image: nginx
You can update the image version without modifying the Deployment file.
Updating Tags
images:
- name: nginx
newTag: "2.4"
Result:
image: nginx:2.4
Perfect for CI/CD pipelines where image tags change frequently.
Replacing Images
Kustomize can also replace an image entirely.
Configuration:
images:
- name: nginx
newName: haproxy
newTag: "2.4"
Result:
image: haproxy:2.4
This allows different environments to use different container images while sharing the same base manifests.
Real-World Example
Base Configuration
resources:
- deployment.yaml
- service.yaml
Development Overlay
nameSuffix: -dev
commonLabels:
env: dev
images:
- name: nginx
newTag: "1.25"
Production Overlay
nameSuffix: -prod
commonLabels:
env: prod
images:
- name: nginx
newTag: "1.28"
replicas: 5
The same application now supports multiple environments without duplicating manifests.
Key Takeaways
Kustomize helps teams manage Kubernetes configurations by separating:
Base Configuration
What remains the same across environments.
Overlays
What changes between environments.
Combined with transformers, Kustomize enables:
✅ Environment-specific deployments
✅ Reusable manifests
✅ Consistent naming conventions
✅ Automated image updates
✅ Cleaner repositories
✅ Reduced configuration drift
For teams that prefer plain YAML over templates, Kustomize offers one of the cleanest approaches to Kubernetes configuration management.




