Project Oxygen & Ideo-LabIDEO LAB Dashboard 2026

Interactions Kubernetes et PostgreSQL — Guide DBA / SRE

Objectif du guide

Comprendre prĂ©cisĂ©ment comment Kubernetes et PostgreSQL interagissent : pod, PVC, service, DNS, opĂ©rateur, rĂ©plication, failover, sauvegarde, restauration, sĂ©curitĂ©, observabilitĂ© et procĂ©dures d’exploitation. Ce guide est orientĂ© entretien DBA, exploitation rĂ©elle et architecture de plateforme.

PostgreSQL
Moteur transactionnel, WAL, réplication, slots, rÎles, backup physique et logique.
Kubernetes
Orchestration, pods, services, StatefulSet, PVC, scheduling, RBAC, secrets.
Opérateur
Automatisation du cycle de vie : création, failover, backup, restore, upgrade.
GitOps
DĂ©claration de l’état cible dans Git, rĂ©conciliation via ArgoCD ou Flux.

Le point clé

Kubernetes ne transforme pas PostgreSQL en base stateless. PostgreSQL reste un moteur stateful avec des fichiers de donnĂ©es, des journaux WAL, des contraintes d’intĂ©gritĂ©, des transactions et une logique de rĂ©plication propre. Kubernetes apporte l’orchestration, le placement, le redĂ©marrage, l’abstraction rĂ©seau, le stockage persistant et les primitives de sĂ©curitĂ©. L’opĂ©rateur PostgreSQL fait le pont entre les deux mondes.

Erreur classique : croire qu’un simple Deployment PostgreSQL + un PVC suffit pour faire de la haute disponibilitĂ©. En production, il faut gĂ©rer le rĂŽle primary/standby, la rĂ©plication, les WAL, le failover, les services applicatifs, les backups et les tests de restauration.

Carte mentale des interactions

CoucheKubernetes apportePostgreSQL exigeRisque si mal compris
ExĂ©cutionPod, container, probes, restart policy, scheduling.DĂ©marrage contrĂŽlĂ©, arrĂȘt propre, cohĂ©rence fichiers.Crash loop, recovery permanent, corruption logique ou indisponibilitĂ©.
IdentitéStatefulSet, ordinal, DNS stable.Instance primary ou standby identifiable.Replica qui redémarre avec un mauvais rÎle ou service mal routé.
StockagePV, PVC, StorageClass, CSI, snapshots.Latence faible, fsync fiable, volume persistant, IOPS prévisibles.Perte de données, lenteur massive, PVC bloqué, snapshot incohérent.
RéseauService, DNS, NetworkPolicy, endpoints.Port 5432, réplication, client routing, split lecture/écriture.Applications qui écrivent sur un standby, failover non transparent.
Cycle de vieRolling update, reconciliation, CRD, operator.Upgrade maßtrisé, sauvegarde avant changement, compatibilité extension.Upgrade moteur raté, downtime, incompatibilité de données.
Vue simple : du manifest Ă  la base disponible
GitManifest Cluster PostgreSQL
→
GitOpsArgoCD / Flux applique l’état cible
→
OperatorCrée pods, PVC, services, secrets
→
PostgreSQLPrimary, standbys, WAL, replication
→
ApplicationsConnexion via services rw / ro

Résultat attendu pour un DBA

  • Savoir expliquer pourquoi PostgreSQL doit ĂȘtre traitĂ© comme un workload stateful.
  • Savoir choisir entre PostgreSQL hors Kubernetes, PostgreSQL dans Kubernetes via StatefulSet manuel, et PostgreSQL via opĂ©rateur.
  • Savoir lire les objets Kubernetes liĂ©s Ă  PostgreSQL : pods, PVC, services, secrets, events, logs.
  • Savoir diagnostiquer les problĂšmes de failover, rĂ©plication, storage, DNS, permissions et backups.
  • Savoir dĂ©fendre une architecture de production : backup testĂ©, restore testĂ©, services sĂ©parĂ©s, storage chiffrĂ©, sĂ©curitĂ© rĂ©seau, observabilitĂ©.

Architecture d’ensemble : Kubernetes autour de PostgreSQL

Une architecture PostgreSQL Kubernetes sĂ©rieuse est composĂ©e de plusieurs couches. Le DBA doit savoir oĂč commence Kubernetes, oĂč commence PostgreSQL, et oĂč l’opĂ©rateur intervient.

Diagramme en couches
ApplicationsServices métiers, API, batchs, workers, outils BI connectés aux services PostgreSQL.
Services KubernetesEntrées réseau stables : service read/write vers primary, service read-only vers replicas.
Pods PostgreSQLUn pod par instance PostgreSQL, avec rÎle primary ou standby et volume dédié.
OperatorRéconciliation, bootstrap, failover, réplication, backup, restore, maintenance.
Storage KubernetesPV/PVC, StorageClass, CSI driver, snapshots, expansion, chiffrement.
InfrastructureNodes, zones, réseau, disques cloud/on-prem, IAM, sécurité, object storage.

Trois modÚles de déploiement

ModĂšleDescriptionAvantagesLimites
External DBPostgreSQL est hors Kubernetes : VM, bare metal, RDS, Cloud SQL, Azure Database.SimplicitĂ© pour les applications Kubernetes, maturitĂ© DBA classique.Moins cloud-native, deux mondes d’exploitation sĂ©parĂ©s.
StatefulSet manuelPostgreSQL est dĂ©ployĂ© avec StatefulSet, PVC, scripts et configuration maison.ContrĂŽle total, bon pour apprendre.Failover, backup, upgrade et promotion Ă  gĂ©rer soi-mĂȘme.
OperatorPostgreSQL est dĂ©crit par une CRD ; l’opĂ©rateur orchestre le cycle de vie.Production-friendly, automatisation, services, backup, failover.DĂ©pendance Ă  l’opĂ©rateur, nĂ©cessitĂ© de comprendre la CRD et ses limites.

