11.10 Components
Kustomize Components define reusable configuration blocks that can be included in selected overlays.
They are useful when a feature should be enabled in some environments, but not all.
Purpose
Components let you package reusable Kubernetes configuration logic such as:
- resources
- patches
- ConfigMaps
- Secrets
- feature-specific changes
Then you can include that logic only in the overlays that need it.
Why Components?
In a normal Kustomize structure, common resources go into base/, and environment-specific changes go into overlays/.
But sometimes you have optional features.
Example:
| Feature | Dev | Premium | Self-hosted |
|---|---|---|---|
| Caching | No | Yes | Yes |
| External DB | Yes | Yes | No |
If caching is added to base/, then every overlay gets caching. That is wrong because dev does not need caching.
If caching is copied into premium/ and self-hosted/, it works, but now you are duplicating YAML.
Problem
Copying the same Redis, database, Secret, or patch files into multiple overlays causes config drift. One overlay may get updated while another is forgotten.
Solution
Put the optional feature into a component, then import that component only where needed.
Mental Model
base
shared app config
components
optional reusable features
overlays
choose base + required components
Example:
premium overlay = base + caching component + db component
self-hosted overlay = base + caching component
dev overlay = base + db component
Quote
Base is for everything shared by all overlays. Components are for reusable optional features used by only a subset of overlays.
Components vs Base vs Overlay
| Kustomize Part | Used For | Should contain |
|---|---|---|
base/ |
Shared default config | Common Deployments, Services, labels |
components/ |
Optional reusable feature logic | Redis, external DB, feature patches |
overlays/ |
Environment or product variation | Dev, premium, self-hosted, prod |
Tip
If every overlay needs it, put it in base/.
If only some overlays need it, make it a component.
Example Folder Structure
k8s/
├── base/
│ ├── kustomization.yaml
│ └── api-depl.yaml
├── components/
│ ├── caching/
│ │ ├── kustomization.yaml
│ │ ├── deployment-patch.yaml
│ │ └── redis-depl.yaml
│ └── db/
│ ├── kustomization.yaml
│ ├── deployment-patch.yaml
│ └── postgres-depl.yaml
└── overlays/
├── dev/
│ └── kustomization.yaml
├── premium/
│ └── kustomization.yaml
└── standalone/
└── kustomization.yaml
Note
Each component has its own kustomization.yaml, just like a base or overlay, but its kind is different.
Base Configuration
The base contains the shared application configuration.
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- api-depl.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-deployment
spec:
replicas: 1
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: nginx
Component Example: External Database
This component adds a PostgreSQL deployment, generates a Secret, and patches the API deployment so the app can read the database password.
apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component
resources:
- postgres-depl.yaml
secretGenerator:
- name: postgres-cred
literals:
- password=postgres123
patches:
- path: deployment-patch.yaml
Component API version
Components use:
Do not use kind: Kustomization for a component.
PostgreSQL Resource
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres-deployment
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:15
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-cred
key: password
Patch the Base Deployment
The component can patch resources from the base.
In this example, the DB component adds a DB_PASSWORD environment variable to the base API deployment.
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-deployment
spec:
template:
spec:
containers:
- name: api
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-cred
key: password
Note
This is a strategic merge patch. It targets the existing api-deployment and modifies only the required part.
Import a Component in an Overlay
The overlay imports:
- the base
- one or more components
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
components:
- ../../components/db
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
components:
- ../../components/db
- ../../components/caching
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
components:
- ../../components/caching
Feature selection
devgets external DB only.premiumgets external DB and caching.standalonegets caching only.
Component Example: Caching
A caching component may include Redis plus patches that configure the application to use Redis.
apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component
resources:
- redis-depl.yaml
patches:
- path: deployment-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-deployment
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:7
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-deployment
spec:
template:
spec:
containers:
- name: api
env:
- name: CACHE_ENABLED
value: "true"
- name: CACHE_HOST
value: redis-deployment
Tip
Boolean-like values in environment variables should usually be strings, for example "true" instead of true.
Build and Apply
Note
kustomize build only renders the final YAML. It does not deploy resources unless you pipe it to kubectl apply -f - or use kubectl apply -k.
When to Use Components
Use components when a feature is:
- optional
- reusable
- needed by more than one overlay
- not needed by every overlay
- made of multiple resources and patches
Good component examples
- Redis caching
- external database support
- monitoring sidecar
- optional logging agent
- premium-only feature config
- self-hosted-only resources
Bad component examples
- Core application deployment required everywhere
- Namespace required by every overlay
- Common labels used by every resource
- One-off patch used by only one overlay
Production Best Practices
Do
- Keep components focused on one feature.
- Use clear names like
components/cachingorcomponents/db. - Keep shared app resources in
base/. - Import components only in overlays that need them.
- Keep component patches small and easy to review.
- Use generated or external Secrets instead of hardcoding sensitive data.
- Preview output with
kustomize buildbefore applying.
Don't
- Do not put optional features into
base/. - Do not copy the same feature YAML across multiple overlays.
- Do not create one large component for many unrelated features.
- Do not store real production passwords in Git.
- Do not assume a component applies globally; it only applies where imported.
Components vs Common Transformers
| Need | Best Option |
|---|---|
| Add the same label to all resources | Common transformer |
| Add the same namespace to all resources | Common transformer |
| Add Redis only to premium and self-hosted | Component |
| Add DB only to dev and premium | Component |
| Patch one deployment in one environment | Overlay patch |
| Reuse a feature across selected overlays | Component |
Why not just use overlays?
You can put feature YAML directly in overlays, but if the same feature is needed in multiple overlays, copying it creates duplication. Components avoid that duplication.
Do and Don't Summary
| Do | Don't |
|---|---|
| Use components for optional reusable features | Put every optional feature in base |
| Import components from overlays | Copy the same component YAML into many overlays |
| Keep each component single-purpose | Mix caching, DB, and monitoring into one component |
Use kind: Component |
Use kind: Kustomization inside component folders |
Test with kustomize build |
Apply without checking rendered YAML |
Troubleshooting
Patch did not modify the deployment
Check that the patch target name matches the base resource name exactly:
Secret name changed unexpectedly
secretGenerator may append a hash to Secret names. This is normal Kustomize behavior. If your app expects a stable name, configure generator options carefully.
Component support
Components are a Kustomize feature. Make sure your kubectl embedded Kustomize version supports them, or use the standalone kustomize binary.
Final Example
k8s/
├── base/
│ ├── kustomization.yaml
│ └── api-depl.yaml
├── components/
│ ├── caching/
│ │ ├── kustomization.yaml
│ │ ├── redis-depl.yaml
│ │ └── deployment-patch.yaml
│ └── db/
│ ├── kustomization.yaml
│ ├── postgres-depl.yaml
│ └── deployment-patch.yaml
└── overlays/
├── dev/
│ └── kustomization.yaml
├── premium/
│ └── kustomization.yaml
└── standalone/
└── kustomization.yaml
Quote
Components help you write optional feature logic once and reuse it safely across selected overlays.