Kustomize Deployment Guide
Kustomize is the recommended deployment method for Greenfield Cluster. It provides declarative configuration management with environment-specific overlays, making it perfect for GitOps workflows.
Overview
Kustomize allows you to customize Kubernetes manifests without modifying the original files. It uses a declarative approach with patches and overlays for environment-specific configurations.
Why Kustomize?
- ✅ Native Kubernetes: Built into kubectl (v1.14+)
- ✅ Declarative: Define what you want, not how to get there
- ✅ Composable: Build complex configurations from simple pieces
- ✅ GitOps-Ready: Perfect for ArgoCD and Flux CD
- ✅ No Templating: Use actual Kubernetes YAML, not templates
Project Structure
kustomize/
├── base/ # Base configurations
│ ├── namespace/ # Namespace definition
│ ├── redis/ # Redis manifests
│ ├── postgres/ # PostgreSQL manifests
│ ├── mysql/ # MySQL manifests
│ ├── mongodb/ # MongoDB manifests
│ ├── kafka/ # Kafka manifests
│ ├── istio/ # Istio service mesh
│ ├── cert-manager/ # Certificate management
│ ├── otel-collector/ # OpenTelemetry collector
│ ├── jaeger/ # Jaeger tracing
│ ├── prometheus/ # Prometheus metrics
│ ├── grafana/ # Grafana dashboards
│ ├── observability/ # SLOs and alerts
│ ├── fastapi-app/ # Example application
│ ├── sealed-secrets/ # Sealed secrets controller
│ ├── auth/ # Authentication system
│ └── kustomization.yaml # Base kustomization file
└── overlays/ # Environment-specific configs
├── dev/ # Development environment
│ ├── kustomization.yaml
│ └── patches/
├── staging/ # Staging environment
│ ├── kustomization.yaml
│ └── patches/
└── prod/ # Production environment
├── kustomization.yaml
└── patches/
Quick Start
Prerequisites
- Kubernetes cluster (v1.24+)
- kubectl with Kustomize support (built-in)
- At least 8 CPU cores, 16GB RAM
Deploy Base Configuration
Deploy all components with default settings:
Deploy with Environment Overlay
Deploy with environment-specific configurations:
# Development
kubectl apply -k kustomize/overlays/dev/
# Staging
kubectl apply -k kustomize/overlays/staging/
# Production
kubectl apply -k kustomize/overlays/prod/
Base Configuration
The base/ directory contains the standard configuration for all components.
Base Kustomization File
kustomize/base/kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: greenfield
resources:
- namespace
- redis
- postgres
- mysql
- mongodb
- kafka
- istio
- cert-manager
- otel-collector
- jaeger
- prometheus
- grafana
- observability
- fastapi-app
- sealed-secrets
Selecting Components
Comment out components you don't need:
resources:
- namespace
- redis
- postgres
# - mysql # Not using MySQL
# - mongodb # Not using MongoDB
- kafka
- istio
- otel-collector
- jaeger
- prometheus
- grafana
Environment Overlays
Overlays customize the base configuration for specific environments.
Development Overlay
Characteristics: - Single replicas - Minimal resources - Local storage - Relaxed limits
kustomize/overlays/dev/kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: greenfield
resources:
- ../../base
replicas:
- name: fastapi-app
count: 1
- name: redis-master
count: 1
- name: redis-replica
count: 0
patches:
- path: patches/resource-limits.yaml
- path: patches/storage.yaml
configMapGenerator:
- name: env-config
literals:
- ENVIRONMENT=development
- LOG_LEVEL=debug
Staging Overlay
Characteristics: - Multiple replicas - Medium resources - Production-like setup - Testing configuration
kustomize/overlays/staging/kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: greenfield-staging
bases:
- ../../base
nameSuffix: -staging
replicas:
- name: fastapi-app
count: 2
- name: redis-replica
count: 1
patches:
- path: patches/resource-limits.yaml
- path: patches/ingress.yaml
configMapGenerator:
- name: env-config
literals:
- ENVIRONMENT=staging
- LOG_LEVEL=info
Production Overlay
Characteristics: - High availability - Full resource allocation - Multiple replicas - Production-grade configuration
kustomize/overlays/prod/kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: greenfield
bases:
- ../../base
replicas:
- name: fastapi-app
count: 5
- name: redis-replica
count: 2
- name: postgres
count: 3
- name: mysql
count: 3
- name: mongodb
count: 3
patches:
- path: patches/resource-limits.yaml
- path: patches/anti-affinity.yaml
- path: patches/pdb.yaml
- path: patches/ingress-tls.yaml
configMapGenerator:
- name: env-config
literals:
- ENVIRONMENT=production
- LOG_LEVEL=warning
Customization Techniques
Patching Resources
Strategic Merge Patch
Modify specific fields in resources:
overlays/prod/patches/resource-limits.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: fastapi-app
spec:
template:
spec:
containers:
- name: fastapi-app
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2000m
memory: 4Gi
JSON Patch
Precise modifications using JSON Patch syntax:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
patches:
- target:
kind: Deployment
name: fastapi-app
patch: |-
- op: replace
path: /spec/replicas
value: 10
- op: add
path: /spec/template/metadata/annotations
value:
prometheus.io/scrape: "true"
Replica Count
Scale deployments and statefulsets:
Name Prefix/Suffix
Add prefixes or suffixes to resource names:
Namespace
Override the default namespace:
Labels and Annotations
Add common labels and annotations to all resources:
commonLabels:
environment: production
team: platform
managed-by: kustomize
commonAnnotations:
contact: platform-team@example.com
documentation: https://docs.example.com
ConfigMap and Secret Generators
Generate ConfigMaps and Secrets from literals or files:
configMapGenerator:
- name: app-config
literals:
- DATABASE_HOST=postgres-service
- REDIS_HOST=redis-service
files:
- application.conf
secretGenerator:
- name: app-secrets
literals:
- API_KEY=changeme
files:
- tls.crt
- tls.key
Image Transformation
Override image tags:
images:
- name: fastapi-example
newTag: v2.0.0
- name: redis
newName: redis/redis-stack
newTag: latest
Advanced Patterns
Component-Based Organization
Use Kustomize components for optional features:
# kustomize/components/monitoring/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component
resources:
- prometheus
- grafana
# overlays/prod/kustomization.yaml
components:
- ../../components/monitoring
- ../../components/security
Multiple Bases
Combine multiple base configurations:
Remote Resources
Reference resources from remote repositories:
resources:
- https://raw.githubusercontent.com/istio/istio/1.20.0/manifests/charts/base/crds/crd-all.gen.yaml
- github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.crds.yaml
Helm Chart Integration
Include Helm charts in Kustomize:
helmCharts:
- name: postgresql
repo: https://charts.bitnami.com/bitnami
version: 12.x.x
releaseName: postgres
namespace: greenfield
valuesFile: values.yaml
Validation and Testing
Preview Changes
Generate output without applying:
# Build and preview
kubectl kustomize kustomize/overlays/prod/
# Save to file for review
kubectl kustomize kustomize/overlays/prod/ > output.yaml
Dry Run
Test application without making changes:
# Client-side dry run
kubectl apply -k kustomize/overlays/prod/ --dry-run=client
# Server-side dry run (validates against API server)
kubectl apply -k kustomize/overlays/prod/ --dry-run=server
Diff Changes
See what will change before applying:
Validate Syntax
Check YAML syntax and structure:
# Validate with kustomize
kustomize build kustomize/overlays/prod/ | kubectl apply --dry-run=client -f -
# Use kubeconform for validation
kustomize build kustomize/overlays/prod/ | kubeconform -strict -
Deployment Workflows
Manual Deployment
# Deploy to development
kubectl apply -k kustomize/overlays/dev/
# Wait for rollout
kubectl rollout status deployment -n greenfield
# Verify deployment
kubectl get pods -n greenfield
GitOps with ArgoCD
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: greenfield-cluster
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/yourusername/green_field_cluster
targetRevision: main
path: kustomize/overlays/prod
destination:
server: https://kubernetes.default.svc
namespace: greenfield
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
GitOps with Flux CD
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
name: greenfield-cluster
namespace: flux-system
spec:
interval: 1m
url: https://github.com/yourusername/green_field_cluster
ref:
branch: main
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: greenfield-cluster
namespace: flux-system
spec:
interval: 10m
path: ./kustomize/overlays/prod
prune: true
sourceRef:
kind: GitRepository
name: greenfield-cluster
healthChecks:
- apiVersion: apps/v1
kind: Deployment
name: fastapi-app
namespace: greenfield
Managing Updates
Update Deployment
# Pull latest changes
git pull origin main
# Preview changes
kubectl diff -k kustomize/overlays/prod/
# Apply updates
kubectl apply -k kustomize/overlays/prod/
# Watch rollout
kubectl rollout status deployment/fastapi-app -n greenfield
Rollback Changes
# Revert Git commit
git revert HEAD
kubectl apply -k kustomize/overlays/prod/
# Or checkout previous commit
git checkout <previous-commit>
kubectl apply -k kustomize/overlays/prod/
git checkout main
Best Practices
Organization
- Keep base/ generic: No environment-specific configuration
- Use overlays for environment differences: dev, staging, prod
- Component per service: Separate directory for each component
- Consistent naming: Follow naming conventions across all resources
Configuration Management
- Use ConfigMaps for configuration: Not hardcoded in deployments
- Generate secrets with kustomize: Use secretGenerator
- Version control everything: All configurations in Git
- Document patches: Comment why patches are needed
Resource Management
- Always set resource requests/limits: In production overlays
- Use pod disruption budgets: For high availability
- Configure anti-affinity: Spread pods across nodes
- Set appropriate replica counts: Based on environment
Security
- Never commit secrets: Use Sealed Secrets or external secret managers
- Use RBAC: Define appropriate roles and bindings
- Enable security contexts: Run as non-root when possible
- Regular updates: Keep base images and dependencies updated
Troubleshooting
Common Issues
Error: no matches for kind "X" in version "Y"
Solution: Ensure CRDs are installed first:
Error: namespace not found
Solution: Apply namespace first or use --create-namespace:
Patch doesn't apply
Solution: Verify patch target and structure:
Resource already exists
Solution: Use declarative apply with --server-side:
Migration from Helm
If migrating from Helm to Kustomize:
-
Export Helm values as YAML:
-
Organize into base structure: Split manifests by component into
kustomize/base/ -
Create kustomization.yaml: Reference all component directories
-
Create overlays: Extract environment-specific values into overlay patches
-
Test thoroughly: Deploy to dev environment first