Kustomize, when used with Argo CD for GitOps, isn’t just about managing configurations; it’s about orchestrating immutable infrastructure deployments through declarative Git manifests.
Let’s see Kustomize and Argo CD in action. Imagine a simple web application deployed across development, staging, and production environments.
Here’s a basic Kustomize base:
# 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/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
Now, let’s create an overlay for development:
# overlays/dev/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 2 # Increased replicas for dev
template:
spec:
containers:
- name: my-app
image: nginx:1.21.0 # Specific version for dev
# overlays/dev/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../../base
patchesStrategicMerge:
- deployment.yaml
commonLabels:
env: dev
When Argo CD points to overlays/dev in your Git repository, it runs kustomize build overlays/dev. The output will be a modified deployment.yaml with replicas: 2, image: nginx:1.21.0, and the env: dev label applied.
The problem Kustomize solves here is managing environment-specific configurations without duplicating entire Kubernetes manifests. Instead of having dev-deployment.yaml, staging-deployment.yaml, and prod-deployment.yaml, you maintain a single base and then apply targeted patches or modifications in overlays. This drastically reduces configuration drift and makes updates far more manageable.
Argo CD integrates seamlessly. You configure an Argo CD Application that points to your Git repository. For the dev environment, the source.path would be overlays/dev. Argo CD fetches the manifests, Kustomize builds them, and Argo CD applies the resulting YAML to your cluster.
Here’s a snippet of an Argo CD Application manifest for this:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app-dev
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/your-username/your-repo.git
targetRevision: HEAD
path: overlays/dev # Points to the Kustomize overlay
destination:
server: https://kubernetes.default.svc
namespace: dev # Target namespace for deployment
syncPolicy:
automated:
prune: true
selfHeal: true
The core mental model is that Kustomize transforms a set of base configurations into environment-specific outputs. Argo CD consumes these outputs as the desired state for your Kubernetes cluster. It’s a two-stage process: Git -> Kustomize build -> Argo CD apply.
The levers you control are within your kustomization.yaml files:
resources: Points to other Kustomize directories or raw YAML files that form the base.bases: Includes other Kustomize directories, allowing for hierarchical configuration.patchesStrategicMerge: Applies patches to existing resources.patchesJson6902: Applies JSON patches.commonLabelsandcommonAnnotations: Adds labels/annotations to all resources.images: Overrides image names and tags.namePrefix,nameSuffix: Prefixes or suffixes resource names.replicas: A shortcut to set replica counts for Deployments, StatefulSets, etc.
When you define a replicas field directly in an overlay’s kustomization.yaml (like replicas: 2 in overlays/dev/kustomization.yaml), Kustomize intelligently applies this to all Deployments, StatefulSets, and ReplicaSets found in the base and merged resources. It doesn’t require you to write a specific patch for each workload type; Kustomize understands common Kubernetes workload resources and applies the replica count globally to them.
The next conceptual hurdle is managing secrets and sensitive configuration across environments, often involving tools like Sealed Secrets or external secret management solutions integrated with Argo CD.