PostgresCluster
Portée : namespaced · Backend : CloudNativePG (type: cnpg)
PostgreSQL partagé avec des bases de données par consommateur au sein d'un même cluster. Le moteur est interchangeable via type ; cnpg est implémenté, zalando et cockroachdb sont à l'état de scaffold.
Spec
| Champ | Type | Description |
|---|---|---|
type | enum cnpg (par défaut) | zalando | cockroachdb | Implémentation du backend |
mode | enum managed | adopt | external (requis) | Mode de Provenance |
managed | object | Paramètres lorsque mode: managed |
adopt | object | Référence à un Cluster CNPG existant |
external | object | Secret de connexion pour une base de données externe |
databases[] | list | Bases de données à garantir au sein du cluster (une par workload consommateur) |
managed
| Champ | Par défaut | Description |
|---|---|---|
instances | 3 | Nombre de réplicas HA CNPG |
storageSize | — | Taille du PVC par instance |
storageClass | valeur par défaut du cluster | StorageClass |
resources | — | Requests & limits CPU/mémoire |
backup | désactivé | Sauvegardes planifiées vers un stockage objet (voir backup) |
backup
Désactivé par défaut. Lorsqu'il est activé, l'opérateur configure les sauvegardes vers le stockage objet de CNPG (Barman intégré) et l'archivage continu des WAL — vous obtenez ainsi des sauvegardes complètes planifiées et une récupération à un instant précis (point-in-time recovery). Il émet le bloc Cluster.spec.backup ainsi qu'un ScheduledBackup. Les identifiants proviennent d'un Secret via SecretsManagement — jamais en ligne.
| Champ | Par défaut | Description |
|---|---|---|
enabled | false | Activer les sauvegardes planifiées + l'archivage des WAL |
provider | s3 | s3, azure, ou gcs |
s3 / azure / gcs | — | Bloc du fournisseur (celui correspondant à provider est requis) |
schedule | 0 0 2 * * * | cron à 6 champs avec secondes (format CNPG, pas à 5 champs) — par défaut quotidien à 02:00 |
retentionPolicy | 30d | Rétention par fenêtre de récupération, p. ex. 30d, 4w |
Blocs de fournisseur — chacun prend un destinationPath ainsi que des identifiants (ou une échappatoire par identité de charge de travail afin qu'aucune clé statique ne soit stockée) :
| Fournisseur | destinationPath | Clés du Secret d'identifiants | Identité de charge de travail |
|---|---|---|---|
s3 | s3://bucket/path (+ endpointURL optionnel pour MinIO/R2) | access-key-id, secret-access-key | inheritFromIAMRole: true |
azure | https://<acct>.blob.core.windows.net/<container>/ | connection-string | inheritFromAzureAD: true |
gcs | gs://bucket/path | credentials (JSON de compte de service) | gkeEnvironment: true |
Le destinationPath doit inclure un segment conteneur/bucket — un simple https://<acct>.blob.core.windows.net/ (Azure) ou s3:// sans bucket produit une cible de sauvegarde non inscriptible. Les jobs de sauvegarde ClickHouse et MongoDB rejettent un chemin sans conteneur via un événement d'avertissement BackupMisconfigured sur le datastore, au lieu d'émettre un CronJob dont les pods échouent.
adopt / external
| Champ | Description |
|---|---|
adopt.clusterRef | Un Cluster CNPG existant (postgresql.cnpg.io/v1) ; namespace est optionnel et peut désigner un autre namespace — voir l'adoption inter-namespaces |
external.connectionSecretRef | Secret contenant un DATABASE_URL |
databases[]
| Champ | Description |
|---|---|
name | Nom de la base de données |
owner | Rôle propriétaire (optionnel) |
credentialsSecretName | Secret que l'opérateur matérialise pour le consommateur |
Les workloads qui référencent ce cluster obtiennent leur base même lorsqu'elle n'est pas déclarée ici, avec la licence auto-wiring ; status.databases[].claimedBy indique qui utilise chacune. Un nom de base que Kubernetes ne peut pas utiliser dans des noms d'objets (par exemple langfuse_prod) reçoit un nom assaini pour sa Database CNPG et son Secret d'identifiants. Voir Bases de données pour les workloads qui référencent un datastore.
Comportement par mode
managed(type: cnpg) — garantit la présence de l'opérateurcloudnative-pg, crée unClusterCNPG, et crée unDatabaseCNPG (ainsi qu'un rôle et un Secret d'identifiants) par entrée dedatabases[].adopt— résout leClusterréférencé, garantit les bases de données qu'il contient, et ne touche jamais au cycle de vie du cluster. Si le cluster réside dans un autre namespace (adoption inter-namespaces), les ressources CNPGDatabasesont créées à côté de lui (CNPG résoutDatabase.spec.clusterdans le namespace de laDatabaseelle-même), tandis que le Secret d'identifiants destiné aux consommateurs reste matérialisé dans ce namespace. Supprimer cette ressource retire ces CRDatabase— jamais le cluster adopté.external— expose leDATABASE_URLfourni ; aucun opérateur n'est installé.zalando/cockroachdb— à l'état de scaffold ; la ressource rapporteReady=Falseavec la raisonBackendNotImplemented.
Exemple — managed, deux bases de données
apiVersion: core.navique.com/v1alpha1
kind: PostgresCluster
metadata:
name: forge-pg
namespace: forge-data
spec:
type: cnpg
mode: managed
managed:
instances: 3
storageSize: 20Gi
databases:
- { name: litellm, credentialsSecretName: litellm-db-credentials }
- { name: langfuse, credentialsSecretName: langfuse-db-credentials }Exemple — external (apportez votre propre Postgres managé)
spec:
type: cnpg
mode: external
external:
connectionSecretRef: { name: azure-postgres, key: DATABASE_URL }
databases:
- { name: litellm, credentialsSecretName: litellm-db-credentials }Exemple — managed avec sauvegardes S3 planifiées
spec:
type: cnpg
mode: managed
managed:
instances: 3
storageSize: 20Gi
backup:
enabled: true
provider: s3
schedule: "0 0 2 * * *" # quotidien à 02:00 (cron à 6 champs : sec min heure jour mois jour-semaine)
retentionPolicy: 30d
s3:
destinationPath: s3://forge-backups/pg
# endpointURL: https://minio.example.com:9000 # pour les stockages compatibles S3
credentialsSecretRef: { name: pg-backup } # clés : access-key-id, secret-access-key
databases:
- { name: litellm, credentialsSecretName: litellm-db-credentials }Restauration
Un Postgres managé est sauvegardé en continu par CNPG (base backups + archivage WAL) ; la restauration est donc une récupération point-in-time (PITR) dans un nouveau cluster qui s'amorce depuis le même stockage objet — CNPG ne restaure jamais en place. Créez un second Cluster avec une source bootstrap.recovery pointant vers le barmanObjectStore de la sauvegarde ; l'opérateur navique ne modélise pas la restauration en CRD, appliquez donc le Cluster CNPG directement :
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata: { name: forge-pg-restored, namespace: forge }
spec:
instances: 1
bootstrap:
recovery:
source: forge-pg
# recoveryTarget: { targetTime: "2026-06-27 14:00:00+00" } # omettre = dernier
externalClusters:
- name: forge-pg
barmanObjectStore:
destinationPath: s3://my-bucket/postgres
s3Credentials:
accessKeyId: { name: pg-backup, key: access-key-id }
secretAccessKey: { name: pg-backup, key: secret-access-key }Une fois forge-pg-restored healthy, redirigez les workloads (ou passez le PostgresCluster en mode: adopt le référençant). Référence complète : récupération CNPG. Le Lock auto-créé protège l'original d'une suppression accidentelle pendant la récupération — conservez-le jusqu'à confirmation des données restaurées.
Partage entre workloads
Un même PostgresCluster alimente typiquement à la fois le Gateway (base litellm) et Langfuse (base langfuse). Chaque consommateur référence le cluster et nomme sa base de données ; l'opérateur provisionne une base de données isolée et un Secret d'identifiants par consommateur.
Status
Expose les coordonnées de connexion et, pour chaque base de données, l'état de disponibilité ainsi que le nom du Secret d'identifiants, en plus des conditions et de l'observedGeneration standard.