Exemple de choix d’architecture

ContexteChoix recommandéJustification
Application critique, équipe DBA classique forte, cloud managé disponible.PostgreSQL managé hors cluster.Réduction du risque opérationnel Kubernetes/stateful.
Plateforme interne, besoin GitOps, multi-environnements, maßtrise Kubernetes.CloudNativePG ou opérateur équivalent.Cycle de vie déclaratif, intégration Kubernetes, automatisation.
Formation, POC, expérimentation technique.StatefulSet manuel ou CNPG minimal.Permet de comprendre les objets Kubernetes et le comportement PostgreSQL.
TrĂšs forte volumĂ©trie, latence extrĂȘme, contraintes disques spĂ©cifiques.À arbitrer : bare metal, cloud DB ou operator avec storage haut de gamme.Le stockage est souvent le facteur limitant.
Pattern de production : pour une base critique dans Kubernetes, privilégier une architecture opérateur, trois instances, anti-affinity, storage dédié, services read/write et read-only, backup continu WAL vers object storage, tests de restauration et supervision complÚte.

Cycle de vie : ce que Kubernetes peut faire, ce que PostgreSQL doit faire

Kubernetes sait crĂ©er, dĂ©placer, redĂ©marrer et exposer des pods. PostgreSQL sait maintenir la cohĂ©rence transactionnelle, Ă©crire ses WAL, faire du crash recovery, streamer vers des replicas, archiver ses journaux et restaurer un Ă©tat cohĂ©rent. L’opĂ©rateur coordonne ces deux logiques.

Cycle de vie d’un cluster PostgreSQL managĂ© par opĂ©rateur

1. DĂ©claration Un manifest dĂ©crit le cluster : nombre d’instances, version PostgreSQL, stockage, ressources, sauvegarde et paramĂštres.
2. Bootstrap L’opĂ©rateur initialise le primary avec initdb, un backup existant ou une rĂ©cupĂ©ration PITR.
3. Création des replicas Les standbys sont provisionnés, connectés au primary, et commencent à recevoir les WAL.
4. Exposition réseau Des services Kubernetes exposent le rÎle read/write et le rÎle read-only aux applications.
5. Exploitation Backups, métriques, logs, probes, secrets, certificats et quotas sont suivis dans Kubernetes.
6. Incident Si le primary tombe, l’opĂ©rateur dĂ©tecte l’état, promeut un standby et ajuste les services.
7. Maintenance Upgrade mineur, changement de paramÚtres, extension de PVC ou rotation de secrets sont opérés progressivement.
8. Restore Un nouveau cluster peut ĂȘtre reconstruit depuis un backup physique et des WAL archivĂ©s.

Responsabilités comparées

ActionKubernetesPostgreSQLOperator
Redémarrer un podOuiCrash recovery au redémarrageSurveille et ordonne si nécessaire
Savoir qui est primaryNon nativementOui via rÎle interneMaintient les labels/services cohérents
Faire un failover PostgreSQLNon seulPromotion possibleAutomatise la promotion et le routage
Créer un PVCOuiConsomme le filesystemDéclare les volumes nécessaires
Archiver les WALNonProduit les WALConfigure le mécanisme de backup/archive
Restaurer à un instant précisNonRecovery via backup + WALOrchestre bootstrap recovery
Point d’entretien : Kubernetes ne comprend pas les transactions PostgreSQL. Il sait voir un pod vivant ou mort. Le rĂŽle primary/standby, la rĂ©plication, les WAL et le point de recovery appartiennent au monde PostgreSQL.

StatefulSet, pods et identité PostgreSQL

PostgreSQL a besoin d’une identitĂ© stable et d’un stockage stable. C’est pour cette raison que les bases dans Kubernetes s’appuient sur des StatefulSets ou sur des objets créés par un opĂ©rateur qui produisent un comportement Ă©quivalent.

Pourquoi pas un Deployment simple ?

Besoin PostgreSQLDeploymentStatefulSet / Operator
Nom stable par instanceNon garantiOui, ordinal stable ou identité opérateur
Volume stable par instancePossible mais moins naturelOui, PVC attachĂ© Ă  l’instance
Ordre de création et suppressionNon orienté statefulOui
RĂ©plication primary/standbyÀ coder soi-mĂȘmeOrchestration plus adaptĂ©e
Failover DBNonOui avec opérateur

Exemple pédagogique de StatefulSet PostgreSQL minimal

postgres-statefulset-lab.yaml
apiVersion: apps/v1
                kind: StatefulSet
                metadata:
                name: postgres-lab
                namespace: db-lab
                spec:
                serviceName: postgres-lab-headless
                replicas: 1
                selector:
                matchLabels:
                app: postgres-lab
                template:
                metadata:
                labels:
                app: postgres-lab
                spec:
                containers:
                - name: postgres
                image: postgres:16
                ports:
                - containerPort: 5432
                name: postgres
                env:
                - name: POSTGRES_DB
                value: appdb
                - name: POSTGRES_USER
                valueFrom:
                secretKeyRef:
                name: postgres-lab-secret
                key: username
                - name: POSTGRES_PASSWORD
                valueFrom:
                secretKeyRef:
                name: postgres-lab-secret
                key: password
                volumeMounts:
                - name: pgdata
                mountPath: /var/lib/postgresql/data
                volumeClaimTemplates:
                - metadata:
                name: pgdata
                spec:
                accessModes: ["ReadWriteOnce"]
                storageClassName: db-fast-ssd
                resources:
                requests:
                storage: 20Gi
Attention : cet exemple est volontairement pédagogique. Il ne fournit pas de HA PostgreSQL, pas de réplication, pas de backup, pas de failover et pas de gestion de version. Pour la production, utiliser un opérateur comme CloudNativePG ou une architecture contrÎlée équivalente.

Commandes de diagnostic utiles

