11.02 Kustomize vs Helm
Abstract
Kustomize and Helm both help manage Kubernetes YAML across multiple environments, but they solve the problem differently.
- Kustomize customizes plain YAML using base + overlays
- Helm generates YAML using templates + values files
Why Compare Kustomize and Helm?
In production Kubernetes, the same application often needs different settings for each environment.
Example:
| Environment | Replica Count | Image Tag |
|---|---|---|
| dev | 1 | dev |
| stg | 2 | stg |
| prod | 5 | 2.4.4 |
Instead of manually editing YAML files for every environment, teams use tools like Kustomize or Helm.
Question
Which one should you use?
It depends on whether you need simple YAML customization or full application packaging and lifecycle management.
Helm Approach
Helm uses Go templating syntax inside Kubernetes manifests.
Instead of hardcoding values, Helm uses variables such as:
and:
These values are supplied from a values.yaml file.
Note
Helm templates are not pure Kubernetes YAML until Helm renders them.
Helm Template Example
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Values.name }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Values.name }}
template:
metadata:
labels:
app: {{ .Values.name }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "nginx:{{ .Values.image.tag }}"
Corresponding values.yaml:
Example
Helm replaces template variables with values from values.yaml during install or upgrade.
Helm Environment Structure
A common Helm structure for multiple environments:
k8s/
├── environments/
│ ├── values.dev.yaml
│ ├── values.stg.yaml
│ └── values.prod.yaml
│
└── templates/
├── nginx-deployment.yaml
├── nginx-service.yaml
├── db-deployment.yaml
└── db-service.yaml
Install with environment-specific values:
helm install nginx-app ./k8s -f environments/values.dev.yaml
helm install nginx-app ./k8s -f environments/values.stg.yaml
helm install nginx-app ./k8s -f environments/values.prod.yaml
Tip
Use separate values files for each environment instead of editing templates directly.
Kustomize Approach
Kustomize does not use templates.
It keeps Kubernetes YAML as plain YAML and modifies it using overlays.
Apply environment-specific configuration:
Success
Kustomize is simpler because the manifests remain valid YAML.
Kustomize Structure Example
k8s/
├── base/
│ ├── kustomization.yaml
│ ├── nginx-deployment.yaml
│ └── nginx-service.yaml
│
└── overlays/
├── dev/
│ ├── kustomization.yaml
│ └── replica-patch.yaml
│
├── stg/
│ ├── kustomization.yaml
│ └── replica-patch.yaml
│
└── prod/
├── kustomization.yaml
└── replica-patch.yaml
Production patch example:
Note
Kustomize modifies existing YAML instead of generating YAML from templates.
Main Difference
| Area | Kustomize | Helm |
|---|---|---|
| Style | Overlay-based | Template-based |
| YAML readability | Plain YAML | Go templates inside YAML |
| Complexity | Lower | Higher |
| Built into kubectl | Yes | No, separate CLI |
| Package manager | No | Yes |
| Release tracking | No | Yes |
| Rollback support | No native release rollback | Yes |
| Best use case | Environment-specific YAML customization | Application packaging and lifecycle management |
Kustomize vs Helm Workflow
Best when you want simple environment customization using plain YAML.
When to Use Kustomize
Use Kustomize when:
- You want plain Kubernetes YAML
- You need simple dev/stg/prod differences
- You want fewer abstractions
- You do not need release tracking
- You are using GitOps tools like Argo CD or Flux
- Your team prefers readable manifests
Good fit
Kustomize is a strong choice for internal platform manifests, environment overlays, and GitOps repositories.
When to Use Helm
Use Helm when:
- You need to package a full application
- You want install, upgrade, rollback, and uninstall commands
- You want to use public charts like Bitnami, Prometheus, or NGINX
- You need loops, conditionals, functions, or hooks
- You want release history
- You distribute applications across teams or customers
Good fit
Helm is a strong choice for reusable application packages and third-party software installation.
Helm Strengths
- Complete Kubernetes package manager
- Supports release lifecycle management
- Supports install, upgrade, rollback, and uninstall
- Supports reusable public charts
- Supports functions, conditionals, loops, and hooks
- Good for complex applications like WordPress, Prometheus, Grafana, and cert-manager
helm install my-release bitnami/wordpress
helm upgrade my-release bitnami/wordpress
helm rollback my-release 1
helm uninstall my-release
Tip
Use Helm when you need application lifecycle management, not just YAML customization.
Helm Limitations
Warning
Helm templates can become difficult to read when charts grow large.
Common issues:
- Template syntax can make YAML harder to understand
- Debugging rendered output may take extra steps
- Chart behavior may be hidden behind variables and conditions
- Bad charts can generate unsafe or unexpected resources
- Values files can become large and complex
Preview rendered YAML before applying:
Kustomize Strengths
- Uses plain YAML
- Easier to read and review
- Built into
kubectl - No separate templating language
- Good for GitOps workflows
- Clean environment-specific overlays
- Easy to see exactly what changes between environments
Tip
Use Kustomize when your main goal is clean environment customization.
Kustomize Limitations
Warning
Kustomize is not a full package manager.
Limitations:
- No native release tracking
- No built-in rollback history like Helm
- No chart repository model
- No native lifecycle hooks like Helm
- Can become hard to manage if overlays are deeply nested or overused
Production Decision Guide
| Requirement | Recommended Tool |
|---|---|
| Simple environment customization | Kustomize |
| Plain readable YAML | Kustomize |
| GitOps environment overlays | Kustomize |
| Installing third-party apps | Helm |
| Application packaging | Helm |
| Rollbacks and release history | Helm |
| Complex reusable app deployment | Helm |
| Advanced templating logic | Helm |
Example
A common production pattern is to use Helm to install vendor applications and Kustomize to manage environment-specific overlays.
Production Best Practices
Recommended
- Preview rendered manifests before applying
- Keep environment-specific values separate
- Store all manifests and values files in Git
- Avoid hardcoding secrets in YAML
- Use immutable image tags in production
- Validate generated manifests in CI
- Keep Helm values files small and documented
- Keep Kustomize overlays focused and minimal
- Use GitOps tools for deployment consistency
Do's
Kustomize
- Use
base/for shared manifests - Use overlays for environment differences
- Keep patches small
- Preview with
kubectl kustomize - Use GitOps-friendly folder structures
Helm
- Use separate values files per environment
- Preview with
helm template - Track releases with
helm list - Review release history with
helm history - Use verified charts when possible
Don'ts
Kustomize
- Don't duplicate full manifests per environment
- Don't put production-only settings in the base
- Don't make overlays too complex
- Don't store raw secrets in Git
Helm
- Don't install charts without reviewing generated YAML
- Don't put every value behind unnecessary templates
- Don't use unknown/untrusted charts in production
- Don't store passwords directly in values files
- Don't rely only on Helm rollback for database recovery
Security Considerations
Danger
Both Helm and Kustomize can deploy privileged or insecure Kubernetes resources if manifests are not reviewed.
Production safeguards:
- Use RBAC with least privilege
- Scan manifests in CI
- Use admission controllers or policy engines
- Avoid plaintext secrets
- Review container images and registries
- Use signed or trusted charts where possible
- Restrict who can deploy to production namespaces
Troubleshooting Commands
Exam / Interview Notes
Quote
- Kustomize uses base and overlays
- Helm uses templates and values
- Kustomize keeps YAML simple and readable
- Helm provides package management and release lifecycle
- Helm is more powerful but more complex
- Kustomize is simpler but does not manage releases
Summary
Quote
- Use Kustomize for simple, readable environment customization
- Use Helm for application packaging, releases, upgrades, and rollbacks
- Helm uses Go templates and values files
- Kustomize uses plain YAML patches and overlays
- In production, always preview generated manifests before applying