Logo
Overview
Un Talos européen de qualité - Part VI - Base de données et sauvegardes

Un Talos européen de qualité - Part VI - Base de données et sauvegardes

October 31, 2025
15 min read
part-06

Objectif 🎯

À la fin de la section précédente, nous en avions terminé avec l’ingress. Il s’agirait maintenant d’avoir un vrai service de base de données pour nos applications ainsi des backups chiffrés avec une bonne stratégie. Pour tout cela, nous allons nous appuyer sur les opérateurs déjà installés à la section 4.

Backups

Il y a plusieurs éléments à prendre en compte :

  • Backup de l’etcd, cerveau du cluster.
  • Backup des volumes persistants critiques, en mode block et/ou en mode fichiers.
  • Backup des bases de données en temps réel.

Etcd

Il peut être utile de faire des sauvegardes régulières de notre etcd en cas de situation extrême de devoir restaurer rapidement un cluster défectueux, notamment si un seul nœud control plane unique est envisagé.

Et ça tombe bien, Talos propose un outil taillé pour cela.

Important

La backup de l’etcd ne servira en aucun cas à la création d’un nouveau cluster :

  1. La construction en mode GitOps rend ce processus inutile et inefficient.
  2. Les nouvelles machines peuvent avoir des caractéristiques différentes.
  3. Permet de renouveler tous les certificats.
  4. Les secrets étant chiffrés à la volée par défaut via Talos, une restauration ne pourrait pas fonctionner, puisque la clé de déchiffrement lié à la nouvelle instance Talos serait nécessairement différente.
clusters/dev-kube/module-database.tf
module "kube_database" {
source = "../../modules/kube/database"
talos_backup_cluster_name = local.cluster_name
talos_backup_public_key = var.talos_etcd_backup_age
talos_backup_s3_endpoint = "https://${local.s3_endpoint}"
talos_backup_s3_region = local.s3_region
talos_backup_s3_bucket = local.cluster_name
talos_backup_s3_access_key = var.talos_etcd_backup_s3_username
talos_backup_s3_secret_key = var.talos_etcd_backup_s3_password
}
Explanation

Ce qui compte ici sont les accès s3, assez classiques, ainsi que la clé publique age qui servira à chiffrer les backups de l’etcd avant leur envoi vers le stockage distant.

Longhorn

La backup côté stockage persistant est assurée par Longhorn, uniquement en mode block. Il suffit de créer des objets RecurringJob pour définir la fréquence et la rétention des backups.

resource "kubernetes_manifest" "longhorn_jobs" {
for_each = {
daily = {
cron = "0 0 * * *"
retain = 7
},
weekly = {
cron = "0 3 * * 1"
retain = 4
}
monthly = {
cron = "0 6 1 * *"
retain = 3
}
}
manifest = {
apiVersion = "longhorn.io/v1beta2"
kind = "RecurringJob"
metadata = {
name = each.key
namespace = "longhorn-system"
}
spec = {
concurrency = 1
cron = each.value.cron
groups = ["backup"]
name = each.key
retain = each.value.retain
task = "backup"
}
}
}

La stratégie classique de backup décrite ci-dessus est la suivante :

  • Backup quotidien, conservé 7 jours.
  • Backup hebdomadaire, conservé 4 semaines.
  • Backup mensuel, conservé 3 mois.

Très facile à adapter selon vos besoins. De plus, du fait de la nature même de la sauvegarde en mode block, son chiffrement est déjà assuré sur les volumes chiffrés.

Après application, vous devriez les retrouver dans l’interface web de Longhorn :

Longhorn Backup

Par défaut, seuls les volumes placés dans le groupe backup seront concernés par les jobs de backup. Ce n’est pas le cas par défaut, il faudra donc les définir explicitement dans l’onglet Volumes. Je préfère explicitement choisir quels volumes doivent être sauvegardés ou non mais libre à vous de changer votre stratégie.

Base de données

Qu’est-ce qu’un kube sans cluster de base de données ? Pour garder la maîtrise des coûts et de toute la chaîne de l’infra, nous préférerions éviter les services managés. Bien que ces derniers facilitent réellement la vie des développeurs qui n’ont pas envie de se prendre la tête avec la gestion des bases et toute ce qui va avec (réplication, backups, etc.), l’arrivée de puissants opérateurs tels que CloudNativePG facilitent grandement la mise en œuvre et gestion du cycle de vie de clusters PostgreSQL.

Dragonfly

On commence par un truc simple, Dragonfly, une base de données en mémoire performante et compatible avec le protocole Redis.

clusters/dev-kube/module-database.tf
module "kube_database" {
// ...
dragonfly_password = var.dragonfly_password
}

CloudNativePG

On s’attaque au plus gros sujet. De la même manière que pour Dragonfly, nous allons installer un cluster PostgreSQL mais construit via l’opérateur CloudNativePG. Le même principe s’applique sur les volumes Longhorn en mode local strict, pour maximiser les perfs IO.

On gérera dans le même temps les backups de la base de données via le plugin barman-cloud qui permettra de faire des backups sur notre S3.

Le schéma qui résume la stack CloudNativePG cible :

Schéma CloudNativePG

Barman operator, en plus de la politique de rétention, est donc en charge de fournir à l’opérateur principal les spécifications nécessaires à la génération du sidecar barman lors de la création d’une instance PostgreSQL.

Important

Il est essentiel d’avoir 2 modes de backups :

  • Backup de base quotidienne, voire hebdomadaire, via le plugin barman-cloud (mode fichier).
  • Backup incrémental en quasi-temps réel, via le plugin barman-cloud uniquement, par sauvegarde des fichiers WAL (Write-Ahead Logging), éléments essentiels sur lequel s’appuie le mode Point in Time recovery (PITR). Le principe est de sauvegarder en continu les fichiers WAL, qui permettent de rejouer toutes les transactions effectuées sur la base de données depuis le dernier backup full.