stateful-diagnostics.sh
kubectl -n db-lab get statefulset
                kubectl -n db-lab get pods -o wide
                kubectl -n db-lab get pvc
                kubectl -n db-lab describe pod postgres-lab-0
                kubectl -n db-lab logs postgres-lab-0
                kubectl -n db-lab exec -it postgres-lab-0 -- psql -U appuser -d appdb

Ce qu’un DBA doit regarder dans un pod PostgreSQL

  • Le pod est-il en Running, Pending, CrashLoopBackOff ou Terminating ?
  • Le PVC est-il bien attachĂ© au pod attendu ?
  • Le pod a-t-il changĂ© de node rĂ©cemment ?
  • Le conteneur PostgreSQL a-t-il redĂ©marrĂ© ? Combien de fois ?
  • Les logs montrent-ils un crash recovery, une promotion, un refus de rĂ©plication ou une erreur disque ?

Stockage Kubernetes et exigences PostgreSQL

Le stockage est le sujet le plus critique. Kubernetes peut provisionner un volume, mais il ne garantit pas automatiquement que ce volume est adaptĂ© Ă  PostgreSQL. Il faut comprendre les IOPS, la latence, le fsync, la politique de conservation, l’expansion, les snapshots et les zones.

Objets de stockage

ObjetRĂŽleImpact PostgreSQL
StorageClassDécrit le type de volume provisionné par le CSI.Détermine performance, chiffrement, expansion, zone, politique de suppression.
PersistentVolumeClaimDemande de stockage consommée par un pod.Chaque instance PostgreSQL doit avoir son volume stable.
PersistentVolumeVolume rĂ©el fourni par l’infrastructure.Contient PGDATA, donc les donnĂ©es critiques.
VolumeSnapshotCopie ponctuelle d’un volume via CSI.Utile mais doit ĂȘtre coordonnĂ© avec PostgreSQL pour cohĂ©rence applicative.
reclaimPolicyComportement aprÚs suppression du PVC/PV.Retain est souvent préférable pour éviter perte accidentelle.

StorageClass recommandée pour PostgreSQL

storageclass-postgres.yaml
apiVersion: storage.k8s.io/v1
                kind: StorageClass
                metadata:
                name: db-fast-ssd
                provisioner: ebs.csi.aws.com
                parameters:
                type: gp3
                encrypted: "true"
                reclaimPolicy: Retain
                allowVolumeExpansion: true
                volumeBindingMode: WaitForFirstConsumer

Pourquoi WaitForFirstConsumer ?

Cette option Ă©vite de crĂ©er un volume dans une mauvaise zone avant que le pod soit planifiĂ©. Pour PostgreSQL multi-zone, cela aide Ă  aligner volume, pod et node. Sans cela, on peut avoir un PVC créé dans une zone oĂč le pod ne peut pas tourner.

Check-list stockage PostgreSQL

ContrĂŽleCommandeLecture
PVC liĂ©skubectl -n db get pvcTous les PVC doivent ĂȘtre Bound.
PV conservéskubectl get pvVérifier Retain pour bases critiques.
Events storagekubectl -n db describe pvc <name>Repérer erreurs CSI, quota ou zone.
Espace disque PostgreSQLdf -h dans le podNe jamais attendre 100% avant action.
WAL volumétrieSELECT * FROM pg_replication_slots;Un slot bloqué peut retenir trop de WAL.
PiĂšge : un snapshot de volume n’est pas automatiquement Ă©quivalent Ă  un backup PostgreSQL restaurable. Pour du PRA sĂ©rieux, il faut privilĂ©gier backup physique PostgreSQL + archivage WAL + test de restauration.

Réseau : services, DNS, routage primary/replica

Le rĂ©seau Kubernetes fournit des noms stables. Mais pour PostgreSQL, le routage doit respecter les rĂŽles : les Ă©critures doivent aller vers le primary, les lectures optionnelles peuvent aller vers les replicas. C’est l’une des interactions les plus importantes entre Kubernetes et PostgreSQL.

Services typiques

ServiceCibleUsage applicatifRisque
cluster-rwPrimary uniquementConnexions read/write, migrations, transactions.Critique : doit suivre le primary aprĂšs failover.
cluster-roReplicas disponiblesLectures, reporting lĂ©ger, requĂȘtes analytiques contrĂŽlĂ©es.Replica lag, lectures obsolĂštes.
cluster-rN’importe quelle instanceLecture distribuĂ©e selon opĂ©rateur.Peut toucher le primary si mal utilisĂ©.
Headless servicePods individuelsDĂ©couverte stable des instances.À rĂ©server aux besoins internes ou avancĂ©s.

Service ClusterIP minimal

postgres-service.yaml
apiVersion: v1
                kind: Service
                metadata:
                name: postgres-app-rw
                namespace: db-lab
                spec:
                type: ClusterIP
                selector:
                app: postgres-lab
                role: primary
                ports:
                - name: postgres
                port: 5432
                targetPort: 5432

NetworkPolicy : n’autoriser que l’application

postgres-networkpolicy.yaml
apiVersion: networking.k8s.io/v1
                kind: NetworkPolicy
                metadata:
                name: allow-app-to-postgres
                namespace: db-prod
                spec:
                podSelector:
                matchLabels:
                cnpg.io/cluster: pg-prod
                policyTypes:
                - Ingress
                ingress:
                - from:
                - namespaceSelector:
                matchLabels:
                name: app-prod
                podSelector:
                matchLabels:
                app: backend-api
                ports:
                - protocol: TCP
                port: 5432

DNS Ă  connaĂźtre

dns-examples.txt
pg-prod-rw.db-prod.svc.cluster.local
                pg-prod-ro.db-prod.svc.cluster.local
                pg-prod-r.db-prod.svc.cluster.local
                postgres-lab-0.postgres-lab-headless.db-lab.svc.cluster.local
