--- title: "Cómo gestionar manifiestos de Kubernetes con Kustomize" description: "Organiza tus manifiestos de Kubernetes con Kustomize: crea una base común, overlays por entorno, patches y generadores de ConfigMap, y despliégalos con kubectl." category: "Ingeniería de Plataformas" language: es source: https://cubepath.com/es/docs/ingeniería-de-plataformas/kustomize-gestion-de-configuracion-kubernetes updated: 2026-09-25 --- # Cómo gestionar manifiestos de Kubernetes con Kustomize Kustomize es la herramienta de Kubernetes para personalizar manifiestos YAML sin plantillas: mantienes una **base** con lo común y aplicas **overlays** con las diferencias de cada entorno. Viene integrada en `kubectl`, así que no necesitas instalar nada adicional para usarla. En este tutorial construirás una aplicación de ejemplo con una base y dos overlays (desarrollo y producción), usarás patches, generarás un ConfigMap y desplegarás el resultado en un clúster. ## Requisitos previos - Una máquina con Ubuntu 24.04 LTS (tu equipo o un VPS de CubePath) con `kubectl` instalado. - Acceso a un clúster de Kubernetes con permisos para crear namespaces y Deployments. Sirve un clúster local con kind o k3s. - Conocimientos básicos de Deployments y Services. Comprueba que `kubectl` llega al clúster y qué versión de Kustomize trae integrada: ```bash kubectl version ``` ```output Client Version: v1.33.1 Kustomize Version: v5.6.0 Server Version: v1.33.1 ``` Cualquier `kubectl` reciente incluye Kustomize v5, que es la versión que se usa en esta guía. ## Paso 1: Crear la estructura del proyecto Kustomize trabaja con directorios. Cada directorio contiene un `kustomization.yaml` que lista los recursos y las transformaciones que se aplican. Crea la estructura: ```bash mkdir -p ~/mi-aplicacion/base ~/mi-aplicacion/overlays/desarrollo ~/mi-aplicacion/overlays/produccion cd ~/mi-aplicacion ``` Al terminar el tutorial el proyecto tendrá esta forma: - `base/`: `deployment.yaml`, `service.yaml` y `kustomization.yaml`, comunes a todos los entornos. - `overlays/desarrollo/`: `kustomization.yaml` con los cambios para desarrollo. - `overlays/produccion/`: `kustomization.yaml`, un patch de réplicas y recursos, y el archivo `app.env` del ConfigMap. ## Paso 2: Definir la base La base contiene los manifiestos que comparten todos los entornos. Crea el Deployment: ```bash nano base/deployment.yaml ``` ```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: nginx:1.27 ports: - containerPort: 80 env: - name: ENTORNO value: base resources: requests: cpu: 50m memory: 64Mi limits: memory: 128Mi ``` Crea el Service: ```bash nano base/service.yaml ``` ```yaml apiVersion: v1 kind: Service metadata: name: mi-aplicacion spec: selector: app: mi-aplicacion ports: - port: 80 targetPort: 80 ``` Por último, el `kustomization.yaml` de la base, que enumera los recursos y añade una etiqueta común: ```bash nano base/kustomization.yaml ``` ```yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - deployment.yaml - service.yaml labels: - pairs: app.kubernetes.io/part-of: mi-aplicacion app.kubernetes.io/managed-by: kustomize ``` > Nota: el campo `labels` sustituye a `commonLabels`, que está obsoleto en Kustomize v5. A diferencia de `commonLabels`, `labels` no modifica los selectores por defecto, lo que evita errores al cambiar etiquetas en un Deployment ya desplegado (los selectores son inmutables). Renderiza la base para comprobar que es válida: ```bash kubectl kustomize base ``` La salida es el YAML final con la etiqueta `app.kubernetes.io/part-of` añadida a ambos recursos. `kubectl kustomize` no toca el clúster: solo imprime lo que se aplicaría. ## Paso 3: Crear el overlay de desarrollo Un overlay referencia la base en `resources` y declara solo lo que cambia. Para desarrollo usarás un namespace propio, un prefijo en los nombres y un patch inline que cambia una variable de entorno: ```bash nano overlays/desarrollo/kustomization.yaml ``` ```yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - ../../base namespace: desarrollo namePrefix: dev- patches: - patch: |- apiVersion: apps/v1 kind: Deployment metadata: name: mi-aplicacion spec: template: spec: containers: - name: app env: - name: ENTORNO value: desarrollo ``` > Nota: el campo antiguo `bases:` está obsoleto. Las bases se incluyen ahora en `resources:`, igual que cualquier otro manifiesto. Este patch es de tipo **strategic merge**: se escribe como un fragmento del recurso y Kustomize lo fusiona con la base, usando el nombre del contenedor (`app`) y el de la variable (`ENTORNO`) como claves. Renderiza el overlay: ```bash kubectl kustomize overlays/desarrollo | grep -E 'name:|namespace:|value:' ``` ```output name: dev-mi-aplicacion namespace: desarrollo name: dev-mi-aplicacion namespace: desarrollo - name: ENTORNO value: desarrollo name: app ``` Los dos recursos tienen ahora el prefijo `dev-` y el namespace `desarrollo`, y la variable `ENTORNO` vale `desarrollo`. ## Paso 4: Crear el overlay de producción con patches y un ConfigMap Producción necesita más réplicas, más recursos, una imagen fijada y configuración propia. Empieza por un patch strategic merge en un archivo aparte: ```bash nano overlays/produccion/patch-deployment.yaml ``` ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: mi-aplicacion spec: replicas: 3 template: spec: containers: - name: app resources: requests: cpu: 250m memory: 256Mi limits: memory: 512Mi ``` Crea el archivo de variables con el que Kustomize generará un ConfigMap: ```bash nano overlays/produccion/app.env ``` ```ini LOG_LEVEL=info CACHE_TTL=300 ``` Ahora el `kustomization.yaml` de producción. Combina un patch desde archivo, un patch JSON 6902 para un cambio puntual, el cambio de imagen y el generador: ```bash nano overlays/produccion/kustomization.yaml ``` ```yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - ../../base namespace: produccion namePrefix: prod- images: - name: nginx newTag: "1.27-alpine" configMapGenerator: - name: app-config envs: - app.env patches: - path: patch-deployment.yaml - target: kind: Deployment name: mi-aplicacion patch: |- - op: replace path: /spec/template/spec/containers/0/env/0/value value: produccion - op: add path: /spec/template/spec/containers/0/envFrom value: - configMapRef: name: app-config ``` Qué hace cada bloque: - `images` cambia la etiqueta de la imagen `nginx` en todos los recursos sin tocar la base. - `configMapGenerator` crea un ConfigMap a partir de `app.env` y añade un sufijo con el hash de su contenido (por ejemplo `prod-app-config-7h2k9fmt4b`). Kustomize actualiza automáticamente la referencia `app-config` del Deployment, así que cada cambio de configuración provoca un rollout. - El patch JSON 6902 usa operaciones exactas (`replace`, `add`, `remove`) sobre rutas del objeto. Es útil cuando el strategic merge no basta, por ejemplo para listas sin clave de fusión. Renderiza y revisa las partes clave: ```bash kubectl kustomize overlays/produccion | grep -E 'replicas:|image:|app-config|value: produccion' ``` ```output name: prod-app-config-7h2k9fmt4b replicas: 3 value: produccion name: prod-app-config-7h2k9fmt4b image: nginx:1.27-alpine ``` > Advertencia: `secretGenerator` funciona igual que `configMapGenerator`, pero no guardes contraseñas en archivos que vayan al repositorio. Genera los Secrets fuera de Git o usa una herramienta como Sealed Secrets o External Secrets. ## Paso 5: Desplegar los overlays en el clúster Kustomize no crea el namespace si no lo incluyes como recurso. Créalos: ```bash kubectl create namespace desarrollo kubectl create namespace produccion ``` Antes de aplicar, revisa las diferencias con lo que hay en el clúster. La primera vez todo aparece como nuevo: ```bash kubectl diff -k overlays/produccion ``` Aplica ambos overlays con la opción `-k`, que ejecuta Kustomize antes de enviar los manifiestos: ```bash kubectl apply -k overlays/desarrollo kubectl apply -k overlays/produccion ``` ```output configmap/prod-app-config-7h2k9fmt4b created service/prod-mi-aplicacion created deployment.apps/prod-mi-aplicacion created ``` Comprueba que el Deployment de producción tiene tres réplicas listas y la variable correcta: ```bash kubectl -n produccion rollout status deployment/prod-mi-aplicacion kubectl -n produccion exec deploy/prod-mi-aplicacion -- printenv ENTORNO LOG_LEVEL ``` ```output deployment "prod-mi-aplicacion" successfully rolled out produccion info ``` ## Paso 6: Actualizar la imagen desde un pipeline de CI/CD En un pipeline no conviene editar YAML a mano. La CLI independiente de Kustomize incluye `kustomize edit`, que modifica el `kustomization.yaml` de forma segura. Descarga el script oficial de instalación, revísalo y ejecútalo; deja el binario en el directorio actual: ```bash curl -fsSLO https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh less install_kustomize.sh bash install_kustomize.sh sudo install -m 0755 kustomize /usr/local/bin/kustomize kustomize version ``` Fija la nueva versión de la imagen en el overlay de producción: ```bash cd ~/mi-aplicacion/overlays/produccion kustomize edit set image nginx=nginx:1.28-alpine grep -A2 images kustomization.yaml ``` ```output images: - name: nginx newTag: 1.28-alpine ``` En el pipeline, tras este comando, haz commit del cambio y deja que la herramienta de GitOps lo despliegue, o aplícalo directamente con `kubectl apply -k .` seguido de `kubectl -n produccion rollout status deployment/prod-mi-aplicacion`. Si usas Argo CD, no necesitas configurar nada especial: detecta el `kustomization.yaml` del directorio indicado en `path` y lo renderiza: ```yaml apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: mi-aplicacion-produccion namespace: argocd spec: project: default source: repoURL: https://github.com/your_org/mi-aplicacion.git targetRevision: main path: overlays/produccion destination: server: https://kubernetes.default.svc namespace: produccion syncPolicy: automated: prune: true selfHeal: true ``` ## Solución de problemas **`accumulating resources: ... no such file or directory`**: una ruta de `resources` o `patches` no existe. Las rutas son relativas al directorio del `kustomization.yaml` que las declara, no al directorio desde el que ejecutas el comando. **El patch no se aplica o crea un recurso nuevo**: el `metadata.name` y el `kind` del patch deben coincidir con el recurso de la base, con el nombre original (sin `namePrefix`). **`field is immutable` al aplicar**: has cambiado etiquetas que forman parte de `spec.selector`, algo típico al usar `commonLabels`. Usa `labels` sin `includeSelectors` o recrea el Deployment. **Validar contra el esquema del clúster sin aplicar**: ```bash kubectl apply -k overlays/produccion --dry-run=server ``` ## Conclusión Has creado una base reutilizable y dos overlays que la adaptan a desarrollo y producción con patches strategic merge y JSON 6902, un ConfigMap generado con hash y un cambio de imagen automatizable. Como siguientes pasos, puedes gestionar los overlays con Argo CD o Flux, añadir componentes reutilizables con `kind: Component` para funcionalidades opcionales, o combinar Kustomize con Skaffold para el desarrollo local.