Helm rellena un chart desde values.yaml. Kustomize parcha YAML que ya puedes leer. Ambos emiten manifiestos, y ambos pueden configurar el mismo recuento de réplicas y etiqueta de imagen. Esta página muestra cómo cambiar en ambas direcciones, luego cuándo un chart, un overlay, o ambos es el propietario correcto.

Respuesta corta

Elige Helm cuando la unidad de entrega es una versión: un tarball o un artefacto OCI, un historial de revisión, y un comando que instala o hace rollback de cada objeto. Elige Kustomize cuando la unidad es un directorio y cada entorno es un parche en una base. kubectl 1.30 ya incluye Kustomize, así que kubectl apply -k, kubectl diff -k, y kubectl kustomize no necesitan instalación extra.

Las plantillas Helm son plantillas Go. Pueden saltar un documento con if, o fallar el render cuando falta un value. Kustomize no tiene lenguaje de plantilla. Un objeto opcional es un archivo listado solo en el overlay que lo necesita.

Lado a lado

Helm 3 Kustomize
Entrada Chart (Chart.yaml, values.yaml, templates/) Directorio con kustomization.yaml
Cómo difieren los entornos Otro archivo values, o --set Overlay: images, replicas, patches, namespace
Dry run helm template, o helm upgrade --dry-run kubectl kustomize, o kubectl diff -k
Aplicar helm upgrade --install kubectl apply -k
Historial Revisiones en un Secret en el namespace de lanzamiento Historial de git, más historial de rollout de Deployment
Rollback del conjunto completo helm rollback <release> <revision> Aplica un commit más antiguo
Rollback de un Deployment Posible, pero el siguiente upgrade puede revertirlo kubectl rollout undo
Comparte con otro equipo Chart repo o OCI registry Copia un directorio, o apunta a una base remota
Integrado en kubectl No Sí (-k / kubectl kustomize)

kubectl diff -k sale con 1 cuando los objetos live difieren del build. Eso es un diff, no un binario roto. Cuenta con eso en CI antes de tratar el código de salida como un fallo.

El mismo cambio, ambas formas

El objetivo es tres réplicas de API y la etiqueta 1.4.2.

Values de Helm:

replicaCount: 3
image:
  repository: example/api
  tag: "1.4.2"

La plantilla solo reemplaza lo que varía. required detiene un render que de otro modo imprimiría un recuento de réplicas vacío:

spec:
  replicas: {{ required "replicaCount is required" .Values.replicaCount }}
  template:
    spec:
      containers:
        - name: api
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
helm lint ./chart
helm upgrade --install api ./chart -n demo --create-namespace -f values/prod.yaml --wait --timeout 3m
helm history api -n demo

--wait bloquea hasta que el Deployment esté disponible o --timeout se alcance. --atomic hace rollback de un upgrade fallido, y desinstala un primer install fallido.

La base de Kustomize lista los manifiestos planos. El overlay de producción no los copia:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - ../../base
namespace: prod
replicas:
  - name: api
    count: 3
images:
  - name: example/api
    newTag: "1.4.2"
patches:
  - path: memory.yaml
    target:
      kind: Deployment
      name: api

newTag edita YAML. No construye una imagen. images.name es el repositorio sin la etiqueta. En el parche abajo, el name del contenedor es la clave de merge:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  template:
    spec:
      containers:
        - name: api
          resources:
            requests:
              memory: 256Mi
            limits:
              memory: 512Mi
kubectl kustomize overlays/prod
kubectl diff -k overlays/prod
kubectl apply -k overlays/prod

-k es el flag integrado en apply, diff, y delete. kubectl kustomize solo imprime el build.

Prefiere labels cuando no quieres que los selectores se reescriban. commonLabels aún escribe en selectores, que son dolorosos de cambiar después.

labels:
  - pairs:
      app.kubernetes.io/part-of: shop
    includeSelectors: false

Cuándo elegir Helm

Elige Helm para ingress-nginx, cert-manager, o cualquier chart que no quieras bifurcar. Fija una versión. Los repositorios HTTP aún funcionan:

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm search repo ingress-nginx/ingress-nginx --versions
helm show values ingress-nginx/ingress-nginx