Bonne pratique : les applications ne doivent pas pointer directement vers les noms de pods PostgreSQL. Elles doivent utiliser les services stables prévus pour leur usage : read/write ou read-only.

CloudNativePG : opérateur PostgreSQL Kubernetes

CloudNativePG est un opérateur PostgreSQL trÚs adapté à ce sujet, car il expose clairement les interactions entre Kubernetes et PostgreSQL : CRD Cluster, services, secrets, PVC, backup, failover et restauration.

Objets CNPG importants

ObjetRĂŽleCe que le DBA doit savoir
ClusterDĂ©crit un cluster PostgreSQL complet.Nombre d’instances, version image, stockage, bootstrap, paramĂštres.
BackupDéclenche ou représente un backup.Vérifier statut, date, durée, destination.
ScheduledBackupPlanifie des backups rĂ©currents.S’assurer que la frĂ©quence respecte le RPO.
PoolerGÚre un pool pgBouncer intégré selon configuration.Utile pour réduire les connexions directes à PostgreSQL.
Services générés-rw, -ro, -r.Routage applicatif selon rÎle PostgreSQL.

Manifest CNPG minimal mais sérieux

cnpg-cluster-basic.yaml
apiVersion: postgresql.cnpg.io/v1
                kind: Cluster
                metadata:
                name: pg-prod
                namespace: db-prod
                spec:
                instances: 3
                imageName: ghcr.io/cloudnative-pg/postgresql:16

                bootstrap:
                initdb:
                database: appdb
                owner: appuser
                secret:
                name: appuser-secret

                storage:
                size: 100Gi
                storageClass: db-fast-ssd

                resources:
                requests:
                cpu: "1"
                memory: 4Gi
                limits:
                cpu: "4"
                memory: 8Gi

                postgresql:
                parameters:
                max_connections: "300"
                shared_buffers: 2GB
                effective_cache_size: 6GB
                wal_level: replica
                hot_standby: "on"

                monitoring:
                enablePodMonitor: true

Commandes CNPG d’exploitation

cnpg-operations.sh
kubectl -n db-prod get cluster
                kubectl -n db-prod describe cluster pg-prod
                kubectl -n db-prod get pods -l cnpg.io/cluster=pg-prod -o wide
                kubectl -n db-prod get svc | grep pg-prod
                kubectl -n db-prod get pvc | grep pg-prod
                kubectl -n db-prod get backup
                kubectl -n db-prod logs deployment/cnpg-controller-manager -c manager

Ce que CNPG automatise

Bootstrap

Initialisation depuis zéro, backup ou recovery.

Réplication

Primary/standby, services cohérents, suivi des rÎles.

Failover

Promotion contrĂŽlĂ©e d’un standby en cas de perte du primary.

Backup

Intégration backup physique et archivage WAL vers object storage.

Restore

CrĂ©ation d’un nouveau cluster depuis sauvegarde et WAL.

Monitoring

Exposition de métriques et intégration Prometheus.

À retenir : CNPG ne remplace pas PostgreSQL. Il automatise ce qu’un DBA ferait manuellement : initialiser, configurer, superviser, sauvegarder, promouvoir, restaurer et exposer correctement le cluster.

Manifests : construire un environnement PostgreSQL Kubernetes

Cette section donne une base de manifests que tu peux adapter dans un dĂ©pĂŽt GitOps. L’idĂ©e est d’avoir une organisation claire : namespace, quotas, secrets, storage, cluster PostgreSQL, pooler et politiques rĂ©seau.

Arborescence Git recommandée

git-tree.txt
postgres-k8s-platform/
                clusters/
                dev/
                kustomization.yaml
                namespace.yaml
                quotas.yaml
                secrets.yaml
                cluster.yaml
                pooler.yaml
                networkpolicy.yaml
                prod/
                kustomization.yaml
                namespace.yaml
                quotas.yaml
                secrets-external.yaml
                cluster.yaml
                backup.yaml
                pooler.yaml
                networkpolicy.yaml
                base/
                cnpg-operator/
                storage/
                observability/
                runbooks/
                failover.md
                restore.md
                pvc-full.md
                upgrade.md

Namespace et quota

namespace-and-quota.yaml
apiVersion: v1
                kind: Namespace
                metadata:
                name: db-prod
                labels:
                name: db-prod
                workload-type: database
                ---
                apiVersion: v1
                kind: ResourceQuota
                metadata:
                name: db-prod-quota
                namespace: db-prod
                spec:
                hard:
                requests.cpu: "12"
                requests.memory: 48Gi
                limits.cpu: "24"
                limits.memory: 96Gi
                requests.storage: 2Ti
                persistentvolumeclaims: "20"

Secret applicatif

appuser-secret.yaml
apiVersion: v1
                kind: Secret
                metadata:
                name: appuser-secret
                namespace: db-prod
                type: kubernetes.io/basic-auth
                stringData:
                username: appuser
                password: change-me-in-vault

Pooler pgBouncer via CNPG

cnpg-pooler.yaml
apiVersion: postgresql.cnpg.io/v1
                kind: Pooler
                metadata:
                name: pg-prod-pooler-rw
                namespace: db-prod
                spec:
                cluster:
                name: pg-prod
                instances: 2
                type: rw
                pgbouncer:
                poolMode: transaction
                parameters:
                max_client_conn: "1000"
                default_pool_size: "50"

Kustomization simple

kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
                kind: Kustomization
                resources:
                - namespace-and-quota.yaml
                - appuser-secret.yaml
                - cnpg-cluster-basic.yaml
                - cnpg-pooler.yaml
                - postgres-networkpolicy.yaml
Production : ne stocker aucun mot de passe rĂ©el en clair dans Git. Utiliser Vault, External Secrets, Sealed Secrets ou un mĂ©canisme Ă©quivalent validĂ© par l’équipe sĂ©curitĂ©.

Réplication PostgreSQL dans Kubernetes

