Relai SMTP¶
Hors-prod — Mailcatcher¶
En environnement hors-prod, les applications utilisent Mailcatcher, un pod standalone déployé dans le namespace de l'application qui intercepte les e-mails sans les envoyer réellement.
Déploiement¶
La configuration se fait dans les Helm values de l'application. Une seule déclaration suffit par namespace, quel que soit le nombre de composants.
Compatible avec app-template-v2 et drupal-template.
standaloneMailcatcher:
enabled: true
image:
repository: rg.fr-par.scw.cloud/namespace-scw-service/mailcatcher
tag: latest
pullPolicy: Always
ingress:
enabled: true
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-scaleway-dns01"
traefik.ingress.kubernetes.io/router.middlewares: "int-APP_NAME-APP_NAME-ip-whitelist@kubernetescrd"
host: int-APP_NAME-mailcatcher.direct.horsprod.ademe-scw.fr
tls: int-APP_NAME-mailcatcher-direct-horsprod-ademe-scw-fr-tls
Variables d'environnement¶
Une fois Mailcatcher déployé, configurer les variables d'environnement de l'application (les noms exacts dépendent du framework) :
MAIL_HOST=APP_NAME-mailcatcher
MAIL_PORT=1025
À éviter — le mode sidecar¶
Ne pas utiliser mailcatcher.enabled: true
mailcatcher:
enabled: true # Ne pas faire
Nous avons fait le choix de toujours privilégier standaloneMailcatcher : un seul pod dédié par namespace.
L'option sidecar sera supprimée de l'app-template-v2 une fois toutes les applications migrées.
Prod — Maddy¶
Contexte¶
| Époque | Solution | Problème |
|---|---|---|
| Avant | Postfix par namespace → SMTP DRI | Un pod par namespace ; indisponible si le SMTP DRI est down |
| Tentative | Scaleway TEM en direct | Erreurs rencontrées |
| Aujourd'hui | Maddy — mutualisé, cluster prod uniquement | — |
Architecture¶
Application (cluster prod)
↓ SMTP port 25 (sans authentification)
smtp-maddy.prod-maddy-smtp.svc.cluster.local
↓ ↓
Deployment DRI (4 replicas) Deployment TEM (4 replicas)
smtp.ademe-dri.fr:25 smtp.tem.scaleway.com:587
Deux déploiements distincts sont exposés derrière le même service Kubernetes, ce qui répartit le trafic entre les deux relais selon le ratio de leurs replicas :
| Déploiement | Replicas | Relai cible | Ratio actuel |
|---|---|---|---|
maddy-dri |
4 | smtp.ademe-dri.fr:25 |
~50 % |
maddy-tem |
4 | smtp.tem.scaleway.com:587 |
~50 % |
Le trafic passe vers TEM par paliers, pour construire la réputation de l'IP d'envoi TEM Scaleway sans la dégrader. La cible est un envoi entièrement par TEM.
Sondes de disponibilité¶
Chaque déploiement est équipé de sondes liveness et readiness qui surveillent à la fois Maddy localement et le SMTP distant. Si le SMTP distant devient indisponible, les pods concernés sont automatiquement retirés du service — le trafic bascule entièrement sur l'autre déploiement.
custom_probes:
liveness:
exec:
command:
- /bin/sh
- -c
- 'echo QUIT | nc -w 5 localhost 25 | head -1 | grep -q "220"'
initialDelaySeconds: 15
periodSeconds: 30
failureThreshold: 5
successThreshold: 1
readiness:
exec:
command:
- /bin/sh
- -c
- 'echo QUIT | nc -w 5 smtp.ademe-dri.fr 25 | head -1 | grep -q "220"'
periodSeconds: 30
timeoutSeconds: 6
failureThreshold: 3
successThreshold: 2
- Liveness : vérifie que Maddy répond localement sur le port 25. En cas d'échec répété (5×), le pod est redémarré.
- Readiness : vérifie que le SMTP distant répond. En cas d'échec (3×), le pod est retiré du service sans être redémarré — il reprend le trafic automatiquement dès que le SMTP distant revient.
Résilience¶
- Chaque déploiement est réparti sur fr-par-1 et fr-par-2, avec un PDB
maxUnavailable: 1et la prioritéplatform-high. - À l'arrêt, Maddy coupe les sessions SMTP en cours. Le
preStop(sleep 15) laisse le pod sortir du service et terminer ses sessions avant de s'arrêter. - Après une baisse de
replicas, vérifier la répartition par zone : la suppression de pods l'ignore. Si une zone est chargée, y supprimer un pod, il est recréé dans l'autre.
Utilisation depuis une application¶
SMTP_HOST=smtp-maddy.prod-maddy-smtp.svc.cluster.local
SMTP_PORT=25
Aucune authentification requise — le cluster interne est considéré comme de confiance.
Configuration¶
| Paramètre | Description |
|---|---|
maddy.hostname |
Nom d'hôte SMTP déclaré par le serveur |
maddy.primary_domain |
Domaine principal déclaré dans le protocole SMTP |
maddy.secondary_domains |
Domaines supplémentaires (séparés par des espaces) |
maddy.tls_secret_name |
Secret Kubernetes contenant le certificat TLS |
smtp_target_tem |
Activer le relai Scaleway TEM |
smtp_target_dri |
Activer le relai ADEME DRI |
Secrets¶
Gérés via External Secrets + Vault, rafraîchis automatiquement toutes les 5 minutes.
| Secret Vault | Contenu | Usage |
|---|---|---|
ademe/cluster-service/maddy |
users |
Credentials utilisateurs Maddy |
ademe/service/tem_scaleway |
username_prod |
Login relai Scaleway TEM |
ademe/service/maddy |
scw_api_secret |
Mot de passe relai Scaleway TEM |
Avantages et limites¶
| Postfix (avant) | Maddy (maintenant) | |
|---|---|---|
| Résilience | Single point of failure par namespace | Multi-replica réparti sur fr-par-1 et fr-par-2, bascule automatique TEM / DRI |
| Mutualisation | Un pod par namespace | Un service partagé pour tout le cluster prod |
| Métriques par application | Stats Postfix par application | Non disponible — en cours |
Métriques en cours de construction
La migration vers Maddy a supprimé les stats d'envoi par application qu'offraient les métriques Postfix. Des dashboards basés sur les logs Maddy sont en cours de construction.
TODO¶
- Construire les dashboards de métriques à partir des logs Maddy
- Migrer toutes les applications du mode sidecar vers
standaloneMailcatcher - Supprimer l'option
mailcatcher.enabledde l'app-template-v2 après migration complète - Augmenter la part de TEM par paliers jusqu'à un envoi entièrement par TEM