helm show values imprime las claves que el chart honra. Si falta una configuración, parcha el render después. No bifurques un chart para un límite de memoria de una línea.

Publica tu propia app como un artefacto OCI. La URL de push no tiene nombre de chart ni versión. Helm lee ambas del tarball. La URL de instalación incluye el nombre del chart.

helm package ./chart
helm registry login ghcr.io -u myuser
helm push shop-0.1.0.tgz oci://ghcr.io/example/charts
helm upgrade --install shop oci://ghcr.io/example/charts/shop --version 0.1.0 -n demo --create-namespace

helm package nombra el archivo desde Chart.yaml (name más version). apiVersion: v2 es el Helm 3 chart API. helm registry login toma un host (ghcr.io), no una URL con esquema o ruta.

Usa un if de plantilla cuando un documento existe solo en algunos entornos. Mantén la plantilla delgada así los revisores aún pueden ver el YAML.

Cuándo elegir Kustomize

Elige Kustomize cuando cada entorno es el mismo Deployment con una etiqueta diferente, namespace, o recuento de réplicas. La base sigue siendo YAML válido. Los overlays no tienen loops. El git diff es el cluster diff.

configMapGenerator y secretGenerator hashean el nombre del objeto y reescriben referencias en esa kustomización, así un cambio de datos hace rollout de Pods. Configura generatorOptions.disableNameSuffixHash: true solo cuando un llamador fuera del overlay necesita un nombre fijo. Entonces posees el rollout.

Prueba el overlay en un laptop cluster desde kind vs minikube vs k3d antes de que lo apuntes a una API compartida. El movimiento Compose-a-manifiestos en forma de app se cubre en Docker Compose vs Kubernetes.

Cuándo usar ambas

Un propietario. Un helm upgrade posterior sobrescribe un campo que parcheaste con kubectl. Si aplicas YAML renderizado y nunca instalas un lanzamiento, helm rollback no tiene nada que restaurar.

Renderiza, luego parcha. Esta es la forma trabajable de «helm template, luego kustomize». kubectl apply -k lee un directorio, no un pipe, así que escribe el render a un archivo que el overlay lista:

helm template shop ./chart -n prod -f values/prod.yaml > overlays/prod/all.yaml
kubectl apply -k overlays/prod

Haz rollback aplicando un all.yaml más antiguo, o kubectl rollout undo deployment/api -n prod para solo ese Deployment. Más patrones de kubectl están en la chuleta de kubectl.

Infla un chart dentro de Kustomize. helmCharts ejecuta helm template como un subproceso. Helm debe estar en PATH (--helm-command si el binario se llama algo más). --enable-helm existe en kubectl kustomize y no existe en kubectl apply, así que -k da error cuando helmCharts está presente.

helmCharts:
  - name: ingress-nginx
    repo: https://kubernetes.github.io/ingress-nginx
    version: X.Y.Z
    releaseName: ingress-nginx
    namespace: ingress-nginx
    valuesFile: values.yaml

Reemplaza X.Y.Z con una versión de helm search repo ingress-nginx/ingress-nginx --versions. Luego:

kubectl kustomize --enable-helm overlays/prod | kubectl apply -f -

Aún no hay lanzamiento de Helm. El chart es solo una fuente de YAML.

Secretos

Helm almacena cada revisión en un Secret nombrado sh.helm.release.v1.<release>.v<revision> (tipo helm.sh/release.v1) en el namespace de lanzamiento. El payload incluye los values. Cualquiera que pueda obtener Secrets allí puede recuperarlos. La encriptación en reposo es una configuración de etcd, no un flag de Helm.

Apunta el chart a un Secret que ya existe (existingSecret es una clave de values común, no un campo universal). Créalo fuera de git:

kubectl create secret generic app-secret -n demo --from-literal=POSTGRES_PASSWORD="$POSTGRES_PASSWORD"

Un literal secretGenerator es plaintext en git. kubectl apply -k crea el Secret y no desencripta nada. Desencripta antes de apply si lo necesitas. Los generadores exec no son parte de un run de plain -k.