La rĂ©plication PostgreSQL repose sur les WAL. Le primary envoie les changements aux standbys via streaming replication. Kubernetes ne fait pas cette rĂ©plication ; il fournit le rĂ©seau, les pods et les services. L’opĂ©rateur configure et surveille.

Concepts PostgreSQL essentiels

ConceptDéfinitionImpact Kubernetes
WALWrite-Ahead Log, journal transactionnel nécessaire à la réplication et au recovery.Peut saturer le disque si archive ou replica bloqué.
PrimaryInstance acceptant les écritures.Le service -rw doit pointer dessus.
StandbyReplica recevant et rejouant les WAL.Le service -ro peut pointer dessus.
Replication slotMécanisme retenant les WAL nécessaires à un consommateur.Un slot inactif peut remplir le PVC du primary.
Replication lagRetard entre primary et standby.Les lectures -ro peuvent ĂȘtre obsolĂštes.

RequĂȘtes SQL de diagnostic rĂ©plication

replication-diagnostics.sql
SELECT application_name,
                client_addr,
                state,
                sync_state,
                sent_lsn,
                write_lsn,
                flush_lsn,
                replay_lsn
                FROM pg_stat_replication;

                SELECT slot_name,
                slot_type,
                active,
                restart_lsn,
                wal_status
                FROM pg_replication_slots;

                SELECT now() - pg_last_xact_replay_timestamp() AS replica_lag;

Commandes Kubernetes corrélées

replication-k8s-checks.sh
kubectl -n db-prod get pods -l cnpg.io/cluster=pg-prod -o wide
                kubectl -n db-prod get svc pg-prod-rw pg-prod-ro pg-prod-r
                kubectl -n db-prod describe cluster pg-prod
                kubectl -n db-prod logs pg-prod-1 | grep -i replication
                kubectl -n db-prod logs pg-prod-2 | grep -i wal

Replication lag : causes typiques

CauseSymptĂŽmeAction
Replica sous-dimensionnĂ©CPU ou I/O saturĂ©s sur standby.Augmenter ressources, vĂ©rifier requĂȘtes longues.
Réseau instableDéconnexions fréquentes, streaming interrompu.Vérifier CNI, NetworkPolicy, DNS, node.
WAL généré trop viteRetard croissant pendant batch massif.Analyser batch, IOPS, checkpoint, archiving.
Slot inactifAccumulation WAL sur primary.Identifier slot, redémarrer consommateur ou supprimer si validé.
Replica bloqué en recoveryLogs recovery répétés.Comparer timeline, WAL disponibles, restaurer replica si nécessaire.
Phrase d’entretien : “Kubernetes expose et dĂ©place les instances, mais c’est PostgreSQL qui garantit la rĂ©plication via WAL. Je surveille donc Ă  la fois les objets Kubernetes et les vues PostgreSQL comme pg_stat_replication.”

Backup : interaction entre WAL, object storage et Kubernetes

En environnement Kubernetes, le backup PostgreSQL sérieux ne doit pas dépendre seulement de la survie des PVC. Il faut externaliser les sauvegardes vers un object storage et archiver les WAL pour restaurer à un point précis.

Trois types de sauvegarde

TypeExempleUsageLimite
Backup logiquepg_dump, pg_dumpallMigration, extraction, petite base, objet spécifique.Lent pour grosses bases, PITR non couvert seul.
Backup physiqueBarman, pgBackRest, base backup.Production, restauration complÚte, gros volumes.Nécessite gestion WAL et compatibilité version.
Snapshot volumeCSI VolumeSnapshotComplément infrastructure, rollback rapide selon contexte.Pas suffisant seul sans cohérence PostgreSQL.

Architecture backup recommandée

Flux backup PostgreSQL Kubernetes
PrimaryGénÚre données et WAL
→
Backup sidecar / toolBase backup + WAL archive
→
Object storageS3 / MinIO / Azure Blob / GCS
→
Restore clusterBootstrap recovery + PITR

Backup CNPG avec plugin Barman Cloud — structure conceptuelle

cnpg-backup-concept.yaml
apiVersion: postgresql.cnpg.io/v1
                kind: ScheduledBackup
                metadata:
                name: pg-prod-daily-backup
                namespace: db-prod
                spec:
                schedule: "0 0 2 * * *"
                backupOwnerReference: self
                cluster:
                name: pg-prod

Backup logique ponctuel via Kubernetes Job

pgdump-job.yaml
apiVersion: batch/v1
                kind: Job
                metadata:
                name: pgdump-appdb
                namespace: db-prod
                spec:
                template:
                spec:
                restartPolicy: Never
                containers:
                - name: pgdump
                image: postgres:16
                env:
                - name: PGPASSWORD
                valueFrom:
                secretKeyRef:
                name: appuser-secret
                key: password
                command:
                - /bin/sh
                - -c
                - |
                pg_dump -h pg-prod-rw -U appuser -d appdb -Fc -f /backup/appdb.dump
                volumeMounts:
                - name: backup-volume
                mountPath: /backup
                volumes:
                - name: backup-volume
                persistentVolumeClaim:
                claimName: pgdump-backup-pvc

ContrĂŽles minimum aprĂšs backup

  • Le backup est-il terminĂ© avec succĂšs ?
  • Les WAL sont-ils archivĂ©s en continu ?
  • Le stockage objet est-il accessible depuis le cluster ?
  • Le backup est-il chiffrĂ© cĂŽtĂ© stockage ou applicatif ?
  • La rĂ©tention respecte-t-elle les contraintes mĂ©tiers et rĂ©glementaires ?
  • Un restore rĂ©el a-t-il Ă©tĂ© testĂ© rĂ©cemment ?
RÚgle absolue : un backup non restauré au moins une fois est une hypothÚse, pas une garantie.

Restore, PITR et reconstruction de cluster

