Introduction
Kustomize, intégré nativement à kubectl depuis la v1.14, révolutionne la gestion des manifests Kubernetes en 2026. Contrairement à Helm qui repose sur des templates, Kustomize applique des transformations déclaratives via des fichiers YAML purs, favorisant le GitOps pur. Imaginez une base commune pour un déploiement Nginx, surchargée par des environnements (dev/prod) sans duplication ni variables magiques.
Pourquoi l'adopter ? Il évite les erreurs de templating, intègre parfaitement avec ArgoCD/Flux, et gère les patches stratégiques pour des mutations post-build. Ce tutoriel avancé couvre de la structure de base aux generators Secrets, avec 8 exemples YAML complets. À la fin, vous déployez une app microservices modulaire, scalable en cluster EKS/GKE/AKS. Idéal pour les Sr. DevOps gérant 100+ manifests.
Prérequis
- kubectl 1.28+ avec Kustomize intégré (
kubectl kustomize) - Cluster Kubernetes accessible (Minikube pour tests, ou cloud prod)
- Connaissances avancées : Deployments, ConfigMaps, Secrets, RBAC
- Git pour versioning des overlays
- Outil
kustomizeCLI standalone (optionnel, viabrew install kustomize)
Installer et vérifier Kustomize
# Installation standalone (macOS/Linux)
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
sudo mv kustomize /usr/local/bin/
# Vérification avec kubectl intégré
kubectl kustomize version
# Test basique
mkdir test-kust && cd test-kust
echo 'apiVersion: v1
kind: ConfigMap
metadata:
name: test' > configmap.yaml
echo 'resources:
- configmap.yaml' > kustomization.yaml
kubectl kustomize .Ce script installe Kustomize v5+ et vérifie son intégration kubectl. Le test crée un ConfigMap simple via kustomization.yaml, démontrant le build sans kubectl apply. Évitez les versions obsolètes pour les generators alpha comme les StrategicMergePatch.
Structure de base d'un Kustomization
Un projet Kustomize repose sur un fichier kustomization.yaml listant les ressources et transformations. Créez un dossier base/ pour les manifests communs, réutilisables via bases:. Analogie : comme des Lego, la base assemble les pièces, les overlays ajoutent les couleurs.
Créer une base Nginx simple
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
namespace: default
namePrefix: app-
nameSuffix: -v1
commonLabels:
app.kubernetes.io/name: nginx-app
version: v1.0Ce kustomization.yaml de base référence un Deployment et Service Nginx, ajoute des labels communs et pré/suf fixes noms. Appliquez avec kubectl kustomize . pour générer les manifests transformés. Piège : omettre apiVersion cause des erreurs de parsing en v1beta1+.
Manifests de base (Deployment + Service)
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
type: ClusterIPCes manifests forment la base : Deployment avec 2 replicas Nginx, Service ClusterIP. Kustomize les assemble sans altération initiale. Copiez-collable ; testez avec kubectl apply -k base/. Attention : labels doivent matcher pour le selector.
Implémenter des Overlays pour environnements
Les overlays surchargent la base via bases: [../base]. Créez overlays/dev/ et overlays/prod/ pour dev/prod. Utilisez patches pour muter replicas, images, etc.
Overlay Dev avec patches
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../../base
patchesStrategicMerge:
- deployment-patch.yaml
images:
- name: nginx
newTag: 1.25-alpine
replicas:
- name: nginx-deployment
count: 1
namespace: devCet overlay pointe la base, patch le Deployment (réplicas/image), et cible namespace dev. patchesStrategicMerge fusionne mergeable fields. Build : kubectl kustomize overlays/dev. Évitez patchesJson6902 sauf pour non-mergeables comme arrays.
Patch stratégique pour Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
template:
spec:
containers:
- name: nginx
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1Ce patch ajoute resources et stratégie RollingUpdate au Deployment base. StrategicMerge fusionne sans écraser. Crucial pour prod : maxUnavailable: 0 assure zero-downtime. Testez diffs avec kustomize build --enable-helm . si Helm-like.
Générateurs ConfigMap et Secret
Kustomize excelle avec generators pour injecter valeurs sensibles/env-specific sans base64 manuels. configMapGenerator et secretGenerator hashe les fichiers pour immutabilité.
Overlay Prod avec generators
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../../base
configMapGenerator:
- name: app-config
files:
- config.properties=app-config.properties
- database.properties=db.properties
secretGenerator:
- name: db-secret
files:
- db-pass.txt=db-password.txt
type: Opaque
patchesStrategicMerge:
- |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
template:
spec:
volumes:
- name: config-volume
configMap:
name: app-config
- name: secret-volume
secret:
secretName: db-secret
containers:
- name: nginx
volumeMounts:
- name: config-volume
mountPath: /etc/config
- name: secret-volume
mountPath: /etc/secrets
readOnly: true
images:
- name: nginx
newTag: 1.25
newName: nginx
replicas:
- name: nginx-deployment
count: 5
namespace: prodCet overlay génère ConfigMap/Secret à partir de fichiers, patch le Deployment pour volumes/mounts. Hash suffixes assurent rebuild sur changement. Placez app-config.properties et db-password.txt dans le dossier. Sécurise secrets sans kubectl create secret.
Patches avancés et PostBuild
Patches JSON6902 pour mutations précises (e.g. arrays), postBuild pour vars comme SHA images GitOps.
Patch JSON6902 et vars
apiVersion: apps/v1
$patch: replace
$operation: add
path: /spec/template/spec/containers/0/env
value:
- name: ENV
value: production
- name: DB_HOST
valueFrom:
secretKeyRef:
name: db-secret
key: host
---
# Dans kustomization.yaml, ajoutez :
# vars:
# - name: IMAGE_TAG
# objref:
# kind: Deployment
# name: nginx-deployment
# apiVersion: apps/v1
# fieldref:
# fieldpath: spec.template.spec.containers.[name=nginx].image
# patchesJson6902: [patch-json.yaml]
# postBuild:
# substitute:
# IMAGE_TAG: latest-sha
# Exemple postBuild complet dans kustomization.yaml :
postBuild:
substitute:
app-name: "nginx-prod"
sha: "abc123"JSON6902 ajoute env vars au premier container. vars et postBuild.substitute injectent dynamiquement (e.g. SHA CI/CD). Ajoutez à kustomization.yaml prod. Puissant pour ArgoCD sync waves.
Déploiement complet via kubectl
# Structure arbo :
# kustomize-app/
# ├── base/
# │ ├── kustomization.yaml
# │ ├── deployment.yaml
# │ └── service.yaml
# └── overlays/
# ├── dev/
# │ ├── kustomization.yaml
# │ └── deployment-patch.yaml
# └── prod/
# ├── kustomization.yaml
# ├── deployment-patch.yaml
# ├── patch-json.yaml
# ├── app-config.properties
# └── db-password.txt
# Build et dry-run
kubectl kustomize overlays/prod | kubectl apply --dry-run=client -f -
# Déploiement réel
kubectl apply -k overlays/prod
# Vérif
kubectl get all -n prod
kubectl rollout status deployment/nginx-deployment -n prodCe script assume l'arbo complète, build/dry-run puis apply. -k utilise Kustomize intégré. rollout status attend readiness. Parfait pour CI pipelines GitHub Actions/Jenkins.
Bonnes pratiques
- Structure arbo :
base/+overlays/{env}/{team}/pour scalabilité multi-équipes. - Generators hashed : Toujours utiliser
secretGeneratoravectype: Opaqueet literals/files. - Patches prioritaires : StrategicMerge > JSON6902 ; testez diffs avec
k diff. - GitOps ready : Commit overlays, ignore fichiers sensibles via
.gitignore+ SealedSecrets. - Helm fallback : Activez
enableHelm: truepour hybride, mais priorisez pur Kustomize.
Erreurs courantes à éviter
- Oublier apiVersion v1beta1 : Cause
no kind "Kustomization"; toujours spécifier. - Merge conflicts : Arrays non-mergeables cassent ; utilisez JSON6902 avec
$patch: replace. - Secrets en clair : Ne commitez jamais ; utilisez
literal:ou SOPS +sopsGeneratorplugin. - Namespace manquant : Applique sans
-néchoue ; forcez vianamespace:dans kustomization.
Pour aller plus loin
- Docs officielles : Kustomize Book
- Plugins avancés : Helm, SOPS pour secrets (kustomize-sops)
- GitOps : Intégrez avec ArgoCD ou Flux.
- Formations expertes : Découvrez nos formations Learni sur Kubernetes & GitOps.