Interactions Kubernetes et PostgreSQL â Guide DBA / SRE
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.
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.
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
| Couche | Kubernetes apporte | PostgreSQL exige | Risque si mal compris |
|---|---|---|---|
| ExĂ©cution | Pod, 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é. |
| Stockage | PV, 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éseau | Service, DNS, NetworkPolicy, endpoints. | Port 5432, réplication, client routing, split lecture/écriture. | Applications qui écrivent sur un standby, failover non transparent. |
| Cycle de vie | Rolling update, reconciliation, CRD, operator. | Upgrade maßtrisé, sauvegarde avant changement, compatibilité extension. | Upgrade moteur raté, downtime, incompatibilité de données. |
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.
Trois modÚles de déploiement
| ModĂšle | Description | Avantages | Limites |
|---|---|---|---|
| External DB | PostgreSQL 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 manuel | PostgreSQL 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. |
| Operator | PostgreSQL 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
| Contexte | Choix 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. |
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
initdb, un backup existant ou une récupération PITR.Responsabilités comparées
| Action | Kubernetes | PostgreSQL | Operator |
|---|---|---|---|
| Redémarrer un pod | Oui | Crash recovery au redémarrage | Surveille et ordonne si nécessaire |
| Savoir qui est primary | Non nativement | Oui via rÎle interne | Maintient les labels/services cohérents |
| Faire un failover PostgreSQL | Non seul | Promotion possible | Automatise la promotion et le routage |
| Créer un PVC | Oui | Consomme le filesystem | Déclare les volumes nécessaires |
| Archiver les WAL | Non | Produit les WAL | Configure le mécanisme de backup/archive |
| Restaurer à un instant précis | Non | Recovery via backup + WAL | Orchestre bootstrap recovery |
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 PostgreSQL | Deployment | StatefulSet / Operator |
|---|---|---|
| Nom stable par instance | Non garanti | Oui, ordinal stable ou identité opérateur |
| Volume stable par instance | Possible mais moins naturel | Oui, PVC attachĂ© Ă lâinstance |
| Ordre de création et suppression | Non orienté stateful | Oui |
| RĂ©plication primary/standby | Ă coder soi-mĂȘme | Orchestration plus adaptĂ©e |
| Failover DB | Non | Oui avec opérateur |
Exemple pédagogique de StatefulSet PostgreSQL minimal
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: 20GiCommandes de diagnostic utiles
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 appdbCe quâun DBA doit regarder dans un pod PostgreSQL
- Le pod est-il en
Running,Pending,CrashLoopBackOffouTerminating? - 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
| Objet | RĂŽle | Impact PostgreSQL |
|---|---|---|
StorageClass | Décrit le type de volume provisionné par le CSI. | Détermine performance, chiffrement, expansion, zone, politique de suppression. |
PersistentVolumeClaim | Demande de stockage consommée par un pod. | Chaque instance PostgreSQL doit avoir son volume stable. |
PersistentVolume | Volume rĂ©el fourni par lâinfrastructure. | Contient PGDATA, donc les donnĂ©es critiques. |
VolumeSnapshot | Copie ponctuelle dâun volume via CSI. | Utile mais doit ĂȘtre coordonnĂ© avec PostgreSQL pour cohĂ©rence applicative. |
reclaimPolicy | Comportement aprÚs suppression du PVC/PV. | Retain est souvent préférable pour éviter perte accidentelle. |
StorageClass recommandée pour PostgreSQL
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: WaitForFirstConsumerPourquoi 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ĂŽle | Commande | Lecture |
|---|---|---|
| PVC liĂ©s | kubectl -n db get pvc | Tous les PVC doivent ĂȘtre Bound. |
| PV conservés | kubectl get pv | Vérifier Retain pour bases critiques. |
| Events storage | kubectl -n db describe pvc <name> | Repérer erreurs CSI, quota ou zone. |
| Espace disque PostgreSQL | df -h dans le pod | Ne jamais attendre 100% avant action. |
| WAL volumétrie | SELECT * FROM pg_replication_slots; | Un slot bloqué peut retenir trop de WAL. |
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
| Service | Cible | Usage applicatif | Risque |
|---|---|---|---|
cluster-rw | Primary uniquement | Connexions read/write, migrations, transactions. | Critique : doit suivre le primary aprĂšs failover. |
cluster-ro | Replicas disponibles | Lectures, reporting lĂ©ger, requĂȘtes analytiques contrĂŽlĂ©es. | Replica lag, lectures obsolĂštes. |
cluster-r | Nâimporte quelle instance | Lecture distribuĂ©e selon opĂ©rateur. | Peut toucher le primary si mal utilisĂ©. |
| Headless service | Pods individuels | Découverte stable des instances. | à réserver aux besoins internes ou avancés. |
Service ClusterIP minimal
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: 5432NetworkPolicy : nâautoriser que lâapplication
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: 5432DNS Ă connaĂźtre
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.localCloudNativePG : 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
| Objet | RĂŽle | Ce que le DBA doit savoir |
|---|---|---|
Cluster | DĂ©crit un cluster PostgreSQL complet. | Nombre dâinstances, version image, stockage, bootstrap, paramĂštres. |
Backup | Déclenche ou représente un backup. | Vérifier statut, date, durée, destination. |
ScheduledBackup | Planifie des backups rĂ©currents. | Sâassurer que la frĂ©quence respecte le RPO. |
Pooler | GÚ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
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: trueCommandes CNPG dâexploitation
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 managerCe que CNPG automatise
Initialisation depuis zéro, backup ou recovery.
Primary/standby, services cohérents, suivi des rÎles.
Promotion contrĂŽlĂ©e dâun standby en cas de perte du primary.
Intégration backup physique et archivage WAL vers object storage.
CrĂ©ation dâun nouveau cluster depuis sauvegarde et WAL.
Exposition de métriques et intégration Prometheus.
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
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.mdNamespace et quota
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
apiVersion: v1
kind: Secret
metadata:
name: appuser-secret
namespace: db-prod
type: kubernetes.io/basic-auth
stringData:
username: appuser
password: change-me-in-vaultPooler pgBouncer via CNPG
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
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.yamlRé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
| Concept | Définition | Impact Kubernetes |
|---|---|---|
| WAL | Write-Ahead Log, journal transactionnel nécessaire à la réplication et au recovery. | Peut saturer le disque si archive ou replica bloqué. |
| Primary | Instance acceptant les écritures. | Le service -rw doit pointer dessus. |
| Standby | Replica recevant et rejouant les WAL. | Le service -ro peut pointer dessus. |
| Replication slot | Mécanisme retenant les WAL nécessaires à un consommateur. | Un slot inactif peut remplir le PVC du primary. |
| Replication lag | Retard entre primary et standby. | Les lectures -ro peuvent ĂȘtre obsolĂštes. |
RequĂȘtes SQL de diagnostic rĂ©plication
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
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 walReplication lag : causes typiques
| Cause | SymptĂŽme | Action |
|---|---|---|
| Replica sous-dimensionnĂ© | CPU ou I/O saturĂ©s sur standby. | Augmenter ressources, vĂ©rifier requĂȘtes longues. |
| Réseau instable | Déconnexions fréquentes, streaming interrompu. | Vérifier CNI, NetworkPolicy, DNS, node. |
| WAL généré trop vite | Retard croissant pendant batch massif. | Analyser batch, IOPS, checkpoint, archiving. |
| Slot inactif | Accumulation WAL sur primary. | Identifier slot, redémarrer consommateur ou supprimer si validé. |
| Replica bloqué en recovery | Logs recovery répétés. | Comparer timeline, WAL disponibles, restaurer replica si nécessaire. |
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
| Type | Exemple | Usage | Limite |
|---|---|---|---|
| Backup logique | pg_dump, pg_dumpall | Migration, extraction, petite base, objet spécifique. | Lent pour grosses bases, PITR non couvert seul. |
| Backup physique | Barman, pgBackRest, base backup. | Production, restauration complÚte, gros volumes. | Nécessite gestion WAL et compatibilité version. |
| Snapshot volume | CSI VolumeSnapshot | Complément infrastructure, rollback rapide selon contexte. | Pas suffisant seul sans cohérence PostgreSQL. |
Architecture backup recommandée
Backup CNPG avec plugin Barman Cloud â structure conceptuelle
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-prodBackup logique ponctuel via Kubernetes Job
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-pvcContrĂŽ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 ?
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
| Type | Objectif | Exemple |
|---|---|---|
| Restore complet | Reconstruire la base au dernier état sauvegardé. | Perte du cluster, corruption volume, migration environnement. |
| PITR | Restaurer juste avant une erreur humaine ou applicative. | Suppression accidentelle dâune table Ă 14:37. |
| Restore partiel logique | Restaurer une base, un schĂ©ma ou des objets depuis dump. | RĂ©cupĂ©ration dâun environnement de test. |
| Clone | Créer un environnement depuis un backup de production. | Staging, analyse incident, recette migration. |
Workflow PITR
Exemple conceptuel de bootstrap recovery CNPG
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-ssdValidation post-restore
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;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é
| Niveau | ContrĂŽle | Exemple |
|---|---|---|
| Kubernetes API | RBAC, namespace isolation, audit logs. | Limiter qui peut lire les Secrets et exécuter dans les pods. |
| Secrets | Encryption at rest, Vault, External Secrets. | Ne pas stocker les mots de passe réels en clair dans Git. |
| Réseau | NetworkPolicy, TLS, services internes. | Autoriser uniquement les pods applicatifs nécessaires. |
| PostgreSQL | RÎles, privilÚges, pg_hba.conf, audit. | Séparer owner, app user, migration user, read-only user. |
| Storage | Volumes chiffrĂ©s, snapshots protĂ©gĂ©s, rĂ©tention. | Chiffrer les volumes et lâobject storage de backup. |
RBAC minimal pour lecture DBA
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.ioRÎles PostgreSQL recommandés
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.
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
| Domaine | Métriques | Alerte typique |
|---|---|---|
| Kubernetes pod | Restart count, readiness, CPU, mĂ©moire, OOMKilled. | Pod PostgreSQL instable ou non prĂȘt. |
| Storage | Utilisation disque, latence, IOPS, PVC pending. | Volume plein, latence élevée, CSI incident. |
| PostgreSQL connexions | numbackends, max_connections, pool usage. | Connexions saturées, besoin pgBouncer. |
| Réplication | Lag, streaming state, slots, WAL retained. | Replica en retard ou slot bloquant. |
| Transactions | Deadlocks, locks, long transactions, xact age. | Blocage applicatif, autovacuum empĂȘchĂ©. |
| Backup | Dernier succÚs, durée, WAL archive errors. | RPO non tenu. |
RequĂȘtes SQL utiles
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é
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=.lastTimestampAlertes prioritaires
Indisponibilité écriture ou failover en cours.
Lectures obsolĂštes et risque RPO.
PITR compromis si non corrigé.
Risque arrĂȘt brutal si volume plein.
RPO non respecté.
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ĂŽme | Causes possibles | ContrĂŽles | Action |
|---|---|---|---|
Pod Pending | PVC non provisionné, quota, zone, node resources. | describe pod, describe pvc, events. | Corriger storage class, quota ou scheduling. |
Pod CrashLoopBackOff | PGDATA incohérent, secret invalide, config cassée, disque plein. | Logs previous, events, volume usage. | Identifier cause avant suppression du volume. |
| Applications ne se connectent plus | Service 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 massif | I/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 plein | WAL 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 échoue | Secret S3 invalide, réseau, bucket, permission, sidecar erreur. | Backup CR status, logs operator, object storage. | Corriger credentials et relancer backup test. |
Runbook : volume plein
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
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();"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Ă©ment | Dans Git ? | Remarque |
|---|---|---|
| Manifest Cluster CNPG | Oui | Version, instances, stockage, ressources, paramĂštres. |
| Namespace / quota / RBAC | Oui | Permet reproductibilité et revue sécurité. |
| NetworkPolicy | Oui | ContrĂŽle des flux applicatifs. |
| Secrets réels | Non en clair | Utiliser Vault, External Secrets ou Sealed Secrets. |
| Backup policy | Oui | La frĂ©quence et la rĂ©tention doivent ĂȘtre revues. |
| Actions dâincident | Pas toujours | Le break-glass peut ĂȘtre hors Git mais doit ĂȘtre tracĂ©. |
Application ArgoCD conceptuelle
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=trueGarde-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.
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
| Question | Ré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
Checklist lab à préparer
k3d/kind ou cluster 3 nodes, StorageClass, metrics server, Prometheus stack.
Cluster 3 instances, services rw/ro, monitoring activé.
MinIO/S3, scheduled backup, WAL archive, test restore.
Suppression du primary, observation promotion, validation service rw.
RBAC read-only, NetworkPolicy, secrets externes ou simulés.
Volume plein, replica lag, backup failed, restore PITR, upgrade mineur.
Mini-séquence de démonstration
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