La restauration est le vrai test de l’architecture. Dans Kubernetes, on restaure souvent dans un nouveau cluster PostgreSQL, avec de nouveaux pods et PVC, Ă  partir d’un backup externe et des WAL archivĂ©s.

Types de restauration

TypeObjectifExemple
Restore completReconstruire la base au dernier état sauvegardé.Perte du cluster, corruption volume, migration environnement.
PITRRestaurer juste avant une erreur humaine ou applicative.Suppression accidentelle d’une table à 14:37.
Restore partiel logiqueRestaurer une base, un schĂ©ma ou des objets depuis dump.RĂ©cupĂ©ration d’un environnement de test.
CloneCréer un environnement depuis un backup de production.Staging, analyse incident, recette migration.

Workflow PITR

1. Identifier l’incidentHeure prĂ©cise, base concernĂ©e, action fautive, impact mĂ©tier.
2. Choisir le point cibleDĂ©finir l’horodatage de rĂ©cupĂ©ration juste avant l’erreur.
3. CrĂ©er un cluster de restaurationNe pas Ă©craser immĂ©diatement la production si ce n’est pas validĂ©.
4. Rejouer backup + WALLe moteur restaure le backup physique puis applique les WAL jusqu’au point cible.
5. Valider les donnéesContrÎler tables, séquences, transactions, intégrité applicative.
6. Basculer ou extraireDécider entre remplacement complet, export partiel ou correction applicative.

Exemple conceptuel de bootstrap recovery CNPG

cnpg-recovery-concept.yaml
apiVersion: postgresql.cnpg.io/v1
                kind: Cluster
                metadata:
                name: pg-restore
                namespace: db-restore
                spec:
                instances: 3
                imageName: ghcr.io/cloudnative-pg/postgresql:16

                bootstrap:
                recovery:
                source: pg-prod-backup
                recoveryTarget:
                targetTime: "2026-06-01 14:35:00+00"

                externalClusters:
                - name: pg-prod-backup
                barmanObjectStore:
                destinationPath: s3://postgres-backups/pg-prod
                s3Credentials:
                accessKeyId:
                name: backup-s3-secret
                key: ACCESS_KEY_ID
                secretAccessKey:
                name: backup-s3-secret
                key: SECRET_ACCESS_KEY

                storage:
                size: 100Gi
                storageClass: db-fast-ssd

Validation post-restore

post-restore-validation.sql
SELECT current_database();
                SELECT pg_is_in_recovery();
                SELECT now();
                SELECT count(*) FROM information_schema.tables WHERE table_schema = 'public';
                SELECT datname, numbackends FROM pg_stat_database ORDER BY datname;
                SELECT schemaname, relname, n_live_tup FROM pg_stat_user_tables ORDER BY n_live_tup DESC LIMIT 20;
Bonne pratique : toujours restaurer dans un namespace isolé comme db-restore ou db-drill, puis valider avant toute bascule applicative.

Sécurité : secrets, RBAC, TLS, chiffrement et accÚs

La sécurité PostgreSQL dans Kubernetes combine plusieurs niveaux : sécurité Kubernetes, sécurité réseau, sécurité PostgreSQL, secrets, certificats, chiffrement des volumes et contrÎle des accÚs humains.

Niveaux de sécurité

NiveauContrĂŽleExemple
Kubernetes APIRBAC, namespace isolation, audit logs.Limiter qui peut lire les Secrets et exécuter dans les pods.
SecretsEncryption at rest, Vault, External Secrets.Ne pas stocker les mots de passe réels en clair dans Git.
RéseauNetworkPolicy, TLS, services internes.Autoriser uniquement les pods applicatifs nécessaires.
PostgreSQLRÎles, privilÚges, pg_hba.conf, audit.Séparer owner, app user, migration user, read-only user.
StorageVolumes chiffrĂ©s, snapshots protĂ©gĂ©s, rĂ©tention.Chiffrer les volumes et l’object storage de backup.

RBAC minimal pour lecture DBA

dba-readonly-rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
                kind: Role
                metadata:
                name: dba-readonly
                namespace: db-prod
                rules:
                - apiGroups: [""]
                resources: ["pods", "services", "endpoints", "persistentvolumeclaims", "events"]
                verbs: ["get", "list", "watch"]
                - apiGroups: ["postgresql.cnpg.io"]
                resources: ["clusters", "backups", "scheduledbackups", "poolers"]
                verbs: ["get", "list", "watch"]
                ---
                apiVersion: rbac.authorization.k8s.io/v1
                kind: RoleBinding
                metadata:
                name: dba-readonly-binding
                namespace: db-prod
                subjects:
                - kind: Group
                name: dba-team
                apiGroup: rbac.authorization.k8s.io
                roleRef:
                kind: Role
                name: dba-readonly
                apiGroup: rbac.authorization.k8s.io

RÎles PostgreSQL recommandés

postgres-roles.sql
CREATE ROLE app_owner NOLOGIN;
                CREATE ROLE app_rw LOGIN PASSWORD 'replace-with-secret';
                CREATE ROLE app_ro LOGIN PASSWORD 'replace-with-secret';
                CREATE ROLE app_migration LOGIN PASSWORD 'replace-with-secret';

                GRANT CONNECT ON DATABASE appdb TO app_rw, app_ro, app_migration;
                GRANT USAGE ON SCHEMA public TO app_rw, app_ro, app_migration;
                GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app_rw;
                GRANT SELECT ON ALL TABLES IN SCHEMA public TO app_ro;
                GRANT CREATE, USAGE ON SCHEMA public TO app_migration;

Secrets : rĂšgles pratiques

  • Activer le chiffrement des Secrets Kubernetes dans etcd.
  • Limiter l’accĂšs aux Secrets avec RBAC strict.
  • PrĂ©fĂ©rer Vault ou External Secrets pour la production.
  • Ne jamais exposer le superuser PostgreSQL Ă  l’application.
  • PrĂ©voir une procĂ©dure de rotation des mots de passe.
  • Activer TLS client/serveur si le contexte l’exige.
