Helm Charts: Gestione dei pacchetti Kubernetes
Distribuzioni Kubernetes con la gestione dei pacchetti Helm
Helm ha rivoluzionato Kubernetes il deployment di applicazioni introducendo concetti di gestione dei pacchetti familiari provenienti da sistemi operativi tradizionali.
Con l’aumento dell’adozione di Kubernetes, la gestione di applicazioni complesse con decine di file YAML diventa impegnativa. I Helm Charts risolvono questo problema imballando tutte le risorse in pacchetti versionati e configurabili.
Questa bella immagine è generata da AI model Flux 1 dev.
Comprendere Helm: Il Gestore dei Pacchetti Kubernetes
Helm è per Kubernetes ciò che apt è per Debian, yum per RedHat, o Homebrew per macOS. Imballa le applicazioni Kubernetes in Charts – raccolte di file che descrivono risorse Kubernetes correlate. Un singolo Chart potrebbe distribuire un intero stack applicativo: server web, database, strati di caching, regole di ingresso e componenti di monitoraggio. Per coloro che sono nuovi a Kubernetes, una Kubernetes Cheatsheet fornisce comandi essenziali e concetti per iniziare.
Perché Helm è Importante nel Moderno DevOps
Riduzione della Complessità: Invece di gestire 20+ file YAML, si gestisce un singolo Chart con valori personalizzabili.
Riproducibilità: Distribuisci configurazioni identiche in ambienti di sviluppo, staging e produzione con sovrascritture di valori specifiche per l’ambiente. Questo è particolarmente utile quando si distribuiscono architetture microservizi complesse dove la coerenza è importante.
Controllo delle Versioni: I Charts sono versionati, abilitando il rollback facile e il tracciamento degli aggiornamenti.
Ecosistema della Comunità: Migliaia di Charts pre-costruiti disponibili tramite Artifact Hub (precedentemente Helm Hub) per applicazioni popolari come PostgreSQL, Redis, NGINX, Prometheus e altro.
Potere di Templating: I template Go abilitano la generazione dinamica di risorse basata sui valori di input, riducendo la duplicazione.
Architettura Helm e Concetti Principali
Architettura Helm 3
Helm 3 ha semplificato l’architettura rimuovendo Tiller, il componente problematico del lato server da Helm 2:
- Helm Client: Strumento CLI che interagisce direttamente con l’API Kubernetes
- Chart: Formato del pacchetto che contiene template e metadati
- Release: Un’istanza di un Chart in esecuzione in un cluster Kubernetes
- Repository: Posizione di archiviazione per i Charts (server HTTP o registro OCI)
Componenti Principali di un Helm Chart
my-app-chart/
├── Chart.yaml # Metadati e versione del Chart
├── values.yaml # Valori di configurazione predefiniti
├── charts/ # Charts dipendenti
├── templates/ # Template delle risorse Kubernetes
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ ├── _helpers.tpl # Aiuti per i template
│ └── NOTES.txt # Note post-installazione
├── .helmignore # File da ignorare durante l'imballaggio
├── README.md
└── LICENSE
Creare il Primo Helm Chart
Inizializzare un Nuovo Chart
helm create my-application
cd my-application
Questo genera un Chart iniziale con template di esempio per un deployment, un servizio e un ingresso.
Chart.yaml: Definire i Metadati
apiVersion: v2
name: my-application
description: Un Chart applicativo pronto per la produzione
type: application
version: 1.0.0 # Versione del Chart
appVersion: "2.4.1" # Versione dell'applicazione
maintainers:
- name: Il tuo Team
email: team@company.com
dependencies:
- name: postgresql
version: "12.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
values.yaml: Gestione della Configurazione
Il file values.yaml definisce le configurazioni predefinite che gli utenti possono sovrascrivere. Questo approccio separa la configurazione dai template, rendendo facile la gestione di diversi ambienti (sviluppo, staging, produzione) e la personalizzazione dei deployment senza modificare i file template.
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
Template: Manifesti Kubernetes Dinamici
I template utilizzano la sintassi di templating Go per generare dinamicamente le risorse Kubernetes. Questi template possono generare qualsiasi tipo di risorsa Kubernetes, da semplici Deployments a complessi StatefulSets per applicazioni che richiedono storage persistente. Per applicazioni che necessitano di identità stabili e volumi persistente, si desidera utilizzare StatefulSets invece di Deployments, come dettagliato nella nostra guida su StatefulSets e Storage Persistente in 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 }}
Aiuti per Template (_helpers.tpl)
Crea funzioni riutilizzabili per evitare la ripetizione:
{{/*
Espandi il nome del Chart.
*/}}
{{- define "my-application.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Crea un nome completo di app predefinito.
*/}}
{{- 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 }}
{{/*
Etichette comuni
*/}}
{{- 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 }}
Gestione dei Charts Helm: Installazione e Operazioni
Installare un Chart
# Installare da un repository
helm install my-release bitnami/postgresql
# Installare da una directory locale
helm install my-app ./my-application
# Installare con valori personalizzati
helm install my-app ./my-application -f values-production.yaml
# Installare con sovrascritture di valori inline
helm install my-app ./my-application \
--set replicaCount=5 \
--set image.tag=2.0.0
Aggiornare le Releases
# Aggiornare con nuovi valori
helm upgrade my-app ./my-application -f values-production.yaml
# Aggiornare con rollback automatico in caso di fallimento
helm upgrade my-app ./my-application --atomic --timeout 5m
# Forzare l'aggiornamento delle risorse
helm upgrade my-app ./my-application --force
Rollback e Storia
# Visualizzare la storia delle releases
helm history my-app
# Rollback alla versione precedente
helm rollback my-app
# Rollback a una revisione specifica
helm rollback my-app 3
Test e Debugging
# Dry-run per visualizzare i manifesti generati
helm install my-app ./my-application --dry-run --debug
# Rendering dei template senza installazione
helm template my-app ./my-application
# Verifica del Chart per problemi
helm lint ./my-application
# Test della release con hook di test
helm test my-app
Funzionalità Avanzate di Helm
Dipendenze del Chart
I Charts Helm possono dipendere da altri Charts, permettendoti di comporre applicazioni complesse da componenti riutilizzabili. Questo è particolarmente utile quando si distribuiscono microservizi che necessitano di database, code di messaggi o altri servizi di supporto. Definisci le dipendenze in 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
Aggiorna le dipendenze:
helm dependency update ./my-application
Hook Helm per la Gestione del Ciclo di Vita
I hook vengono eseguiti in punti specifici del ciclo di vita della release:
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
I tipi di hook includono:
pre-install: Prima che le risorse siano installatepost-install: Dopo che tutte le risorse sono state installatepre-upgrade: Prima dell’aggiornamentopost-upgrade: Dopo l’aggiornamentopre-delete: Prima dell’eliminazionepost-delete: Dopo l’eliminazionepre-rollback: Prima del rollbackpost-rollback: Dopo il rollback
Logica Condizionale e Controllo del Flusso
{{- 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 }}
Supporto per Registri OCI: Distribuzione Moderna dei Charts
Da Helm 3.8, il supporto per i registri OCI (Open Container Initiative) è stabile, permettendo ai Charts di essere archiviati insieme alle immagini container.
Pubblicare su Registro OCI
# Accedi al registro
helm registry login registry.example.com
# Imballa il Chart
helm package ./my-application
# Pubblica sul registro OCI
helm push my-application-1.0.0.tgz oci://registry.example.com/charts
# Installa da registro OCI
helm install my-app oci://registry.example.com/charts/my-application --version 1.0.0
Vantaggi dei Registri OCI
- Archiviazione Unificata: Charts e immagini nello stesso posto
- Strumenti Standard: Utilizza l’infrastruttura esistente del registro
- Migliore Sicurezza: Sfrutta l’autenticazione e la scansione del registro
- Gestione Più Semplice: Non è necessario un server separato per i Chart
Migliori Pratiche per Charts Helm in Produzione
1. Struttura e Documentazione dei Valori
Documenta tutti i valori con commenti:
# -- Numero di repliche per l'applicazione
replicaCount: 3
# -- Configurazione dell'immagine
image:
# -- Repository dell'immagine
repository: myapp/backend
# -- Politica di pull dell'immagine
pullPolicy: IfNotPresent
# -- Tag dell'immagine (predefinito al valore appVersion del Chart)
tag: ""
2. Gestione delle Risorse
Imposta sempre le richieste e i limiti delle risorse:
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 500m
memory: 512Mi
3. Contesti di Sicurezza
Definisci contesti di sicurezza per i contenitori:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
4. Controlli di Salute
Includi probe di vitalità e prontezza:
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
5. Gestione di ConfigMap e Secret
La gestione corretta dei secret è cruciale per le distribuzioni in produzione. Utilizza gestori esterni di secret (Sealed Secrets, External Secrets Operator o Vault) invece di archiviare i secret nei file values. Questo garantisce che dati sensibili come password del database, chiavi API e certificati siano gestiti in modo sicuro:
envFrom:
- secretRef:
name: {{ include "my-application.fullname" . }}-secrets
- configMapRef:
name: {{ include "my-application.fullname" . }}-config
6. Validazione dello Schema
Crea values.schema.json per validare gli input degli utenti:
{
"$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 per Guida all’Utente
Fornisci istruzioni post-installazione:
1. Ottenere l'URL dell'applicazione eseguendo:
{{- 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. Monitorare il deployment:
kubectl --namespace {{ .Release.Namespace }} get pods -l "app.kubernetes.io/name={{ include "my-application.name" . }}"
Test dei Charts Helm e Integrazione con CI/CD
Test dei Charts con chart-testing (ct)
# Installa chart-testing
brew install chart-testing
# Lint dei Charts
ct lint --config ct.yaml
# Installa e testa i Charts
ct install --config ct.yaml
Esempio di 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: Set up Helm
uses: azure/setup-helm@v3
with:
version: 3.12.0
- name: Set up chart-testing
uses: helm/chart-testing-action@v2
- name: Lint charts
run: ct lint --config ct.yaml
- name: Create kind cluster
uses: helm/kind-action@v1
- name: Install charts
run: ct install --config ct.yaml
GitOps con Helm: ArgoCD e Flux
Strumenti GitOps come ArgoCD e Flux si integrano in modo fluido con i Charts Helm, abilitando deployment dichiarativi e automatizzati. Questi strumenti monitorano il tuo repository Git per modifiche e sincronizzano automaticamente le releases Helm, rendendo il deployment continuo semplice. Per architetture microservizi complesse, considera come i pattern di transazioni distribuite come il pattern Saga possono aiutare a gestire la coerenza tra servizi distribuiti tramite Helm.
Applicazione 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 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"
Risoluzione dei Problemi Comuni con Helm
Problema: Aggiornamento Fallito Bloccato in Pendente
# Controlla lo stato della release
helm list --all-namespaces
# Ottieni i dettagli della release
helm status my-app -n namespace
# Forza l'eliminazione se necessario (usa con attenzione)
kubectl delete secret -n namespace -l owner=helm,name=my-app
Problema: Errori di Rendering dei Template
# Debug del rendering dei template
helm template my-app ./my-application --debug
# Valida contro Kubernetes
helm template my-app ./my-application | kubectl apply --dry-run=client -f -
Problema: Valori Non Applicati
# Controlla i valori fusi
helm get values my-app
# Mostra tutti i valori calcolati
helm get values my-app --all
Ecosistema e Strumenti Helm
L’ecosistema Helm include numerosi strumenti che estendono le sue capacità e si integrano con altre tecnologie Kubernetes. Quando si distribuiscono applicazioni che richiedono funzionalità avanzate di rete come la comunicazione servizio-servizio, la gestione del traffico e le politiche di sicurezza, considera l’integrazione con un Service Mesh con Istio e Linkerd, che possono essere distribuiti e gestiti tramite Charts Helm.
Strumenti Essenziali
- Helmfile: Specifica dichiarativa per distribuire Charts Helm
- Helm Diff: Anteprima dei cambiamenti prima dell’aggiornamento
- Helm Secrets: Gestione dei secret con SOPS
- Nova: Trova Charts Helm obsoleti
- Pluto: Rileva API Kubernetes deprecate
Esempio di 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
Il Futuro di Helm
L’ecosistema Helm continua ad evolversi:
- OCI-Nativo: Transizione completa ai registri OCI come standard
- Migliore Sicurezza: Migliori funzionalità di gestione dei secret e firma
- Prestazioni: Rendering e installazione più veloci per Charts grandi
- Supporto WASM: WebAssembly per plugin e estensioni dei Charts
- Migliore Validazione: Validazione dello schema e applicazione delle politiche migliorata
Conclusione
Helm è diventato lo standard de facto per la gestione dei pacchetti Kubernetes, e padroneggiarlo è essenziale per le pratiche moderne di DevOps. Comprendendo la struttura del Chart, il templating, la gestione dei valori e le migliori pratiche, puoi creare deployment Kubernetes mantenibili, sicuri e scalabili.
Inizia con Charts semplici, incorpora gradualmente funzionalità avanzate come hook e dipendenze, e integra gli strumenti GitOps per infrastrutture a livello di produzione. La comunità Helm fornisce migliaia di Charts pre-costruiti, ma il vero potere deriva dalla creazione di Charts personalizzati adatti alle esigenze dell’organizzazione. Che tu stia distribuendo applicazioni stateless o carichi di lavoro stateful che richiedono storage persistente, Helm semplifica la complessità della gestione delle risorse Kubernetes. Per i team che stanno configurando nuovi cluster Kubernetes, considera l’installazione di Kubernetes con Kubespray o esplora distribuzioni Kubernetes come k3s o MicroK8s per ambienti di sviluppo. Se stai valutando quale distribuzione si adatta alle tue esigenze di homelab o cluster piccoli, vedi la nostra confronto completo delle distribuzioni Kubernetes per un’analisi dettagliata.
Link Utili
- Documentazione Ufficiale di Helm
- Artifact Hub - Scopri Charts Helm
- Repository GitHub di Helm
- Guida alle Best Practices di Helm
- Strumento di Test dei Charts
- Helmfile
- ArgoCD
- Flux CD
- Repository dei Charts Bitnami
- Kubernetes Cheatsheet
- Installare Kubernetes con Kubespray
- Confronto delle Distribuzioni Kubernetes per un Homelab a 3 Nodi
- Panoramica delle Distribuzioni Kubernetes - kubeadm, k3s, MicroK8s, Minikube, Talos Linux e RKE2
- Service Mesh con Istio e Linkerd
- StatefulSets e Storage Persistente in Kubernetes
- Pattern Saga in Transazioni Distribuite