Gráficos de Helm: Gestión de paquetes de Kubernetes
Implementaciones de Kubernetes con gestión de paquetes Helm
Helm ha revolucionado la implementación de aplicaciones en Kubernetes al introducir conceptos de gestión de paquetes familiares de los sistemas operativos tradicionales.
A medida que aumenta la adopción de Kubernetes, gestionar aplicaciones complejas con docenas de archivos YAML se vuelve desafiante. Los Charts de Helm resuelven este problema empaquetando todos los recursos en paquetes versionados y configurables.
Esta imagen agradable fue generada por modelo AI Flux 1 dev.
Entendiendo Helm: El Gestor de Paquetes de Kubernetes
Helm es para Kubernetes lo que apt es para Debian, yum para RedHat o Homebrew para macOS. Empaqueta aplicaciones de Kubernetes en Charts – colecciones de archivos que describen recursos relacionados de Kubernetes. Un solo Chart podría desplegar una pila completa de aplicaciones: servidores web, bases de datos, capas de caché, reglas de entrada y componentes de monitoreo. Para aquellos nuevos en Kubernetes, una Guía rápida de Kubernetes proporciona comandos esenciales y conceptos para comenzar.
Por qué Helm importa en DevOps moderno
Reducción de complejidad: En lugar de gestionar 20+ archivos YAML, gestionas un solo Chart con valores personalizables.
Reproducibilidad: Despliega configuraciones idénticas en desarrollo, entorno de pruebas y producción con sobrescrituras de valores específicas del entorno. Esto es especialmente valioso al desplegar arquitecturas complejas de microservicios donde la consistencia importa.
Control de versiones: Los Charts están versionados, lo que permite fácil retroceso y seguimiento de actualizaciones.
Ecosistema de la comunidad: Miles de Charts preconstruidos disponibles a través de Artifact Hub (anteriormente Helm Hub) para aplicaciones populares como PostgreSQL, Redis, NGINX, Prometheus y más.
Poder de plantillas: Las plantillas de Go permiten la generación dinámica de recursos basados en valores de entrada, reduciendo la duplicación.
Arquitectura y conceptos clave de Helm
Arquitectura de Helm 3
Helm 3 simplificó la arquitectura al eliminar Tiller, el componente problemático del lado del servidor de Helm 2:
- Cliente Helm: Herramienta CLI que interactúa directamente con la API de Kubernetes
- Chart: Formato de paquete que contiene plantillas y metadatos
- Lanzamiento: Una instancia de un Chart en ejecución en un clúster de Kubernetes
- Repositorio: Ubicación de almacenamiento para Charts (servidor HTTP o registro OCI)
Componentes clave de un Chart de Helm
my-app-chart/
├── Chart.yaml # Metadatos y versión del Chart
├── values.yaml # Valores de configuración predeterminados
├── charts/ # Charts dependientes
├── templates/ # Plantillas de recursos de Kubernetes
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ ├── _helpers.tpl # Funciones de ayuda de plantilla
│ └── NOTES.txt # Notas posteriores a la instalación
├── .helmignore # Archivos a ignorar al empaquetar
├── README.md
└── LICENSE
Creando tu primer Chart de Helm
Inicializar un nuevo Chart
helm create my-application
cd my-application
Esto genera un Chart inicial con plantillas de ejemplo para un despliegue, servicio e ingreso.
Chart.yaml: Definiendo metadatos
apiVersion: v2
name: my-application
description: Un chart de aplicación listo para producción
type: application
version: 1.0.0 # Versión del chart
appVersion: "2.4.1" # Versión de la aplicación
maintainers:
- name: Tu Equipo
email: team@company.com
dependencies:
- name: postgresql
version: "12.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
values.yaml: Gestión de configuración
El archivo values.yaml define configuraciones predeterminadas que los usuarios pueden sobrescribir. Este enfoque separa la configuración de las plantillas, facilitando la gestión de diferentes entornos (desarrollo, pruebas, producción) y personalizando los despliegues sin modificar los archivos de plantilla.
replicaCount: 3
image:
repository: myapp/backend
tag: "1.0.0"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
ingress:
enabled: true
className: "nginx"
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
hosts:
- host: myapp.example.com
paths:
- path: /
pathType: Prefix
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 250m
memory: 256Mi
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
targetCPUUtilizationPercentage: 80
Plantillas: Manifestos dinámicos de Kubernetes
Las plantillas utilizan la sintaxis de plantillas de Go para generar dinámicamente recursos de Kubernetes. Estas plantillas pueden generar cualquier tipo de recurso de Kubernetes, desde simples Despliegues hasta complejos StatefulSets para aplicaciones que requieren almacenamiento persistente. Para aplicaciones que necesitan identidades estables y volúmenes persistentes, querrás usar StatefulSets en lugar de Despliegues, como se detalla en nuestra guía sobre StatefulSets y Almacenamiento Persistente en Kubernetes.
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "my-application.fullname" . }}
labels:
{{- include "my-application.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "my-application.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "my-application.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: 8080
protocol: TCP
resources:
{{- toYaml .Values.resources | nindent 10 }}
Ayudas de plantilla (_helpers.tpl)
Crea funciones de plantilla reutilizables para evitar la repetición:
{{/*
Expandir el nombre del chart.
*/}}
{{- define "my-application.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Crear un nombre completo de aplicación por defecto.
*/}}
{{- define "my-application.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{/*
Etiquetas comunes
*/}}
{{- define "my-application.labels" -}}
helm.sh/chart: {{ include "my-application.chart" . }}
{{ include "my-application.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
Gestión de Charts de Helm: Instalación y operaciones
Instalando un Chart
# Instalar desde un repositorio
helm install my-release bitnami/postgresql
# Instalar desde un directorio local
helm install my-app ./my-application
# Instalar con valores personalizados
helm install my-app ./my-application -f values-production.yaml
# Instalar con sobrescrituras de valores en línea
helm install my-app ./my-application \
--set replicaCount=5 \
--set image.tag=2.0.0
Actualizando lanzamientos
# Actualizar con nuevos valores
helm upgrade my-app ./my-application -f values-production.yaml
# Actualizar con retroceso automático en caso de error
helm upgrade my-app ./my-application --atomic --timeout 5m
# Forzar actualizaciones de recursos
helm upgrade my-app ./my-application --force
Retroceso y historial
# Ver historial de lanzamientos
helm history my-app
# Retroceder a la versión anterior
helm rollback my-app
# Retroceder a una revisión específica
helm rollback my-app 3
Pruebas y depuración
# Ejecutar simulación para ver los manifiestos generados
helm install my-app ./my-application --dry-run --debug
# Renderizado de plantillas sin instalación
helm template my-app ./my-application
# Revisar el chart para problemas
helm lint ./my-application
# Probar lanzamiento con ganchos de prueba
helm test my-app
Características avanzadas de Helm
Dependencias de Chart
Los Charts de Helm pueden depender de otros Charts, lo que permite componer aplicaciones complejas a partir de componentes reutilizables. Esto es especialmente útil al desplegar microservicios que necesitan bases de datos, colas de mensajes u otros servicios de soporte. Define dependencias en Chart.yaml:
dependencies:
- name: redis
version: "17.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: redis.enabled
- name: postgresql
version: "12.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
Actualizar dependencias:
helm dependency update ./my-application
Ganchos de Helm para gestión del ciclo de vida
Los ganchos se ejecutan en puntos específicos del ciclo de vida del lanzamiento:
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "my-application.fullname" . }}-db-migration
annotations:
"helm.sh/hook": pre-upgrade,pre-install
"helm.sh/hook-weight": "5"
"helm.sh/hook-delete-policy": before-hook-creation
spec:
template:
spec:
containers:
- name: db-migrate
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
command: ["python", "manage.py", "migrate"]
restartPolicy: Never
Tipos de ganchos incluyen:
pre-install: Antes de instalar los recursospost-install: Después de instalar todos los recursospre-upgrade: Antes de la actualizaciónpost-upgrade: Después de la actualizaciónpre-delete: Antes de la eliminaciónpost-delete: Después de la eliminaciónpre-rollback: Antes del retrocesopost-rollback: Después del retroceso
Lógica condicional y control de flujo
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "my-application.fullname" . }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.className }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
pathType: {{ .pathType }}
backend:
service:
name: {{ include "my-application.fullname" $ }}
port:
number: {{ $.Values.service.port }}
{{- end }}
{{- end }}
{{- end }}
Soporte de registro OCI: Distribución moderna de Charts
Desde Helm 3.8, el soporte para registros OCI (Open Container Initiative) es estable, permitiendo almacenar Charts junto con imágenes de contenedor.
Publicar en un registro OCI
# Iniciar sesión en el registro
helm registry login registry.example.com
# Empaquetar el chart
helm package ./my-application
# Enviar al registro OCI
helm push my-application-1.0.0.tgz oci://registry.example.com/charts
# Instalar desde el registro OCI
helm install my-app oci://registry.example.com/charts/my-application --version 1.0.0
Ventajas de los registros OCI
- Almacenamiento unificado: Charts e imágenes en un solo lugar
- Herramientas estándar: Usar infraestructura de registro existente
- Mejor seguridad: Aprovechar autenticación y escaneo del registro
- Gestión más sencilla: No se necesita un servidor de repositorio de Charts separado
Mejores prácticas para Charts de Helm en producción
1. Estructura y documentación de valores
Documenta todos los valores con comentarios:
# -- Número de réplicas para la aplicación
replicaCount: 3
# -- Configuración de imagen
image:
# -- Repositorio de imagen
repository: myapp/backend
# -- Política de extracción de imagen
pullPolicy: IfNotPresent
# -- Etiqueta de imagen (por defecto, appVersion del chart)
tag: ""
2. Gestión de recursos
Siempre establece solicitudes y límites de recursos:
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 500m
memory: 512Mi
3. Contextos de seguridad
Define contextos de seguridad para contenedores:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
4. Pruebas de salud
Incluye pruebas de vivacidad y preparación:
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
5. Gestión de ConfigMap y Secret
La gestión adecuada de secretos es crítica para despliegues en producción. Usa gestores de secretos externos (Sealed Secrets, External Secrets Operator o Vault) en lugar de almacenar secretos en archivos de valores. Esto asegura que datos sensibles como contraseñas de base de datos, claves API y certificados se manejen de forma segura:
envFrom:
- secretRef:
name: {{ include "my-application.fullname" . }}-secrets
- configMapRef:
name: {{ include "my-application.fullname" . }}-config
6. Validación de esquema
Crea values.schema.json para validar entradas de usuario:
{
"$schema": "https://json-schema.org/draft-07/schema#",
"properties": {
"replicaCount": {
"type": "integer",
"minimum": 1
},
"image": {
"type": "object",
"properties": {
"repository": {
"type": "string"
},
"tag": {
"type": "string"
}
},
"required": ["repository"]
}
},
"required": ["image"]
}
7. NOTES.txt para orientación al usuario
Proporciona instrucciones posteriores a la instalación:
1. Obten la URL de la aplicación ejecutando:
{{- if .Values.ingress.enabled }}
https://{{ (index .Values.ingress.hosts 0).host }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "my-application.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- end }}
2. Monitorea el despliegue:
kubectl --namespace {{ .Release.Namespace }} get pods -l "app.kubernetes.io/name={{ include "my-application.name" . }}"
Pruebas de Chart de Helm e integración con CI/CD
Pruebas de Chart con chart-testing (ct)
# Instalar chart-testing
brew install chart-testing
# Lintear charts
ct lint --config ct.yaml
# Instalar y probar charts
ct install --config ct.yaml
Ejemplo de GitHub Actions
name: Helm Chart CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lint-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Configurar Helm
uses: azure/setup-helm@v3
with:
version: 3.12.0
- name: Configurar chart-testing
uses: helm/chart-testing-action@v2
- name: Lintear charts
run: ct lint --config ct.yaml
- name: Crear clúster kind
uses: helm/kind-action@v1
- name: Instalar charts
run: ct install --config ct.yaml
GitOps con Helm: ArgoCD y Flux
Herramientas de GitOps como ArgoCD y Flux se integran de forma fluida con Charts de Helm, permitiendo despliegues declarativos y automatizados. Estas herramientas vigilan tu repositorio de Git para cambios y sincronizan automáticamente los lanzamientos de Helm, haciendo el despliegue continuo sencillo. Para arquitecturas complejas de microservicios, considera cómo patrones de transacciones distribuidas como el patrón Saga pueden ayudar a gestionar la consistencia en servicios desplegados mediante Helm.
Aplicación de ArgoCD
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-application
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/my-app-chart
targetRevision: main
path: charts/my-application
helm:
valueFiles:
- values-production.yaml
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
HelmRelease de Flux
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: my-application
namespace: flux-system
spec:
interval: 5m
chart:
spec:
chart: my-application
version: '1.x.x'
sourceRef:
kind: HelmRepository
name: my-charts
values:
replicaCount: 5
image:
tag: "2.0.0"
Solución de problemas de problemas comunes de Helm
Problema: Actualización fallida en estado pendiente
# Verificar el estado del lanzamiento
helm list --all-namespaces
# Ver detalles del lanzamiento
helm status my-app -n namespace
# Eliminar forzado si es necesario (usar con cuidado)
kubectl delete secret -n namespace -l owner=helm,name=my-app
Problema: Errores de renderizado de plantillas
# Depurar el renderizado de plantillas
helm template my-app ./my-application --debug
# Validar contra Kubernetes
helm template my-app ./my-application | kubectl apply --dry-run=client -f -
Problema: Valores no aplicados
# Ver valores fusionados
helm get values my-app
# Mostrar todos los valores calculados
helm get values my-app --all
Ecosistema y herramientas de Helm
El ecosistema de Helm incluye numerosas herramientas que extienden sus capacidades e integran con otras tecnologías de Kubernetes. Cuando se despliegan aplicaciones que requieren características avanzadas de red como comunicación servicio a servicio, gestión de tráfico y políticas de seguridad, considere integrarse con una Red de Servicios con Istio y Linkerd, que pueden desplegarse y gestionarse mediante Charts de Helm.
Herramientas esenciales
- Helmfile: Especificación declarativa para desplegar Charts de Helm
- Helm Diff: Previsualizar cambios antes de la actualización
- Helm Secrets: Gestionar secretos con SOPS
- Nova: Encontrar Charts de Helm obsoletos
- Pluto: Detectar APIs de Kubernetes obsoletas
Ejemplo de Helmfile
repositories:
- name: bitnami
url: https://charts.bitnami.com/bitnami
releases:
- name: postgresql
namespace: database
chart: bitnami/postgresql
version: 12.x.x
values:
- postgresql:
auth:
database: myapp
username: appuser
- name: my-app
namespace: production
chart: ./charts/my-application
values:
- values-production.yaml
needs:
- database/postgresql
El futuro de Helm
El ecosistema de Helm continúa evolucionando:
- Nativo de OCI: Transición completa a registros OCI como estándar
- Mejora de seguridad: Mejores herramientas de gestión de secretos y capacidades de firma
- Rendimiento: Rendimiento más rápido de renderizado e instalación para Charts grandes
- Soporte de WASM: WebAssembly para plugins y extensiones de Chart
- Mejor validación: Validación de esquema mejorada y cumplimiento de políticas
Conclusión
Helm se ha convertido en el estándar de facto para la gestión de paquetes en Kubernetes, y dominarlo es esencial para las prácticas modernas de DevOps. Al comprender la estructura del Chart, plantillas, gestión de valores y mejores prácticas, puedes crear despliegues de Kubernetes mantenibles, seguros y escalables.
Comienza con Charts simples, incorpora gradualmente características avanzadas como ganchos y dependencias, e integra con herramientas de GitOps para infraestructura de producción. La comunidad de Helm proporciona miles de Charts preconstruidos, pero el verdadero poder proviene de crear Charts personalizados adaptados a las necesidades de tu organización. Ya sea que estés desplegando aplicaciones sin estado o cargas de trabajo con estado que requieren almacenamiento persistente, Helm simplifica la complejidad de la gestión de recursos de Kubernetes. Para equipos que están configurando nuevos clústeres de Kubernetes, considere instalar Kubernetes con Kubespray o explorar distribuciones de Kubernetes como k3s o MicroK8s para entornos de desarrollo. Si estás evaluando qué distribución se ajusta a tus necesidades de homelab o clúster pequeño, consulta nuestro análisis comparativo completo de distribuciones de Kubernetes para un análisis detallado.
Enlaces útiles
- Documentación oficial de Helm
- Artifact Hub - Descubrir Charts de Helm
- Repositorio de GitHub de Helm
- Guía de mejores prácticas de Helm
- Herramienta de prueba de Charts
- Helmfile
- ArgoCD
- Flux CD
- Repositorio de Charts de Bitnami
- Guía rápida de Kubernetes
- Instalar Kubernetes con Kubespray
- Comparación de distribuciones de Kubernetes para un homelab de 3 nodos
- Distribuciones de Kubernetes - visión general de kubeadm, k3s, MicroK8s, Minikube, Talos Linux y RKE2
- Red de servicios con Istio y Linkerd
- StatefulSets y Almacenamiento Persistente en Kubernetes
- Patrón Saga en transacciones distribuidas