Erreur dangereuse : donner aux développeurs le droit exec dans les pods PostgreSQL de production peut contourner plusieurs contrÎles. Il faut distinguer observabilité, debug applicatif et accÚs DBA privilégié.

Observabilité : Kubernetes + PostgreSQL

Pour superviser PostgreSQL dans Kubernetes, il faut corrĂ©ler deux familles de signaux : les signaux Kubernetes et les signaux PostgreSQL. Une alerte pod en erreur n’explique pas forcĂ©ment la cause database, et une alerte rĂ©plication peut venir du rĂ©seau, du disque ou du moteur.

Métriques à surveiller

DomaineMétriquesAlerte typique
Kubernetes podRestart count, readiness, CPU, mĂ©moire, OOMKilled.Pod PostgreSQL instable ou non prĂȘt.
StorageUtilisation disque, latence, IOPS, PVC pending.Volume plein, latence élevée, CSI incident.
PostgreSQL connexionsnumbackends, max_connections, pool usage.Connexions saturées, besoin pgBouncer.
RéplicationLag, streaming state, slots, WAL retained.Replica en retard ou slot bloquant.
TransactionsDeadlocks, locks, long transactions, xact age.Blocage applicatif, autovacuum empĂȘchĂ©.
BackupDernier succÚs, durée, WAL archive errors.RPO non tenu.

RequĂȘtes SQL utiles

observability.sql
SELECT datname, numbackends, xact_commit, xact_rollback, deadlocks
                FROM pg_stat_database
                ORDER BY numbackends DESC;

                SELECT pid, usename, state, wait_event_type, wait_event, query_start, query
                FROM pg_stat_activity
                WHERE state <> 'idle'
                ORDER BY query_start;

                SELECT blocked_locks.pid AS blocked_pid,
                blocking_locks.pid AS blocking_pid,
                blocked_activity.query AS blocked_query,
                blocking_activity.query AS blocking_query
                FROM pg_catalog.pg_locks blocked_locks
                JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
                JOIN pg_catalog.pg_locks blocking_locks
                ON blocking_locks.locktype = blocked_locks.locktype
                AND blocking_locks.database IS NOT DISTINCT FROM blocked_locks.database
                AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
                AND blocking_locks.pid != blocked_locks.pid
                JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
                WHERE NOT blocked_locks.granted;

Commandes Kubernetes observabilité

observability-k8s.sh
kubectl -n db-prod get pods -o wide
                kubectl -n db-prod top pods
                kubectl -n db-prod describe cluster pg-prod
                kubectl -n db-prod describe pod pg-prod-1
                kubectl -n db-prod logs pg-prod-1 --previous
                kubectl -n db-prod get events --sort-by=.lastTimestamp

Alertes prioritaires

Primary down

Indisponibilité écriture ou failover en cours.

Replica lag

Lectures obsolĂštes et risque RPO.

WAL archive failed

PITR compromis si non corrigé.

PVC usage high

Risque arrĂȘt brutal si volume plein.

Backup failed

RPO non respecté.

Too many connections

Application ou pooling mal dimensionné.

Incidents typiques et diagnostic croisé

Les incidents PostgreSQL dans Kubernetes sont souvent hybrides : un symptÎme PostgreSQL peut avoir une cause Kubernetes, et un symptÎme Kubernetes peut révéler une contrainte PostgreSQL. Le DBA doit savoir croiser les deux mondes.

Table de diagnostic rapide

SymptĂŽmeCauses possiblesContrĂŽlesAction
Pod PendingPVC non provisionné, quota, zone, node resources.describe pod, describe pvc, events.Corriger storage class, quota ou scheduling.
Pod CrashLoopBackOffPGDATA incohérent, secret invalide, config cassée, disque plein.Logs previous, events, volume usage.Identifier cause avant suppression du volume.
Applications ne se connectent plusService mal routé, DNS, NetworkPolicy, failover en cours, max_connections.Endpoints, service, logs app, pg_stat_activity.Valider service rw, pooling, firewall réseau.
Replica lag massifI/O saturé, batch massif, réseau, standby bloqué.pg_stat_replication, pod metrics, logs standby.Réduire charge, augmenter ressources, reconstruire replica si besoin.
Volume presque pleinWAL retenus, logs, table bloat, backup archive bloquée.df, pg_replication_slots, pg_database_size.Expansion PVC, corriger slots, vacuum, purge maßtrisée.
Backup échoueSecret S3 invalide, réseau, bucket, permission, sidecar erreur.Backup CR status, logs operator, object storage.Corriger credentials et relancer backup test.

Runbook : volume plein

pvc-full-runbook.sh
kubectl -n db-prod get pvc
                kubectl -n db-prod describe pvc pg-prod-1
                kubectl -n db-prod exec -it pg-prod-1 -- df -h
                kubectl -n db-prod exec -it pg-prod-1 -- du -h /var/lib/postgresql/data/pgdata/pg_wal | tail
                kubectl -n db-prod exec -it pg-prod-1 -- psql -U postgres -c "SELECT * FROM pg_replication_slots;"
                kubectl -n db-prod exec -it pg-prod-1 -- psql -U postgres -c "SELECT pg_size_pretty(pg_database_size(datname)), datname FROM pg_database ORDER BY pg_database_size(datname) DESC;"

Runbook : failover suspect

failover-checks.sh
kubectl -n db-prod describe cluster pg-prod
                kubectl -n db-prod get pods -l cnpg.io/cluster=pg-prod -o wide
                kubectl -n db-prod get endpoints pg-prod-rw pg-prod-ro
                kubectl -n db-prod logs deployment/cnpg-controller-manager -c manager | tail -n 200
                kubectl -n db-prod exec -it pg-prod-1 -- psql -U postgres -c "SELECT pg_is_in_recovery();"
