Kustomize: Gestión de Configuración en Kubernetes
Kustomize es la herramienta nativa de Kubernetes para personalizar manifiestos YAML sin usar plantillas, permitiendo gestionar configuraciones base y sobrescrituras por entorno de forma limpia y mantenible. Esta guía cubre el uso de bases y overlays, patches, generadores de ConfigMaps y Secrets, transformadores y la integración con pipelines de CI/CD.
Requisitos Previos
kubectl1.14+ (Kustomize viene integrado)- Conocimientos básicos de manifiestos Kubernetes
- Acceso a un clúster Kubernetes
# Verificar que Kustomize está disponible (integrado en kubectl)
kubectl kustomize --help
# Instalar la CLI independiente de Kustomize (versión más reciente)
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
mv kustomize /usr/local/bin/
kustomize version
Conceptos Fundamentales
Kustomize trabaja con el concepto de base y overlay:
- Base: configuración común que se reutiliza en todos los entornos
- Overlay: personalizaciones específicas de cada entorno que extienden la base
- kustomization.yaml: archivo de control que define qué recursos y transformaciones aplicar
# Estructura típica de un proyecto con Kustomize
tree mi-aplicacion/
# mi-aplicacion/
# ├── base/
# │ ├── kustomization.yaml
# │ ├── deployment.yaml
# │ ├── service.yaml
# │ └── configmap.yaml
# └── overlays/
# ├── desarrollo/
# │ ├── kustomization.yaml
# │ └── patch-replicas.yaml
# ├── staging/
# │ ├── kustomization.yaml
# │ └── patch-resources.yaml
# └── produccion/
# ├── kustomization.yaml
# └── patch-produccion.yaml
Bases y Overlays
Crea la capa base con los manifiestos comunes:
# base/deployment.yaml
cat << 'EOF' > base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mi-aplicacion
spec:
replicas: 1
selector:
matchLabels:
app: mi-aplicacion
template:
metadata:
labels:
app: mi-aplicacion
spec:
containers:
- name: app
image: mi-aplicacion:latest
ports:
- containerPort: 8080
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
EOF
# base/service.yaml
cat << 'EOF' > base/service.yaml
apiVersion: v1
kind: Service
metadata:
name: mi-aplicacion
spec:
selector:
app: mi-aplicacion
ports:
- port: 80
targetPort: 8080
EOF
# base/kustomization.yaml - Lista los recursos de la base
cat << 'EOF' > base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# Recursos que forman la base
resources:
- deployment.yaml
- service.yaml
# Etiquetas comunes aplicadas a todos los recursos
commonLabels:
gestionado-por: kustomize
version: v1
EOF
Crea el overlay de producción:
# overlays/produccion/kustomization.yaml
cat << 'EOF' > overlays/produccion/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# Referencia a la base
bases:
- ../../base
# Personalización del namespace de producción
namespace: produccion
# Prefijo para distinguir recursos entre entornos
namePrefix: prod-
# Imagen específica para producción
images:
- name: mi-aplicacion
newName: registry.empresa.com/mi-aplicacion
newTag: v1.5.2
# Patches aplicados solo en producción
patches:
- path: patch-replicas.yaml
target:
kind: Deployment
name: mi-aplicacion
EOF
# overlays/produccion/patch-replicas.yaml
cat << 'EOF' > overlays/produccion/patch-replicas.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mi-aplicacion
spec:
# En producción usamos 3 réplicas para alta disponibilidad
replicas: 3
EOF
Tipos de Patches
Kustomize soporta dos tipos principales de patches:
Strategic Merge Patch (fusión estratégica):
# patch-recursos.yaml - Actualizar recursos del contenedor
apiVersion: apps/v1
kind: Deployment
metadata:
name: mi-aplicacion
spec:
template:
spec:
containers:
- name: app
# Sobrescribir los límites de recursos para producción
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 2000m
memory: 2Gi
JSON Patch (parches atómicos precisos):
# patch-json.yaml - Patch JSON 6902 para cambios precisos
patches:
- target:
kind: Deployment
name: mi-aplicacion
patch: |-
- op: replace
path: /spec/replicas
value: 5
- op: add
path: /spec/template/spec/containers/0/env/-
value:
name: ENTORNO
value: produccion
- op: remove
path: /spec/template/spec/containers/0/resources/limits/cpu
Generadores de ConfigMaps y Secrets
Kustomize puede generar ConfigMaps y Secrets automáticamente desde archivos:
# Crear los archivos de configuración
mkdir -p config/
echo "DEBUG=false" > config/app.env
echo "LOG_LEVEL=info" >> config/app.env
echo "DB_HOST=postgres.produccion.svc.cluster.local" >> config/app.env
# kustomization.yaml con generadores
cat << 'EOF' >> overlays/produccion/kustomization.yaml
# Generar ConfigMap desde archivo de propiedades
configMapGenerator:
- name: configuracion-app
envs:
- config/app.env
options:
# No añadir hash al nombre (útil cuando otros recursos referencian por nombre fijo)
disableNameSuffixHash: true
# Generar Secret desde archivos o literales
secretGenerator:
- name: credenciales-db
literals:
- DB_PASSWORD=secreto123
type: Opaque
options:
disableNameSuffixHash: true
EOF
Transformadores
Los transformadores modifican todos los recursos de forma global:
# kustomization.yaml - Transformadores comunes
transformers:
- |-
apiVersion: builtin
kind: LabelTransformer
metadata:
name: etiquetas-comunes
labels:
entorno: produccion
equipo: plataforma
fieldSpecs:
- path: metadata/labels
create: true
- path: spec/template/metadata/labels
create: true
kind: Deployment
annotations:
# Anotaciones de gestión aplicadas a todos los recursos
gestionado-por: kustomize
repositorio: github.com/mi-org/mi-aplicacion
fecha-despliegue: "2024-01-15"
Personalización por Entorno
# Estructura completa con tres entornos
mkdir -p overlays/{desarrollo,staging,produccion}
# overlays/desarrollo/kustomization.yaml
cat << 'EOF' > overlays/desarrollo/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../../base
namespace: desarrollo
images:
- name: mi-aplicacion
newTag: latest
patches:
- patch: |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: mi-aplicacion
spec:
replicas: 1
template:
spec:
containers:
- name: app
env:
- name: DEBUG
value: "true"
EOF
# Ver el resultado final sin aplicar (modo dry-run)
kubectl kustomize overlays/produccion
# Aplicar el overlay de producción al clúster
kubectl apply -k overlays/produccion
# Aplicar el overlay de desarrollo
kubectl apply -k overlays/desarrollo
# Ver diff entre lo que hay en el clúster y lo que se va a aplicar
kubectl diff -k overlays/produccion
Integración con CI/CD
# Script de despliegue en pipeline CI/CD
#!/bin/bash
set -e
ENTORNO=${1:-staging}
VERSION=${2:-latest}
# Verificar que el overlay existe
if [ ! -d "overlays/${ENTORNO}" ]; then
echo "Error: el overlay ${ENTORNO} no existe"
exit 1
fi
# Actualizar la imagen con la nueva versión
kustomize edit set image mi-aplicacion="registry.empresa.com/mi-aplicacion:${VERSION}" \
--kustomization overlays/${ENTORNO}/kustomization.yaml
# Verificar la configuración generada
kustomize build overlays/${ENTORNO} > /tmp/manifiestos-${ENTORNO}.yaml
# Aplicar al clúster (modo server-side apply para mejor gestión de conflictos)
kubectl apply --server-side -f /tmp/manifiestos-${ENTORNO}.yaml
# Verificar el despliegue
kubectl rollout status deployment/mi-aplicacion -n ${ENTORNO}
Integración con Argo CD usando Kustomize:
# Argo CD detecta automáticamente kustomization.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: mi-aplicacion-prod
namespace: argocd
spec:
source:
repoURL: https://github.com/mi-org/mi-aplicacion
targetRevision: main
path: overlays/produccion # Argo CD usa kustomize automáticamente
destination:
server: https://kubernetes.default.svc
namespace: produccion
syncPolicy:
automated:
prune: true
Solución de Problemas
# Generar y validar los manifiestos sin aplicar
kustomize build overlays/produccion | kubectl apply --dry-run=client -f -
# Depurar el kustomization.yaml
kustomize build overlays/produccion 2>&1 | head -50
# Verificar que todos los recursos referenciados existen
kustomize build base/
# Buscar qué overlay sobreescribe un campo específico
kustomize build overlays/produccion | grep -A5 "replicas"
# Error "map has no entry for key" - recursos no encontrados en la base
ls base/ # Verificar que los archivos existen
# Error de validación de schema
kustomize build overlays/produccion | kubectl apply --dry-run=server -f -
Conclusión
Kustomize ofrece una forma nativa y sin dependencias externas de gestionar configuraciones Kubernetes para múltiples entornos, manteniendo un único conjunto de manifiestos base. La combinación de overlays, patches y generadores permite mantener el principio DRY (Don't Repeat Yourself) mientras se adapta cada despliegue a sus requisitos específicos. Integrado con Argo CD o Flux, Kustomize forma el núcleo de cualquier estrategia GitOps sólida.