clusters/dev-kube/module-database.tf
module "kube_database" {
// ...
cnpg_cluster_name = local.cluster_name
cnpg_pg_version = "18.1-standard-trixie"
cnpg_backup_s3_endpoint = "https://${local.s3_endpoint}"
cnpg_backup_s3_access_key = var.cnpg_backup_s3_username
cnpg_backup_s3_secret_key = var.cnpg_backup_s3_password
cnpg_backup_s3_bucket = local.cluster_name
}
Explanation

Le choix de la version est importante, choisissez le bon tag ici selon vos besoins. Ici nous prenons la dernière version stable au moment de l’écriture de ce guide, la 18, sous debian 13. Ne pas prendre les versions dépréciées system qui ne sont pas compatibles avec les plugins de backup.

Il faudra indiquer les accès S3 pour les backups, qui seront gérés par l’opérateur le plugin CNPG-I barman-cloud.

Après l’habituel terraform apply, vérifier le status des pods postgres via kgp -n postgres -o wide. A un plus haut niveau, vérifier le status du cluster via k cnpg status ohmytalos-dev -n postgres pour avoir quelque chose ressemblant à ceci :

Cluster Summary
Name postgres/ohmytalos-dev
System ID: 7554694612884451350
PostgreSQL Image: ghcr.io/cloudnative-pg/postgresql:18-standard-trixie
Primary instance: ohmytalos-dev-1
Primary start time: 2025-09-27 10:10:48 +0000 UTC (uptime 150h53m23s)
Status: Cluster in healthy state
Instances: 2
Ready instances: 2
Size: 1.1G
Current Write LSN: E2/72001CB8 (Timeline: 2 - WAL File: 00000002000000E200000072)
Continuous Backup status
First Point of Recoverability: 2025-09-27T10:13:34Z
Working WAL archiving: OK
WALs waiting to be archived: 0
Last Archived WAL: 00000002000000E200000071 @ 2025-10-03T17:03:05.124893Z
Last Failed WAL: 00000002.history @ 2025-09-27T10:10:17.393725Z
Streaming Replication status
Replication Slots Enabled
Name Sent LSN Write LSN Flush LSN Replay LSN Write Lag Flush Lag Replay Lag State Sync State Sync Priority Replication Slot
---- -------- --------- --------- ---------- --------- --------- ---------- ----- ---------- ------------- ----------------
ohmytalos-dev-2 E2/72001CB8 E2/72001CB8 E2/72001CB8 E2/72001CB8 00:00:00 00:00:00 00:00:00 streaming async 0 active
Instances status
Name Current LSN Replication role Status QoS Manager Version Node
---- ----------- ---------------- ------ --- --------------- ----
ohmytalos-dev-1 E2/72001CB8 Primary OK Burstable 1.27.0 ohmytalos-dev-storage-wty
ohmytalos-dev-2 E2/72001CB8 Standby (async) OK Burstable 1.27.0 ohmytalos-dev-storage-vsh
Plugins status
Name Version Status Reported Operator Capabilities
---- ------- ------ ------------------------------
barman-cloud.cloudnative-pg.io 0.7.0 N/A Reconciler Hooks, Lifecycle Service

Côté backup, le mode immediate étant activé, vous devriez déjà voir une backup complète apparaître sur votre s3, ainsi que les 1ers WALs.

pgAdmin

Pour bien faire il nous faudrait un petit pgadmin pour gérer nos bases de données PostgreSQL. Rien de plus simple avec ce chart.

clusters/dev-kube/module-database.tf
module "kube_database" {
// ...
internal_domain = local.internal_domain
pgadmin_email = "admin@ohmytalos.io"
}

Voilà simple et basique, après terraform apply, go sur https://pga.dev.ohmytalos.io et rentrer les identifiants admin@ohmytalos.io + SuperSecret, puis changer ce mot de passe par défaut (il sera stocké dans la base sqlite persisté dans le volume).

Il vous reste plus qu’à ajouter vos serveurs PostgreSQL. CloudNativePG propose 3 services d’accès, pour reprendre le nom donnée à notre cluster, nous avons :

  • ohmytalos-dev-rw.postgres : La base primary active, avec accès en écriture. L’opérateur s’occupe de la bascule automatique en cas de défaillance détectée en promouvant un des replicas disponibles.
  • ohmytalos-dev-ro.postgres : Le(s) base(s) standby, avec accès en lecture seule, dont les données sont répliquées depuis le primary. Les backups s’effectuent uniquement via ces bases pour ne pas surcharger la primary.
  • ohmytalos-dev-r.postgres : Tous les serveurs PostgreSQL sans distinction. Très utile dans notre cas (2 serveurs uniquement) pour les applications voulant distribuer la lecture sur toutes les bases.

Créer un accès pour la primary et un autre pour les replicas, comme suit :

pgAdmin New Server

Vous pouvez récupérer le mot de passe généré aléatoirement lors de la création du cluster via la commande kgsec -n postgres -o yaml okami-dev-superuser | yq -r .data.password | base64 -d.

pgAdmin Dashboard

Libre à vous de déclencher des backups logiques, via l’interface pgAdmin, en plus des backups automatiques déjà mis en place. Elles seront stockées dans le volume persistant de pgAdmin, d’une taille à 10 Gio par défaut.

Conclusion

Et voilà qu’on est bien. Il nous manque un dernier gros maillon critique pour un cluster de pro, la stack d’observabilité. C’est ce que nous verrons dans la section suivante.