Saltar al contenido principal

Helm en Kubernetes

Helm es el gestor de paquetes de Kubernetes. Nos permite gestionar, versionar y desplegar aplicaciones completas (decenas de manifiestos) como una sola unidad llamada chart. Si venimos del mundo Linux, pensemos en él como el apt o pacman de Kubernetes.

Ya lo hemos usado varias veces en el curso (para instalar Cilium, el ingress controller o el dashboard); ahora toca entender cómo funciona por dentro.

Estructura de un chart​

Los componentes de un chart se estructuran de la siguiente manera:

├── Chart.yaml
├── README.md
├── templates
│ ├── NOTES.txt
│ ├── _helpers.tpl
│ ├── configmap.yaml
│ ├── deployment.yaml
│ ├── pvc.yaml
│ ├── secrets.yaml
│ └── svc.yaml
└── values.yaml

El fichero Chart.yaml contiene los metadatos del chart (nombre, versión, dependencias), el values.yaml contiene los valores configurables y la carpeta templates contiene los manifiestos de Kubernetes plantillados.

Las templates son manifiestos normales de Kubernetes en los que los valores variables se sustituyen por plantillas Go, de forma que el mismo chart sirva para diferentes propósitos y organizaciones. Por ejemplo:

apiVersion: v1
kind: Secret
metadata:
name: {{ template "fullname" . }}
labels:
app: {{ template "fullname" . }}
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
release: "{{ .Release.Name }}"
heritage: "{{ .Release.Service }}"
type: Opaque
data:
mariadb-root-password: {{ default "" .Values.mariadbRootPassword | b64enc | quote }}
mariadb-password: {{ default "" .Values.mariadbPassword | b64enc | quote }}

Este objeto de tipo secreto está plantillado para que todos sus campos se recojan del fichero de values. Esto nos permite centralizar la configuración en un único fichero (values.yaml) y, por otra parte, hacer que nuestros manifiestos de Kubernetes sean reutilizables.

Cada instalación de un chart en el cluster se llama release, y Helm guarda un historial de versiones de cada release que nos permitirá actualizar y hacer rollback.

Repositorios​

El buscador de referencia de charts es Artifact Hub, que indexa la mayoría de repositorios públicos.

Podríamos buscar charts con el comando:

helm search hub <nombre del chart> # Buscar en Artifact Hub

helm search repo <nombre> # Buscar dentro de los repositorios añadidos en local

También podríamos añadir nuevos repositorios, por ejemplo, el de podinfo, una pequeña aplicación web de demo, pública y bien mantenida, ideal para practicar:

helm repo add podinfo https://stefanprodan.github.io/podinfo

Ojo con Bitnami: durante años fue el repositorio por defecto en todos los tutoriales (bitnami/mariadb, bitnami/postgresql...). En 2025 Broadcom recortó su catálogo gratuito: las imágenes versionadas pasaron a docker.io/bitnamilegacy, sin actualizaciones ni parches de seguridad, y lo gratuito quedó reducido a un puñado de imágenes con la etiqueta latest. Los charts que dependen de esas imágenes pueden fallar al descargarlas, así que para aprender (y para producción) mejor tirar de charts mantenidos por el propio proyecto.

Los repositorios añadidos pueden actualizarse (refrescar su índice de charts) con el comando:

helm repo update

Si ahora quisiéramos buscar charts solo dentro de este repositorio, podríamos hacerlo así:

helm search repo podinfo

Desplegando un chart​

Podemos desplegar un chart directamente con helm install:

helm install <nombre de la release> <repositorio>/<chart>

# Por ejemplo:
helm install mi-podinfo podinfo/podinfo

Pero la mayoría de charts necesitan personalización. Tenemos dos opciones: pasar valores sueltos con --set o, mucho más mantenible, un fichero de valores propio con -f:

# Consultar los valores configurables del chart
helm show values podinfo/podinfo > mis-valores.yaml

# Editar mis-valores.yaml y desplegar con ellos
helm install mi-podinfo podinfo/podinfo -f mis-valores.yaml

Si preferimos inspeccionar el chart completo en local antes de instalarlo (leer su README, revisar las templates), podemos descargarlo:

helm pull podinfo/podinfo --untar
helm install mi-podinfo ./podinfo -f mis-valores.yaml