RĂšgle d’incident : ne jamais supprimer un PVC PostgreSQL dans la panique. Avant toute action destructive, identifier le rĂŽle de l’instance, l’état du backup, l’état des WAL et la stratĂ©gie de rĂ©cupĂ©ration.

GitOps : PostgreSQL déclaratif et garde-fous

En GitOps, l’état attendu du cluster PostgreSQL est stockĂ© dans Git. ArgoCD ou Flux applique cet Ă©tat au cluster. C’est trĂšs puissant, mais dangereux si les manifests de base de donnĂ©es ne sont pas protĂ©gĂ©s par une vraie revue.

Ce qui doit ĂȘtre dans Git

ÉlĂ©mentDans Git ?Remarque
Manifest Cluster CNPGOuiVersion, instances, stockage, ressources, paramĂštres.
Namespace / quota / RBACOuiPermet reproductibilité et revue sécurité.
NetworkPolicyOuiContrĂŽle des flux applicatifs.
Secrets réelsNon en clairUtiliser Vault, External Secrets ou Sealed Secrets.
Backup policyOuiLa frĂ©quence et la rĂ©tention doivent ĂȘtre revues.
Actions d’incidentPas toujoursLe break-glass peut ĂȘtre hors Git mais doit ĂȘtre tracĂ©.

Application ArgoCD conceptuelle

argocd-postgres-app.yaml
apiVersion: argoproj.io/v1alpha1
                kind: Application
                metadata:
                name: postgres-prod
                namespace: argocd
                spec:
                project: databases
                source:
                repoURL: https://git.example.com/platform/postgres-k8s-platform.git
                targetRevision: main
                path: clusters/prod
                destination:
                server: https://kubernetes.default.svc
                namespace: db-prod
                syncPolicy:
                automated:
                prune: false
                selfHeal: true
                syncOptions:
                - CreateNamespace=true

Garde-fous indispensables

  • Pas de prune automatique agressif sur des ressources stateful sans validation.
  • Pas de modification de taille PVC, version majeure ou paramĂštres critiques sans procĂ©dure.
  • Validation obligatoire des PR touchant PostgreSQL production.
  • Diff lisible avant synchronisation ArgoCD/Flux.
  • Runbook rollback Ă©crit avant upgrade.
  • Environnement staging iso-prod pour rĂ©pĂ©ter les changements.
Point subtil : GitOps peut corriger un drift, mais il peut aussi réappliquer une mauvaise configuration. Pour les bases, la revue humaine reste indispensable sur les changements destructifs ou stateful.

Préparation entretien : questions, réponses et checklist

Cette section synthĂ©tise ce qu’il faut savoir dire en entretien pour montrer que tu maĂźtrises les interactions Kubernetes/PostgreSQL au niveau exploitation DBA/SRE.

Questions probables

QuestionRéponse attendue
Pourquoi PostgreSQL dans Kubernetes est difficile ?Parce que PostgreSQL est stateful : stockage persistant, WAL, rĂ©plication, rĂŽle primary/standby, backup et recovery doivent ĂȘtre coordonnĂ©s avec l’orchestration Kubernetes.
Pourquoi utiliser un opérateur ?Pour automatiser le cycle de vie PostgreSQL : bootstrap, replicas, failover, services, backups, restore, upgrades et monitoring.
Différence entre service rw et ro ?rw pointe vers le primary pour les écritures ; ro pointe vers les replicas pour les lectures, avec attention au replica lag.
Un snapshot PVC suffit-il comme backup ?Non. Il peut aider, mais le backup PostgreSQL sérieux repose sur backup physique cohérent, archivage WAL et test de restauration.
Que regarder si le pod PostgreSQL redĂ©marre ?Events Kubernetes, logs previous, PVC, OOMKilled, disque plein, configuration, Ă©tat PostgreSQL et rĂŽle de l’instance.
Comment réduire les connexions ?Utiliser pgBouncer/pooler, dimensionner max_connections, limiter les connexions applicatives, surveiller pool usage.

Phrase de synthĂšse Ă  utiliser

“Je vois PostgreSQL dans Kubernetes comme une interaction entre deux systĂšmes : Kubernetes orchestre les ressources, mais PostgreSQL reste responsable de la cohĂ©rence transactionnelle, des WAL, de la rĂ©plication et du recovery. Mon rĂŽle DBA est de m’assurer que les services, PVC, secrets, backups, restores, failovers et mĂ©triques sont cohĂ©rents avec les contraintes rĂ©elles du moteur PostgreSQL.”

Checklist lab à préparer

Lab Kubernetes

k3d/kind ou cluster 3 nodes, StorageClass, metrics server, Prometheus stack.

CNPG

Cluster 3 instances, services rw/ro, monitoring activé.

Backup

MinIO/S3, scheduled backup, WAL archive, test restore.

Failover

Suppression du primary, observation promotion, validation service rw.

Sécurité

RBAC read-only, NetworkPolicy, secrets externes ou simulés.

Runbooks

Volume plein, replica lag, backup failed, restore PITR, upgrade mineur.

Mini-séquence de démonstration

demo-sequence.sh
kubectl -n db-prod get cluster pg-prod
                kubectl -n db-prod get pods -l cnpg.io/cluster=pg-prod -o wide
                kubectl -n db-prod get svc pg-prod-rw pg-prod-ro
                kubectl -n db-prod exec -it pg-prod-1 -- psql -U postgres -c "SELECT pg_is_in_recovery();"
                kubectl -n db-prod delete pod pg-prod-1
                kubectl -n db-prod get pods -w
                kubectl -n db-prod get endpoints pg-prod-rw
                kubectl -n db-prod get backup
Objectif entretien : ne pas seulement réciter Kubernetes ou PostgreSQL séparément. Il faut montrer que tu comprends les zones de friction : storage, failover, services, secrets, WAL, backups, restauration et observabilité.