helm.sh/resource-policy: keep le dice a helm uninstall que deje ese objeto. No lo oculta ni encripta.

Ruta de migración

Lanzamiento Helm a Kustomize. Captura el render, marca objetos así uninstall los deja, luego aplica el directorio.

helm get manifest api -n demo > base/all.yaml
helm get values api -n demo > values-used.yaml
kubectl -n demo annotate deploy,svc,cm,secret,pvc -l app.kubernetes.io/instance=api helm.sh/resource-policy=keep --overwrite
helm uninstall api -n demo
kubectl apply -k overlays/prod

Helm 3 configura app.kubernetes.io/instance al nombre de lanzamiento a menos que el chart reemplazara etiquetas. Si un tipo no tiene coincidencias, suéltalo y anota de nuevo. Uninstall elimina cualquier cosa sin helm.sh/resource-policy: keep. Elimina la anotación después con un guion al final: kubectl annotate ... helm.sh/resource-policy-.

Directorio Kustomize a un lanzamiento Helm. Diff primero. Helm 3.2 y posterior se niega a objetos existentes hasta que lleven su metadatos de propiedad.

kubectl kustomize overlays/prod > /tmp/before.yaml
helm template api ./chart -n demo -f values/prod.yaml > /tmp/after.yaml
diff -u /tmp/before.yaml /tmp/after.yaml

Cuando el diff restante es solo etiquetas que aceptas, marca los objetos e instala:

kubectl -n demo annotate deployment/api svc/api cm/app-config secret/app-secret \
  meta.helm.sh/release-name=api meta.helm.sh/release-namespace=demo --overwrite
kubectl -n demo label deployment/api svc/api cm/app-config secret/app-secret \
  app.kubernetes.io/managed-by=Helm --overwrite
helm upgrade --install api ./chart -n demo -f values/prod.yaml

Repite eso para cada objeto que el chart renderiza.

helm rollback api 2 -n demo --wait

Omite la revisión para volver a la anterior. kubectl rollout undo deployment/api -n demo solo rebobina la plantilla de Pod de ese Deployment. Usa helm rollback cuando el cambio malo se extendió por el Ingress, el ConfigMap, y el Deployment juntos.

Preguntas frecuentes

¿Debo usar Helm o Kustomize?

Usa Helm cuando publiques un paquete versionado o instales un chart de alguien más. Usa Kustomize cuando posees el YAML y los entornos difieren por etiqueta de imagen, recuento de réplicas, namespace, o un pequeño parche. kubectl ya ejecuta Kustomize. Helm es un binario separado.

¿Puedo usar Helm y Kustomize juntos?

Sí, si solo uno de ellos posee el apply. Renderiza con helm template, parcha con Kustomize, y kubectl apply -k el resultado. O renderiza un chart con kubectl kustomize --enable-helm y aplica ese resultado. No hagas helm upgrade a objetos que Kustomize también parcha. El siguiente upgrade pone la copia del chart de vuelta.

¿Cómo hago rollback de un lanzamiento de Helm versus un apply de Kustomize?

helm rollback <release> <revision> restaura cada objeto de esa revisión. Kustomize no tiene objeto de lanzamiento. Aplica un overlay más antiguo de git, o ejecuta kubectl rollout undo deployment/<name> para un Deployment. El undo no revierte Services, ConfigMaps, o cualquier cosa en el overlay.

¿Dónde deben vivir las contraseñas de base de datos?

En un Secret creado fuera del repo de git, referenciado por nombre. Helm copia values a un Secret de lanzamiento en el mismo namespace, así que una contraseña en values.yaml es legible por cualquiera que pueda obtener Secrets. Los literales secretGenerator de Kustomize son plaintext en git. Ninguna herramienta es una tienda de secretos.

Cómo se verificó esta guía

Escrita a mano a partir de la documentación oficial, con cada comando comprobado de nuevo y una segunda revisión antes de publicar. Última revisión: .

Fuentes oficiales consultadas para este artículo

Share.

Los comentarios están cerrados.