Consejo: antes de instalar, helm template renderiza los manifiestos finales sin aplicarlos, y helm install --dry-run --debug simula la instalación. Perfectos para revisar qué se va a crear exactamente en el cluster.

Muchos proyectos publican además sus charts como artefactos OCI (Open Container Initiative) en un registry de contenedores, sin necesidad de helm repo add:

helm install mi-podinfo oci://ghcr.io/stefanprodan/charts/podinfo

Ciclo de vida de una release​

Una vez desplegada, gestionamos la release con estos comandos:

# Listar las releases desplegadas y sus versiones
helm list

# Actualizar una release (nueva versión del chart o nuevos valores)
helm upgrade mi-podinfo podinfo/podinfo -f mis-valores.yaml

# Ver el historial de revisiones
helm history mi-podinfo

# Volver a una revisión anterior
helm rollback mi-podinfo 1

# Desinstalar la release
helm uninstall mi-podinfo

Helm 4: desde noviembre de 2025 está publicado Helm 4, la primera versión mayor en seis años. Los charts siguen siendo compatibles y los comandos de este capítulo funcionan igual, pero algunos flags cambian de nombre: --atomic pasa a ser --rollback-on-failure y --force pasa a --force-replace (los antiguos siguen funcionando, con aviso de deprecación). Helm 3 deja de recibir parches de seguridad el 11 de noviembre de 2026.

¿Nos suena este flujo? Es el mismo concepto de revisiones y rollbacks que vimos en los deployments, pero a nivel de aplicación completa.

Tres trampas que vimos en el curso presencial​

Una de las fases de la práctica final del curso presencial era pasar a Helm una aplicación que ya estaba desplegada con kubectl apply, hacerle un upgrade y luego un rollback. Por el camino aparecen tres sorpresas.

1. Helm no adopta recursos que no creó él​

Si el Deployment o el Service ya existen (los creamos antes con kubectl), helm install se niega a pisarlos. El error dice que el recurso exists and cannot be imported into the current release: invalid ownership metadata, y enumera lo que le falta.

Para que Helm lo adopte, hay que marcar cada recurso como suyo: una etiqueta y dos anotaciones con el nombre y el namespace de la release:

kubectl -n telemetria label deployment telemetria-api app.kubernetes.io/managed-by=Helm
kubectl -n telemetria annotate deployment telemetria-api \
meta.helm.sh/release-name=telemetria \
meta.helm.sh/release-namespace=telemetria

Con eso, helm install telemetria ./chart -n telemetria se queda con el recurso y lo actualiza según el chart. La alternativa, si podemos permitirnos un corte, es borrar los recursos y dejar que Helm los cree de cero.

2. upgrade y los valores que se pierden (o no llegan)​

  • Un helm upgrade sin -f ni --set reutiliza los valores de la revisión anterior. Pero en cuanto pasamos un solo --set, Helm parte de los valores por defecto del chart más ese --set: todo lo que pusimos en la instalación se pierde.
  • --reuse-values lo evita, pero con trampa: si el chart nuevo añade valores por defecto, no los recoge, y las plantillas que los usan pueden fallar o quedarse vacías.
  • --reset-then-reuse-values (desde Helm 3.14) es lo que casi siempre queremos: parte de los valores por defecto del chart nuevo, aplica encima los nuestros de la revisión anterior y, por último, los -f/--set de este comando.

Lo más seguro, de todas formas, es lo de siempre: un fichero de valores versionado en Git y helm upgrade -f valores.yaml cada vez. Sin sorpresas.

3. rollback borra lo que se añadió después​

Un rollback no "deshace cambios": deja el clúster como estaba en esa revisión. Si en la revisión 2 añadimos un HPA o una NetworkPolicy al chart, helm rollback telemetria 1 los borra, porque en la revisión 1 no existían. Si eso incluye un PVC, se van con él los datos.

Para proteger un recurso concreto de los borrados de Helm (rollback y uninstall incluidos), se le añade la anotación helm.sh/resource-policy: keep en la plantilla.

Crear nuestro propio chart​

Para empaquetar nuestras propias aplicaciones, Helm genera un esqueleto de chart funcional con un solo comando:

helm create mi-aplicacion

Esto crea la estructura que vimos al principio, con un deployment, service e ingress plantillados que podemos adaptar a nuestra aplicación. Es la mejor forma de aprender: generemos el esqueleto y estudiemos cómo están plantillados sus manifiestos.


Volver al índice