In questi giorni ho fatto una scoperta che mi ha deliziato. Gli hook dei chart di Helm
Fatalità con uno dei casi tipici indicati direttamente nella documentazione. La necessità di inizializzare un database prima di eseguire il deployment vero e proprio dell’applicazione (verificare se il db esiste, a che versione è, aggiornare lo schema ecc…).
Gli hook disponibili
Gli hook disponibili sono diversi (dalla doc ufficiale)
| Annotation Value | Description |
|---|---|
| pre-install | Executes after templates are rendered, but before any resources are created in Kubernetes |
| post-install | Executes after all resources are loaded into Kubernetes |
| pre-delete | Executes on a deletion request before any resources are deleted from Kubernetes |
| post-delete | Executes on a deletion request after all of the release’s resources have been deleted |
| pre-upgrade | Executes on an upgrade request after templates are rendered, but before any resources are updated |
| post-upgrade | Executes on an upgrade request after all resources have been upgraded |
| pre-rollback | Executes on a rollback request after templates are rendered, but before any resources are rolled back |
| post-rollback | Executes on a rollback request after all resources have been modified |
| test | Executes when the Helm test subcommand is invoked (view test docs) |
Il mio caso del database
Il chart di helm viene usato sia in installazione che update quindi ho usato gli hooks pre-install e pre-upgrade per fare il check del database e l’eventuale aggiornamento dello schema.
Ecco l’esempio
Il core del mio hook è un job che viene eseguito prima dell’installazione o dell’aggiornamento del chart. Ecco un esempio di come appare il job:
apiVersion: batch/v1
kind: Job
metadata:
name: ...
labels:
...
app.kubernetes.io/component: db-init
annotations:
"helm.sh/hook": pre-install,pre-upgrade
"helm.sh/hook-weight": "1"
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
spec: ...
Maaa…. Altro problema! Siccome il job fa uso di un secret per scaricare l’immagine da un container registry privato, ho dovuto aggiungere anche un imagePullSecrets al job e di conseguenza installarlo nel cluster con un hook pre-install e pre-upgrade con weight 0 (così da essere eseguito prima del job vero e proprio).
apiVersion: v1
kind: Secret
metadata:
name: {{ $secretName }}
namespace: {{ .Release.Namespace }}
labels:
...
annotations:
"helm.sh/hook": pre-install,pre-upgrade
"helm.sh/hook-weight": "0"
Conclusioni
Semplici e pratici gli hook di helm mi hanno permesso quindi di “preparare” in anticipo il terreno (in questo caso il database) prima di eseguire il deployment vero e proprio dell’applicazione che, in un deployment tradizionale, avrebbe fallito miseramente perché un Job senza hook non avrebbe potuto essere seguito in modo garantito prima del resto e quindi… patatrac!