La mise en place d'un système de surveillance robuste inclut souvent la capacité à être notifié en cas d'incident. Dans un environnement Kubernetes, Alertmanager, faisant partie de l'écosystème Prmoetheus, est l'outil privilégié pour gérer et router ces alertes. Ce guide détaille comment configurer Alertmanager pour envoyer des notifications par e-mail via un serveur SMTP.
1. Définition de la configuration SMTP et des récepteurs d'alertes
La première étape consiste à définir les paramètres de connexion à votre serveur SMTP et à spécifier les destinataires des alertes. Cette configuration est généralement stockée dans un Secret Kubernetes pour des raisons de sécurité. Nous allons créer ou modifier un fichier de configuration, par exemple alertmanager-config.yaml, qui contiendra ces informations.
Naviguez vers le répertoire de configuration de votre instance Alertmanager (adaptez le chemin si nécessaire, par exemple /etc/alertmanager ou un répertoire spécifique à votre installation du kube-prometheus-stack).
# alertmanager-config.yaml
global:
resolve_timeout: 5m
# Paramètres SMTP pour l'envoi des e-mails
smtp_smarthost: 'smtp.example.com:587' # Hôte et port de votre serveur SMTP
smtp_from: 'alertes@votre-domaine.com' # Adresse e-mail de l'expéditeur
smtp_auth_username: 'alertes@votre-domaine.com' # Nom d'utilisateur SMTP
smtp_auth_password: 'votre_mot_de_passe_smtp_ici' # Mot de passe SMTP
smtp_require_tls: true # Utiliser TLS pour la connexion SMTP
smtp_hello: 'votre-domaine.com' # Domaine utilisé dans la commande HELO/EHLO
templates:
- '/etc/alertmanager/config/alert-email-template.tmpl' # Chemin vers le modèle d'e-mail monté via ConfigMap
route:
group_by: ['alertname', 'severity', 'namespace'] # Regrouper les alertes par nom, sévérité et namespace
group_wait: 45s # Attendre 45 secondes avant d'envoyer la première notification pour un groupe
group_interval: 10m # Attendre 10 minutes entre les envois de notifications pour un groupe
repeat_interval: 2h # Répéter les notifications toutes les 2 heures si l'alerte persiste
receiver: 'notification-par-email' # Nom du récepteur d'alerte défini ci-dessous
receivers:
- name: 'notification-par-email' # Le nom du récepteur doit correspondre à celui de la route
email_configs:
- to: 'destinataire@autre-domaine.com' # Adresse e-mail du destinataire principal des alertes
send_resolved: true # Envoyer une notification lorsque l'alerte est résolue
html: '{{ template "email.layout" . }}' # Utiliser le modèle HTML défini pour le corps de l'e-mail
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'instance', 'namespace'] # Ne pas envoyer d'alertes 'warning' si une alerte 'critical' est déjà active pour la même ressource
Après avoir créé ou modifié ce fichier, il est nécessaire de l'appliquer à votre cluster Kubernetes en tant que Secret. Si un Secret Alertmanager existe déjà, il doit être supprimé et recréé pour que les modifications soient prises en compte. Nous utiliserons ici alertmanager-config comme nom de Secret.
# Supprimer l'ancien Secret (si existant)
kubectl delete secret alertmanager-config --namespace monitoring
# Créer un nouveau Secret à partir du fichier de configuration
kubectl create secret generic alertmanager-config --from-file=alertmanager-config.yaml --namespace monitoring
Ce Secret sera ensuite monté par le pod Alertmanager, généralement dans /etc/alertmanager/config.
2. Création du modèle d'e-mail personnalisé
Pour des notifications lisibles et informatives, il est conseillé de créer un modèle HTML pour les e-mails. Ce modèle sera utilisé par Alertmanager pour formater le contenu des alertes. Créez un fichier nommé alert-email-template.tmpl (ou un nom similaire) :
# alert-email-template.tmpl
{{ define "email.subject" }}Alertmanager - [{{ .Status | toUpper }}] {{ .CommonLabels.alertname }}{{ end }}
{{ define "email.layout" }}
<meta charset="UTF-8"></meta>
<title>{{ template "email.subject" . }}</title>
<style>
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
.alert-container { border: 1px solid #ddd; padding: 15px; margin-bottom: 20px; border-radius: 5px; }
.firing { border-left: 5px solid #dc3545; } /* Rouge pour les alertes actives */
.resolved { border-left: 5px solid #28a745; } /* Vert pour les alertes résolues */
h2 { color: #0056b3; }
ul { list-style: none; padding: 0; }
li { margin-bottom: 10px; }
strong { color: #000; }
.footer { font-size: 0.9em; color: #777; margin-top: 20px; border-top: 1px solid #eee; padding-top: 10px; }
</style>
{{- if gt (len .Alerts.Firing) 0 }}
<h2>🚨 Nouvelles alertes déclenchées ({{ len .Alerts.Firing }})</h2>
{{- range .Alerts.Firing }}
<div class="alert-container firing">
<ul>
<li><strong>Alerte :</strong> {{ .Labels.alertname }}</li>
<li><strong>Sévérité :</strong> {{ .Labels.severity | toUpper }}</li>
<li><strong>Instance :</strong> {{ .Labels.instance }}</li>
<li><strong>Service :</strong> {{ .Labels.job }}</li>
<li><strong>Résumé :</strong> {{ .Annotations.summary }}</li>
<li><strong>Détails :</strong> {{ .Annotations.description }}</li>
<li><strong>Début :</strong> {{ .StartsAt.Format "02 Jan 2006 15:04:05 MST" }}</li>
{{- if .GeneratorURL }}<li><strong>Lien :</strong> <a href="{{ .GeneratorURL }}">{{ .GeneratorURL }}</a></li>{{ end }}
</ul>
</div>
{{- end }}
{{- end }}
{{- if gt (len .Alerts.Resolved) 0 }}
<h2>✅ Alertes résolues ({{ len .Alerts.Resolved }})</h2>
{{- range .Alerts.Resolved }}
<div class="alert-container resolved">
<ul>
<li><strong>Alerte :</strong> {{ .Labels.alertname }}</li>
<li><strong>Instance :</strong> {{ .Labels.instance }}</li>
<li><strong>Service :</strong> {{ .Labels.job }}</li>
<li><strong>Résumé :</strong> {{ .Annotations.summary }}</li>
<li><strong>Détails :</strong> {{ .Annotations.description }}</li>
<li><strong>Début :</strong> {{ .StartsAt.Format "02 Jan 2006 15:04:05 MST" }}</li>
<li><strong>Fin :</strong> {{ .EndsAt.Format "02 Jan 2006 15:04:05 MST" }}</li>
{{- if .GeneratorURL }}<li><strong>Lien :</strong> <a href="{{ .GeneratorURL }}">{{ .GeneratorURL }}</a></li>{{ end }}
</ul>
</div>
{{- end }}
{{- end }}
<div class="footer">
<p>Ceci est un message généré automatiquement par Alertmanager.</p>
</div>
{{ end }}
Ce modèle doit être mis à disposition d'Alertmanager via un ConfigMap. Créez un fichier YAML pour ce ConfigMap :
kubectl create configmap alertmanager-email-templates --from-file=alert-email-template.tmpl --dry-run=client -o yaml --namespace monitoring > alertmanager-templates-configmap.yaml
Puis, appliquez le ConfigMap au cluster :
kubectl apply -f alertmanager-templates-configmap.yaml
3. Association du modèle à l'instance Alertmanager
Enfin, pour qu'Alertmanager utilise le modèle d'e-mail fraîchement créé, la définition de la ressource Alertmanager (CRD) doit être mise à jour pour référencer le ConfigMap. Modifiez le fichier YAML de votre instance Alertmanager (par exemple, alertmanager-instance.yaml qui gère le déploiement d'Alertmanager, souvent dans le contexte de kube-prometheus-stack) :
# alertmanager-instance.yaml (extrait)
apiVersion: monitoring.coreos.com/v1
kind: Alertmanager
metadata:
name: main
namespace: monitoring
spec:
replicas: 1
# ... autres spécifications de votre Alertmanager ...
configMaps:
- alertmanager-email-templates # Référence au ConfigMap contenant le modèle
# ... suite des spécifications ...
Appliquez cette modification à votre cluster Kubernetes :
kubectl apply -f alertmanager-instance.yaml
Alertmanager devrait maintenant recharger sa configuration et commencer à utiliser le modèle d'e-mail personnalisé pour les notifications.