Workstation Logo
Produits
Labs IAAgents OpenAIAgents ClaudeGrok BotWorkstation CRM (WSL CRM)MarketingTous les Produits
Solutions IA
Stations de Travail IAAI SME PackagesIA PrivéeClusters GPUIA EdgeLaboratoire IA EntrepriseIA par Industrie
Services
Modernisation de plateformeIngénierie numériqueDonnées et activation IAOpérations autonomesConseil IAAutomatisation DevOpsCybersécuritéDéveloppement logicielCréation d'agentsMise en place MLOps
À Propos
PartenairesTémoignages Clients
Articles
Documentation
WSL ProxyRing PromoterWSL VaultJobshoutSysOps 24/7
Blog
Nous ContacterLogin
Workstation

Stations de travail IA, logiciels multi-agents IA, infrastructure GPU et solutions d'agents intelligents pour les entreprises modernes.

Nous Contacter

Solutions IA

Stations de Travail IAAI SME PackagesIA PrivéeClusters GPUIA EdgeLaboratoire IA EntrepriseIA par Industrie

Produits

Tous les ProduitsWSL CRM & ERPMarketingAgents OpenAIWSL ProxyRing PromoterWSL VaultJobshoutSysOps 24/7

Entreprise

À ProposPourquoi WorkstationPartenairesTémoignages ClientsTarificationContact

Ressources

ArticlesDocumentationBlogRechercherPlan du Site
Bureau Royaume-Uni
77-79 Marlowes, Hemel Hempstead HP1 1LFItinéraire : prenez la sortie 20 de la M25, Outer LondonN° d'entreprise: 11641870Lun - Ven : 9h00 - 18h00 GMT
+44 7515 356 146
Bureau Belgique
Workstation SRL, Rue Vanderkindere 34, 1180 Uccle, BrusselsBE 0751.518.683Lun - Ven : 9h00 - 18h00 CET
+32 492 45 67 46
Bureau Inde
#159 Sector 9, Pocket 1, DDA Flats, 110077 Dwarka, New Delhi
+91 98881 98841

© 2026 Workstation AI. Tous droits réservés.

ConfidentialitéCookiesConditions d'UtilisationPlan du site web

Loading blog...

Home / Blog
DatabaseKubernetesDevOpsBackend

PostgreSQL Haute disponibilité avec Crunchy Data PGO : Déploiement Enterprise Kubernetes

Enterprise PostgreSQL HA avec Crunchy Data PGO sur Kubernetes

Balinder Walia12 avril 202630 min read

L'exécution de PostgreSQL en production sur Kubernetes nécessite plus qu'un StatefulSet avec un volume persistant. Vous avez besoin d'un basculement automatisé, d'une sauvegarde continue et d'une récupération ponctuelle, d'un regroupement de connexions, du cryptage TLS, d'une surveillance et de la possibilité d'un déploiement cohérent entre les fournisseurs de cloud et le bare metal. Crunchy Data PGO (Postgres Operator) v5 offre tout cela via une seule ressource personnalisée native Kubernetes — lePostgresClusterCRD — soutenue par des composants testés au combat : Patroni pour la haute disponibilité basée sur le consensus, pgBackRest pour la sauvegarde d'entreprise, PgBouncer pour le pooling de connexions et pgMonitor pour l'observabilité compatible Prometheus.

Ce guide couvre tout ce qui est nécessaire pour faire passer un cluster PostgreSQL géré par PGO du déploiement initial au fonctionnement en production sur AWS EKS, Azure AKS, GCP GKE et bare metal k3s avec Rancher. Chaque section comprend des valeurs concrètes YAML, Helm et des procédures opérationnelles que vous pouvez adapter à votre environnement.

Données croustillantes Architecture PGO v5

PGO v5 est une réécriture complète de l'opérateur Crunchy Postgres. Il remplace les précédents pgcluster/pgreplica/pgpolicy CRD par une seule ressourcePostgresClusterqui décrit de manière déclarative tous les aspects d'un déploiement PostgreSQL. L'opérateur surveille les modifications apportées à cette ressource et rapproche les objets Kubernetes sous-jacents (StatefulSets, Services, ConfigMaps, Secrets, Jobs) pour qu'ils correspondent à l'état souhaité.

L'architecture est construite sur quatre piliers.Patronifonctionne comme un side-car dans chaque pod PostgreSQL et gère l'élection du leader, la topologie de réplication et le basculement automatique à l'aide du consensus distribué natif Kubernetes.pgBackRestgère les sauvegardes complètes, différentielles et incrémentielles ainsi que l'archivage WAL continu vers le stockage objet (S3, GCS, Azure Blob) ou les PVC locaux.PgBouncerfournit un pool de connexions léger qui protège le PostgreSQL des tempêtes de connexion.pgMonitorexpose les métriques PostgreSQL via un side-car d'exportateur Prometheus pour l'intégration avec votre pile d'observabilité existante.

Architecture PGO de données croustillantesPod opérateur PGOPostgresCluster CRDInstance principaleStatefulSet (1 module)Chef patronpgMonitor ExportateurInstances de réplicationStatefulSet (N pods)Répliques PatroniRéplication en continupgBackRest RepoS3 / GCS / Azure BlobComplet + Diff + AugmentationArchives WALWALPgBouncer PoolerDéploiement(2+ pods)Prometheus + GrafanaMétriques pgMonitorModules d'applicationConnectez-vous via PgBouncerPrimaireRépliquesSauvegardePooleurSurveillance

L'opérateur lui-même est sans état : tous les états persistants résident dans le cluster PostgreSQL et son référentiel de sauvegarde. Cela signifie que vous pouvez mettre à niveau ou redémarrer l'opérateur sans affecter les bases de données en cours d'exécution. La boucle de réconciliation des opérateurs est idempotente : appliquer plusieurs fois la même spécificationPostgresClusterproduit le même ensemble d'objets Kubernetes.

Installation de PGO v5

PGO v5 peut être installé via Helm ou des manifestes kubectl directs. L'approche Helm est préférée pour la production car elle s'intègre parfaitement aux flux de travail GitOps et fournit des mises à niveau contrôlées par les versions.

# Add the Crunchy Data Helm repository
helm repo add crunchydata https://charts.crunchydata.com
helm repo update

# Install PGO into its own namespace
helm install pgo crunchydata/pgo \
  --namespace postgres-operator \
  --create-namespace \
  --set controllerImages.cluster=registry.crunchydata.com/crunchydata/postgres-operator:ubi8-5.7.2-0 \
  --set relatedImages.postgres_16=registry.crunchydata.com/crunchydata/crunchy-postgres:ubi8-16.6-1 \
  --set relatedImages.pgbackrest=registry.crunchydata.com/crunchydata/crunchy-pgbackrest:ubi8-2.54.1-0 \
  --set relatedImages.pgbouncer=registry.crunchydata.com/crunchydata/crunchy-pgbouncer:ubi8-1.23.1-0 \
  --set relatedImages.pgexporter=registry.crunchydata.com/crunchydata/crunchy-postgres-exporter:ubi8-0.16.0-0

Pour les environnements isolés, mettez en miroir les images requises dans votre registre interne et mettez à jour les valeursrelatedImagesen conséquence. PGO n'extrairea que les images spécifiées dans les valeurs Helm ou la spécificationPostgresCluster- il n'atteindra jamais les registres externes au moment de l'exécution, à moins d'être explicitement configuré pour le faire.

# Verify the operator is running
kubectl get pods -n postgres-operator
NAME                                READY   STATUS    RESTARTS   AGE
pgo-controller-manager-7d8f9b6c4-xk2pt   1/1     Running   0          45s

PostgresCluster CRD Spécification

LePostgresClusterCRD est la surface déclarative unique pour l'ensemble de votre déploiement PostgreSQL. Vous trouverez ci-dessous une spécification prête pour la production qui présente les sections clés. Chaque section est abordée en détail dans les parties suivantes de ce guide.

apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
  name: production-db
  namespace: databases
spec:
  postgresVersion: 16
  image: registry.crunchydata.com/crunchydata/crunchy-postgres:ubi8-16.6-1

  instances:
    - name: pgha1
      replicas: 3
      resources:
        requests:
          cpu: "2"
          memory: 8Gi
        limits:
          cpu: "4"
          memory: 16Gi
      dataVolumeClaimSpec:
        storageClassName: gp3-csi
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 100Gi
      walVolumeClaimSpec:
        storageClassName: gp3-csi
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 20Gi
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - topologyKey: kubernetes.io/hostname
              labelSelector:
                matchLabels:
                  postgres-operator.crunchydata.com/cluster: production-db
      tolerations:
        - key: "workload"
          operator: "Equal"
          value: "database"
          effect: "NoSchedule"

  backups:
    pgbackrest:
      image: registry.crunchydata.com/crunchydata/crunchy-pgbackrest:ubi8-2.54.1-0
      configuration:
        - secret:
            name: pgbackrest-s3-creds
      global:
        repo1-retention-full: "7"
        repo1-retention-diff: "14"
        repo1-path: /pgbackrest/production-db/repo1
        repo1-s3-uri-style: path
      repos:
        - name: repo1
          schedules:
            full: "0 2 * * 0"         # Sunday 2am
            differential: "0 2 * * 1-6" # Mon-Sat 2am
            incremental: "0 */4 * * *"  # Every 4 hours
          s3:
            bucket: mycompany-pg-backups
            endpoint: s3.eu-west-1.amazonaws.com
            region: eu-west-1

  proxy:
    pgBouncer:
      image: registry.crunchydata.com/crunchydata/crunchy-pgbouncer:ubi8-1.23.1-0
      replicas: 2
      resources:
        requests:
          cpu: 500m
          memory: 256Mi
        limits:
          cpu: "1"
          memory: 512Mi
      config:
        global:
          pool_mode: transaction
          max_client_conn: "1000"
          default_pool_size: "25"
          min_pool_size: "5"
          reserve_pool_size: "5"
          reserve_pool_timeout: "3"

  monitoring:
    pgmonitor:
      exporter:
        image: registry.crunchydata.com/crunchydata/crunchy-postgres-exporter:ubi8-0.16.0-0
        resources:
          requests:
            cpu: 100m
            memory: 128Mi

  patroni:
    dynamicConfiguration:
      synchronous_mode: true
      postgresql:
        parameters:
          shared_buffers: 2GB
          effective_cache_size: 6GB
          work_mem: 32MB
          maintenance_work_mem: 512MB
          max_connections: 200
          wal_buffers: 64MB
          checkpoint_completion_target: 0.9
          random_page_cost: 1.1
          effective_io_concurrency: 200
          min_wal_size: 1GB
          max_wal_size: 4GB
          max_worker_processes: 8
          max_parallel_workers_per_gather: 4
          max_parallel_workers: 8
          log_min_duration_statement: 500
          log_checkpoints: "on"
          log_connections: "on"
          log_disconnections: "on"
          log_lock_waits: "on"

  users:
    - name: appuser
      databases: ["appdb"]
      options: "NOSUPERUSER"
    - name: readonly
      databases: ["appdb"]
      options: "NOSUPERUSER"

  databaseInitSQL:
    name: init-sql-configmap
    key: init.sql

Cette spécification crée un cluster PostgreSQL 16 à trois instances avec des volumes de données et WAL séparés, des sauvegardes sauvegardées par S3 selon une planification complète/différentielle/incrémentale, un regroupement de connexions PgBouncer en mode transaction, une exportation de métriques Prometheus et une réplication synchrone Patroni. La règle d'anti-affinité des pods garantit que les trois instances atterrissent sur des nœuds Kubernetes différents.

HA basée sur Patroni et basculement automatique

Patroni est le framework HA intégré dans chaque pod PostgreSQL géré par PGO. Il utilise le Kubernetes API comme magasin de configuration distribué (DCS) – aucun cluster etcd ou ZooKeeper séparé n'est requis. Patroni surveille en permanence la santé du primaire et des répliques PostgreSQL. Lorsque le serveur principal ne répond plus, Patroni lance un basculement automatique : il promeut la réplique la plus à jour au rang de réplique principale et reconfigure les répliques restantes pour qu'elles suivent le nouveau leader.

Le processus de basculement dans PGO fonctionne comme suit. Patroni sur chaque pod détient un verrou de leader dans Kubernetes (via des objets Endpoints ou ConfigMap). Le primaire actuel doit renouveler ce verrou à un intervalle configurable (TTL par défaut de 10 secondes, attente de boucle de 3 secondes). Si le renouvellement du serveur principal ne parvient pas - parce qu'il est tombé en panne, que le nœud est mort ou que le réseau l'a partitionné - une réplique la plus proche de la position WAL du serveur principal acquerra le verrou et se promouvra. L'ensemble du processus se termine généralement en 10 à 30 secondes.

Le mode de réplication synchrone

, activé viasynchronous_mode: truedans la configuration Patroni, garantit zéro perte de données (RPO = 0) au prix d'une latence d'écriture légèrement plus élevée. En mode synchrone, une transaction n'est pas reconnue au client tant qu'au moins une réplique n'a pas confirmé la réception du WAL. Si aucune réplique synchrone n'est disponible, Patroni désactive temporairement le mode synchrone pour maintenir la disponibilité. Vous pouvez remplacer cela avecsynchronous_mode_strict: truesi vous préférez sacrifier la disponibilité par souci de cohérence.

# Check Patroni cluster status
kubectl exec -it production-db-pgha1-0 -n databases -- patronictl list

+----------------------------+-------------------+---------+---------+----+-----------+
| Member                     | Host              | Role    | State   | TL | Lag in MB |
+----------------------------+-------------------+---------+---------+----+-----------+
| production-db-pgha1-0      | 10.244.0.15       | Leader  | running |  3 |           |
| production-db-pgha1-1      | 10.244.1.22       | Replica | running |  3 |         0 |
| production-db-pgha1-2      | 10.244.2.18       | Replica | running |  3 |         0 |
+----------------------------+-------------------+---------+---------+----+-----------+

# Manual switchover (planned, zero downtime)
kubectl exec -it production-db-pgha1-0 -n databases -- \
  patronictl switchover --master production-db-pgha1-0 --candidate production-db-pgha1-1 --force

# Manual failover (forced, for emergencies)
kubectl exec -it production-db-pgha1-1 -n databases -- \
  patronictl failover --candidate production-db-pgha1-1 --force

PGO configure automatiquement les services Kubernetes pour suivre le leader Patroni. Le serviceproduction-db-primarypointe toujours vers le pod qui détient actuellement le verrou principal, de sorte que les applications qui se connectent via ce service bénéficient d'un basculement transparent avec seulement une brève réinitialisation de la connexion.

pgBackRest Sauvegarde et restauration

pgBackRest est le moteur de sauvegarde intégré à PGO. Il prend en charge trois types de sauvegarde : complète, différentielle et incrémentielle, ainsi que l'archivage WAL continu pour la récupération à un moment donné (PITR). Comprendre comment ces éléments s'articulent est essentiel pour concevoir une stratégie de sauvegarde qui équilibre le coût du stockage, la vitesse de sauvegarde et le temps de récupération.

Architecture de sauvegarde pgBackRestPostgreSQL PrimaireFichiers de données(PGDATA)Segments WALpg_wal/répertoirepgBackRestAgentArchive WAL continueSauvegardes planifiéespgBackRest RéférentielS3 / GCS / Azure Blob / PVCSauvegarde complèteCopie complèteDifférentielDepuis le derniercompletIncrémental (depuis le dernier)Archives WAL000000030000000A000000030000000B000000030000000C... continu ...active PITRChronologie de récupération ponctuellecompletDim 02h00Diff.DifférentielDifférentielDifférentielDifférentielcompletDim 02h00Flux WAL continu →Cible PITRRestaurer à tout momentSauvegarde complèteDifférentielFlux WALCible de récupération

Une sauvegarde complètecopie l'intégralité du répertoire de données PostgreSQL et constitue la référence pour tous les autres types de sauvegarde. Une sauvegarde différentiellecopie uniquement les pages modifiées depuis la dernière sauvegarde complète. Une sauvegarde incrémentiellecopie uniquement les pages modifiées depuis la dernière sauvegarde, quel que soit leur type. Pendant la restauration, pgBackRest enchaîne automatiquement les sauvegardes requises — par exemple, la restauration à partir d'une sauvegarde incrémentielle nécessite la sauvegarde incrémentielle plus la sauvegarde différentielle précédente (ou complète) plus la sauvegarde complète, ainsi que tous les segments WAL nécessaires pour atteindre le point de récupération cible.

Configuration du calendrier de sauvegarde du

La planification de sauvegarde est définie dans la sectionreposde la configuration pgBackRest dans la spécificationPostgresCluster. Un calendrier de production solide exécute généralement des sauvegardes hebdomadaires complètes, différentielles quotidiennes et des sauvegardes incrémentielles plus fréquentes.

backups:
  pgbackrest:
    global:
      repo1-retention-full: "4"        # Keep 4 full backups
      repo1-retention-full-type: count
      repo1-retention-diff: "14"       # Keep 14 differentials
    repos:
      - name: repo1
        schedules:
          full: "0 2 * * 0"            # Weekly full: Sunday 2am
          differential: "0 2 * * 1-6"  # Daily diff: Mon-Sat 2am
          incremental: "0 */6 * * *"   # Every 6 hours
        s3:
          bucket: mycompany-pg-backups
          endpoint: s3.eu-west-1.amazonaws.com
          region: eu-west-1

Sauvegarde et restauration manuelles

# Trigger a manual full backup
kubectl annotate postgrescluster production-db -n databases \
  postgres-operator.crunchydata.com/pgbackrest-backup="$(date +%s)" \
  --overwrite

# Check backup status
kubectl exec -it production-db-pgha1-0 -n databases -- \
  pgbackrest info --stanza=db

# Restore to a specific point in time
# First, update the PostgresCluster spec:
spec:
  backups:
    pgbackrest:
      restore:
        enabled: true
        repoName: repo1
        options:
          - --type=time
          - --target="2026-04-12 08:30:00+00"
          - --target-action=promote

# Apply the restore annotation
kubectl annotate postgrescluster production-db -n databases \
  postgres-operator.crunchydata.com/pgbackrest-restore="$(date +%s)" \
  --overwrite

Lors d'une restauration PITR, PGO arrête toutes les instances PostgreSQL, restaure à partir de la sauvegarde complète ou différentielle la plus proche, relit les segments WAL jusqu'à l'heure cible, puis démarre le cluster. L’ensemble de l’opération est orchestré par l’opérateur : aucune intervention manuelle sur les pods individuels n’est nécessaire.

Regroupement de connexions PgBouncer

PostgreSQL crée un nouveau processus pour chaque connexion client. À grande échelle – des centaines ou des milliers de modules d’applications gérant chacun des pools de connexions – ce modèle s’effondre. PgBouncer se situe entre votre application et PostgreSQL, multiplexant de nombreuses connexions client sur un plus petit nombre de connexions serveur.

PGO déploie PgBouncer en tant que déploiement distinct avec son propre service. C'est au serviceproduction-db-pgbouncerque vos applications doivent se connecter, et non directement au service principal PostgreSQL. PgBouncer prend en charge trois modes de pool :

  • Regroupement de sessions— une connexion serveur est attribuée à un client pour la durée de vie de la connexion client. Le plus sûr, mais le moins efficace.
  • Regroupement de transactions— une connexion au serveur est attribuée uniquement pour la durée d'une transaction. Le plus efficace pour les charges de travail Web. Il s'agit de la valeur par défaut recommandée.
  • Regroupement d'instructions— une connexion serveur est attribuée pour une seule instruction. Ne fonctionne que pour les charges de travail simples et non transactionnelles.
proxy:
  pgBouncer:
    replicas: 3
    config:
      global:
        pool_mode: transaction
        max_client_conn: "2000"
        default_pool_size: "30"
        min_pool_size: "10"
        reserve_pool_size: "10"
        reserve_pool_timeout: "3"
        server_idle_timeout: "300"
        server_lifetime: "3600"
        client_idle_timeout: "600"
        tcp_keepalive: "1"
        tcp_keepidle: "30"
        tcp_keepintvl: "10"
        tcp_keepcnt: "3"
    affinity:
      podAntiAffinity:
        preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              topologyKey: kubernetes.io/hostname
              labelSelector:
                matchLabels:
                  postgres-operator.crunchydata.com/role: pgbouncer

Notez les paramètrestcp_keepalive: ils sont essentiels lorsque PgBouncer s'exécute derrière un équilibreur de charge cloud ou un service Kubernetes. Sans keepalives agressifs, les connexions inactives peuvent être supprimées silencieusement par les composants réseau intermédiaires, provoquant des erreurs d'application lors de la prochaine tentative de requête.

pgMonitor et surveillance Prometheus/Grafana

L'intégration de surveillance du

PGO déploie un side-carcrunchy-postgres-exporterdans chaque pod PostgreSQL. Cet exportateur récupère les vues de statistiques internes de PostgreSQL et les expose en tant que métriques Prometheus sur le port 9187. L'exportateur couvre plus de 150 métriques prêtes à l'emploi, notamment les connexions, le délai de réplication, les taux de transaction, les taux de réussite du cache, les statistiques de tables et d'index, les conflits de verrouillage et les taux de génération de WAL.

# ServiceMonitor for Prometheus Operator auto-discovery
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: postgres-monitoring
  namespace: databases
  labels:
    release: kube-prometheus-stack
spec:
  selector:
    matchLabels:
      postgres-operator.crunchydata.com/cluster: production-db
      postgres-operator.crunchydata.com/crunchy-postgres-exporter: "true"
  endpoints:
    - port: exporter
      interval: 15s
      scrapeTimeout: 10s

Crunchy Data fournit un ensemble de tableaux de bord Grafana prédéfinis que vous pouvez importer directement. Ceux-ci couvrent la présentation de PostgreSQL, l'état de réplication, l'état de sauvegarde de pgBackRest, les statistiques de PgBouncer et l'utilisation des ressources au niveau du pod. Importez-les via le provisionnement du tableau de bord de Grafana ou manuellement à partir du référentiel d'exemples Crunchy Data.

# Install Grafana dashboards as ConfigMaps
kubectl create configmap grafana-pg-overview \
  --from-file=pg-overview.json=dashboards/pg-overview.json \
  -n monitoring
kubectl label configmap grafana-pg-overview grafana_dashboard=1 -n monitoring
Règles d'alerte critique

pour PostgreSQL

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: postgres-alerts
  namespace: databases
  labels:
    release: kube-prometheus-stack
spec:
  groups:
    - name: postgresql-health
      rules:
        - alert: PostgresReplicationLagHigh
          expr: ccp_replication_lag_size_bytes > 104857600
          for: 5m
          labels:
            severity: warning
          annotations:
            summary: "Replica {{ $labels.pod }} lag exceeds 100MB"

        - alert: PostgresConnectionsExhausted
          expr: ccp_connection_stats_active / ccp_connection_stats_max_connections > 0.85
          for: 2m
          labels:
            severity: critical
          annotations:
            summary: "PostgreSQL connections above 85% capacity"

        - alert: PostgresDeadlockDetected
          expr: rate(ccp_stat_database_deadlocks[5m]) > 0
          for: 1m
          labels:
            severity: warning
          annotations:
            summary: "Deadlocks detected in {{ $labels.datname }}"

        - alert: PostgresCacheHitRatioLow
          expr: ccp_stat_database_blks_hit / (ccp_stat_database_blks_hit + ccp_stat_database_blks_read) < 0.95
          for: 10m
          labels:
            severity: warning
          annotations:
            summary: "Cache hit ratio below 95% for {{ $labels.datname }}"

        - alert: PgBackRestStaleBackup
          expr: time() - ccp_backrest_last_full_backup_time_since_completion_seconds > 604800
          for: 1h
          labels:
            severity: critical
          annotations:
            summary: "No full backup in the last 7 days"

AWS Déploiement EKS

Le déploiement de PGO sur AWS EKS nécessite la configuration du pilote EBS CSI pour les volumes persistants et des rôles IAM pour les comptes de service (IRSA) pour l'accès à la sauvegarde S3. Cette approche évite de stocker les informations d’identification AWS de longue durée dans les secrets Kubernetes.

# Install the EBS CSI driver (required for gp3 volumes)
eksctl create addon --name aws-ebs-csi-driver --cluster my-cluster --region eu-west-1 \
  --service-account-role-arn arn:aws:iam::111122223333:role/AmazonEKS_EBS_CSI_DriverRole

# Create a gp3 StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: gp3-csi
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  iops: "3000"
  throughput: "125"
  encrypted: "true"
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
# IAM policy for pgBackRest S3 access
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::mycompany-pg-backups",
        "arn:aws:s3:::mycompany-pg-backups/*"
      ]
    }
  ]
}

# Create an IRSA-enabled service account
eksctl create iamserviceaccount \
  --name pgbackrest-sa \
  --namespace databases \
  --cluster my-cluster \
  --attach-policy-arn arn:aws:iam::111122223333:policy/PGBackRestS3Policy \
  --approve

Dans la spécificationPostgresCluster, faites référence au compartiment et à la région S3. PGO utilisera automatiquement les informations d'identification du compte de service du pod (via IRSA) — aucune clé d'accès explicite n'est nécessaire.

backups:
  pgbackrest:
    repos:
      - name: repo1
        s3:
          bucket: mycompany-pg-backups
          endpoint: s3.eu-west-1.amazonaws.com
          region: eu-west-1

Pour une résilience multi-AZ, assurez-vous que vos groupes de nœuds EKS couvrent au moins trois zones de disponibilité et utilisez les contraintes de répartition de la topologie présentées précédemment pour distribuer les pods PostgreSQL entre elles.

Azure Déploiement AKS

Azure AKS utilise des disques gérés pour le stockage persistant et Azure Blob Storage pour les sauvegardes pgBackRest. La classe de stockage recommandée utilise Premium SSD v2 ou Premium LRS pour les charges de travail de base de données.

# StorageClass for Azure Premium SSD
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: azure-premium-ssd
provisioner: disk.csi.azure.com
parameters:
  skuName: Premium_LRS
  kind: Managed
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true

---
# pgBackRest with Azure Blob Storage
backups:
  pgbackrest:
    configuration:
      - secret:
          name: pgbackrest-azure-creds
    global:
      repo1-azure-account: mystorageaccount
      repo1-retention-full: "7"
    repos:
      - name: repo1
        schedules:
          full: "0 2 * * 0"
          differential: "0 2 * * 1-6"
        azure:
          container: pg-backups

---
# Secret with Azure credentials
apiVersion: v1
kind: Secret
metadata:
  name: pgbackrest-azure-creds
  namespace: databases
stringData:
  azure.conf: |
    [global]
    repo1-azure-key=BASE64_STORAGE_ACCOUNT_KEY

Pour Workload Identity (l'équivalent Azure de AWS IRSA), configurez le cluster AKS avec l'émetteur OIDC et créez des informations d'identification d'identité fédérée pour le compte de service pgBackRest. Cela élimine le besoin de stocker les clés de compte dans les secrets.

Déploiement GCP GKE

GKE utilise un disque persistant (pd-ssd) pour le stockage et GCS pour les sauvegardes pgBackRest. GKE Workload Identity mappe les comptes de service Kubernetes aux comptes de service Google Cloud pour une authentification sécurisée et sans clé.

# StorageClass for GKE SSD Persistent Disk
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: pd-ssd
provisioner: pd.csi.storage.gke.io
parameters:
  type: pd-ssd
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true

---
# pgBackRest with GCS
backups:
  pgbackrest:
    configuration:
      - secret:
          name: pgbackrest-gcs-creds
    repos:
      - name: repo1
        gcs:
          bucket: mycompany-pg-backups

---
# GCS service account key secret
apiVersion: v1
kind: Secret
metadata:
  name: pgbackrest-gcs-creds
  namespace: databases
stringData:
  gcs-key.json: |
    {
      "type": "service_account",
      "project_id": "my-project",
      ...
    }
# Enable Workload Identity on GKE
gcloud container clusters update my-cluster \
  --workload-pool=my-project.svc.id.goog

# Create and bind IAM service account
gcloud iam service-accounts create pgbackrest-gcs \
  --display-name="pgBackRest GCS Access"

gcloud projects add-iam-policy-binding my-project \
  --member="serviceAccount:pgbackrest-gcs@my-project.iam.gserviceaccount.com" \
  --role="roles/storage.objectAdmin"

gcloud iam service-accounts add-iam-policy-binding \
  pgbackrest-gcs@my-project.iam.gserviceaccount.com \
  --role="roles/iam.workloadIdentityUser" \
  --member="serviceAccount:my-project.svc.id.goog[databases/production-db-pgbackrest]"

Reprise après sinistre multi-régions

PGO prend en charge les clusters de secours pour la reprise après sinistre entre régions. Un cluster de secours relit en permanence les WAL à partir du référentiel pgBackRest du cluster principal, conservant une copie chaleureuse qui peut être promue au rang de serveur principal indépendant en cas de panne régionale.

DR multirégionavec clusters de secours PGORégion A (primaire)par exemple, AWS eu-west-1 / Azure Europe de l'OuestPostgreSQL PrimaireLecture/écriturePatron LeaderRépliques (2)Lecture seuleRéplication synchroniséeArchives WALDépôt pgBackRest (S3/GCS/Blob)Réplication interrégionale activéeS3 inter-régionRéplicationRégion B (veille)par exemple, AWS us-east-1 / Azure East USPostgreSQL Cluster de secoursRelecture WAL continue à partir du dépôtLecture seule (mode veille)pgBackRest Repo (Région B)répliqué à partir de la région AWAL ReplayBasculement/PromotionMode SynchroneRPO ≈ minutes (expédition WAL)RTO ≈ 5 à 15 minutesAsynchrone (par défaut)RPO ≈ secondes-minutesRTO ≈ 5-15 minutesLe cluster de secourspeut être promu au rang de cluster principal indépendant via le changement de spécification PostgresCluster
# Standby cluster in Region B
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
  name: production-db-standby
  namespace: databases
spec:
  postgresVersion: 16
  image: registry.crunchydata.com/crunchydata/crunchy-postgres:ubi8-16.6-1

  standby:
    enabled: true
    repoName: repo1

  instances:
    - name: pgha1
      replicas: 2
      dataVolumeClaimSpec:
        storageClassName: gp3-csi
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 100Gi

  backups:
    pgbackrest:
      image: registry.crunchydata.com/crunchydata/crunchy-pgbackrest:ubi8-2.54.1-0
      configuration:
        - secret:
            name: pgbackrest-s3-creds
      repos:
        - name: repo1
          s3:
            bucket: mycompany-pg-backups
            endpoint: s3.us-east-1.amazonaws.com
            region: us-east-1

Pour promouvoir le cluster de secours lors d'un sinistre, définissezstandby.enabled: falsedans la spécification et appliquez la modification. PGO promeut le cluster de secours en cluster principal indépendant. Cette promotion est irréversible : vous devrez reconstruire la relation de réplication à partir de zéro une fois la région principale d'origine récupérée.

Déploiement k3s/Rancher sans système d'exploitation

L'exécution de PGO sur k3s nu avec gestion Rancher nécessite une attention particulière au stockage et à la mise en réseau, car vous ne disposez pas de disques gérés par un fournisseur de cloud ou d'équilibreurs de charge.

Déploiement k3s / Rancher PGO (bare metal)Serveur de gestion RancherCluster k3s (3 serveurs + N nœuds d'agent)Opérateur PGONœud d'agent 1PostgreSQL Primaire+ exportateur pgMonitorLonghorn PVC (données + WAL)Dépôt pgBackRest (PVC local)Nœud d'agent 2PostgreSQL Réplique 1+ exportateur pgMonitorLonghorn PVC (données + WAL)Pod PgBouncerNœud d'agent 3PostgreSQL Réplique 2+ exportateur pgMonitorLonghorn PVC (données + WAL)PgBouncer PodÉquilibreur de chargeMetalLB — Expose pg-primary:5432 + pgbouncer:5432PrimaireRépliquesLongue corneSauvegardePgBouncerMétalLBOpérateur

Rangement Longhorn

Longhorn est un système de stockage en bloc léger et distribué pour Kubernetes, idéal pour les environnements sans système d'exploitation. Il réplique les volumes sur plusieurs nœuds pour plus de durabilité et prend en charge les instantanés, les sauvegardes et l'expansion des volumes.

# Install Longhorn via Helm
helm repo add longhorn https://charts.longhorn.io
helm repo update

helm install longhorn longhorn/longhorn \
  --namespace longhorn-system \
  --create-namespace \
  --set defaultSettings.defaultReplicaCount=3 \
  --set defaultSettings.storageOverProvisioningPercentage=100 \
  --set defaultSettings.storageMinimalAvailablePercentage=15

---
# Longhorn StorageClass for PostgreSQL
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: longhorn-pg
provisioner: driver.longhorn.io
parameters:
  numberOfReplicas: "3"
  staleReplicaTimeout: "2880"
  fsType: ext4
  dataLocality: best-effort
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
reclaimPolicy: Retain

MetalLB pour l'équilibrage de charge

# Install MetalLB
helm repo add metallb https://metallb.github.io/metallb
helm install metallb metallb/metallb --namespace metallb-system --create-namespace

---
# Configure IP address pool
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: pg-pool
  namespace: metallb-system
spec:
  addresses:
    - 192.168.1.200-192.168.1.210
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: pg-l2
  namespace: metallb-system
spec:
  ipAddressPools:
    - pg-pool

Avec MetalLB configuré, les services PGO de typeLoadBalancerrecevront les adresses IP de votre pool, rendant les points de terminaison principaux PostgreSQL et PgBouncer directement accessibles depuis votre réseau sans redirection manuelle de port.

pgBackRest avec PVC local ou NFS pour Bare Metal

# For environments without S3/GCS/Azure Blob, use a PVC-based repo
backups:
  pgbackrest:
    repos:
      - name: repo1
        schedules:
          full: "0 2 * * 0"
          differential: "0 2 * * 1-6"
        volume:
          volumeClaimSpec:
            storageClassName: longhorn-pg
            accessModes: ["ReadWriteOnce"]
            resources:
              requests:
                storage: 200Gi

Pour les environnements isolés, vous pouvez également configurer un référentiel pgBackRest secondaire qui expédie les sauvegardes vers un partage NFS ou une instance MinIO exécutée sur site, fournissant une copie de sauvegarde hors cluster sans dépendances cloud.

Configuration du cryptage TLS/SSL

PGO génère par défaut des certificats TLS auto-signés pour toutes les communications internes : les instances PostgreSQL, la réplication, pgBackRest et PgBouncer communiquent tous sur des canaux cryptés sans aucune gestion manuelle des certificats. Toutefois, pour les environnements de production, vous souhaitez généralement utiliser des certificats signés par l'autorité de certification de votre organisation.

# Create a TLS secret with your CA-signed certificates
kubectl create secret tls production-db-tls \
  --cert=server.crt \
  --key=server.key \
  -n databases

kubectl create secret generic production-db-ca \
  --from-file=ca.crt=ca.crt \
  -n databases

---
# Reference in PostgresCluster spec
spec:
  customTLSSecret:
    name: production-db-tls
  customReplicationTLSSecret:
    name: production-db-replication-tls

PGO configure PostgreSQL avecssl = onet définit les paramètresssl_cert_file,ssl_key_fileetssl_ca_fileappropriés. PgBouncer est configuré de la même manière pour nécessiter TLS pour les connexions client et pour utiliser TLS lors de la connexion aux backends PostgreSQL.

# Enforce TLS for all client connections via pg_hba.conf
spec:
  patroni:
    dynamicConfiguration:
      postgresql:
        pg_hba:
          - hostssl all all 0.0.0.0/0 scram-sha-256
          - hostssl replication all 0.0.0.0/0 scram-sha-256

Configuration PostgreSQL personnalisée

PGO expose la configuration PostgreSQL via la section de configuration dynamique Patroni. Il s'agit de l'approche recommandée car Patroni garantit que toutes les instances maintiennent une configuration cohérente et gère les redémarrages si nécessaire.

patroni:
  dynamicConfiguration:
    postgresql:
      parameters:
        # Memory
        shared_buffers: 4GB
        effective_cache_size: 12GB
        work_mem: 64MB
        maintenance_work_mem: 1GB
        huge_pages: "try"

        # WAL
        wal_buffers: 128MB
        min_wal_size: 2GB
        max_wal_size: 8GB
        checkpoint_completion_target: 0.9
        wal_compression: lz4

        # Query Planning
        random_page_cost: 1.1
        effective_io_concurrency: 200
        default_statistics_target: 200

        # Parallelism
        max_worker_processes: 16
        max_parallel_workers_per_gather: 4
        max_parallel_workers: 8
        max_parallel_maintenance_workers: 4

        # Connections
        max_connections: 200
        idle_in_transaction_session_timeout: 60000
        statement_timeout: 300000

        # Logging
        log_min_duration_statement: 250
        log_checkpoints: "on"
        log_connections: "on"
        log_disconnections: "on"
        log_lock_waits: "on"
        log_temp_files: 0
        log_autovacuum_min_duration: 0

        # Autovacuum Tuning
        autovacuum_max_workers: 5
        autovacuum_naptime: 30
        autovacuum_vacuum_cost_limit: 800
        autovacuum_vacuum_scale_factor: 0.02
        autovacuum_analyze_scale_factor: 0.01

Ces paramètres supposent un nœud avec 16 cœurs CPU et 32 ​​Go de RAM dédiés à PostgreSQL. Ajustez leshared_buffersà environ 25 % de la RAM disponible et leeffective_cache_sizeà environ 75 %. Les paramètres WAL et de point de contrôle sont adaptés aux charges de travail lourdes en écriture : réduisez lemax_wal_sizepour les systèmes gourmands en lecture où la fréquence des points de contrôle importe moins.

Gestion des utilisateurs et des bases de données

PGO gère les utilisateurs et les bases de données PostgreSQL de manière déclarative via la sectionusersde la spécificationPostgresCluster. Lorsque vous ajoutez un utilisateur, PGO crée le rôle dans PostgreSQL, génère un mot de passe aléatoire et stocke les informations d'identification dans un secret Kubernetes.

users:
  - name: appuser
    databases: ["appdb"]
    options: "NOSUPERUSER NOCREATEDB NOCREATEROLE"
  - name: readonly
    databases: ["appdb"]
    options: "NOSUPERUSER NOCREATEDB NOCREATEROLE"
  - name: migrations
    databases: ["appdb"]
    options: "NOSUPERUSER CREATEDB"
  - name: monitoring
    databases: ["postgres"]
    options: "NOSUPERUSER LOGIN"

---
# Access credentials from the generated secret
kubectl get secret production-db-pguser-appuser -n databases -o jsonpath='{.data.password}' | base64 -d

# The secret also contains a full connection URI
kubectl get secret production-db-pguser-appuser -n databases -o jsonpath='{.data.uri}' | base64 -d
# postgresql://appuser:PASSWORD@production-db-primary.databases.svc:5432/appdb

Pour accorder un accès en lecture seule, utilisez la fonctionnalitédatabaseInitSQLpour exécuter SQL lors de la création du cluster qui crée un rôle en lecture seule et lui accorde SELECT sur toutes les tables.

# init.sql ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: init-sql-configmap
  namespace: databases
data:
  init.sql: |
    -- Read-only role for reporting users
    ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonly;
    GRANT CONNECT ON DATABASE appdb TO readonly;
    GRANT USAGE ON SCHEMA public TO readonly;
    GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;

    -- Extensions
    CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
    CREATE EXTENSION IF NOT EXISTS pgcrypto;
    CREATE EXTENSION IF NOT EXISTS pg_trgm;

Mises à jour progressives et mises à niveau de versions majeures

PGO gère les mises à niveau de version mineures via des mises à jour progressives. Lorsque vous modifiez la balise d'image dans la spécificationPostgresClusterpar une version de correctif plus récente, PGO met à jour les instances une par une, en commençant par les répliques et en terminant par la principale (ce qui déclenche un basculement Patroni pour minimiser les temps d'arrêt).

# Minor version upgrade: change the image tag
spec:
  image: registry.crunchydata.com/crunchydata/crunchy-postgres:ubi8-16.7-0
Les mises à niveau des versions majeures de

(par exemple, PostgreSQL 15 à 16) nécessitentpg_upgrade, que PGO orchestre via unPGUpgradeCRD distinct.

apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PGUpgrade
metadata:
  name: production-db-upgrade
  namespace: databases
spec:
  postgresClusterName: production-db
  fromPostgresVersion: 15
  toPostgresVersion: 16
  image: registry.crunchydata.com/crunchydata/crunchy-upgrade:ubi8-5.7.2-0

Le processus de mise à niveau arrête le cluster existant, exécutepg_upgrade --linkpour effectuer une mise à niveau sur place à l'aide de liens physiques (minimisant la copie des données), vérifie la mise à niveau et démarre le cluster sur la nouvelle version. Effectuez toujours une sauvegarde complète avant de démarrer une mise à niveau de version majeure et testez d'abord la procédure sur un cluster hors production.

# Pre-upgrade checklist
# 1. Take a full backup
kubectl annotate postgrescluster production-db -n databases \
  postgres-operator.crunchydata.com/pgbackrest-backup="$(date +%s)" \
  --overwrite

# 2. Verify backup completed
kubectl exec -it production-db-pgha1-0 -n databases -- pgbackrest info --stanza=db

# 3. Shutdown the cluster (set replicas to 0 or use PGO shutdown annotation)
kubectl annotate postgrescluster production-db -n databases \
  postgres-operator.crunchydata.com/shutdown="$(date +%s)" \
  --overwrite

# 4. Apply the PGUpgrade resource
kubectl apply -f pg-upgrade.yaml

# 5. Update the PostgresCluster spec with the new version and image
# 6. Remove the shutdown annotation to start the upgraded cluster
Recommandations de réglage de production du

L'exécution de PGO en production nécessite une attention particulière à plusieurs domaines opérationnels au-delà du déploiement initial.

Performances de stockage

  • Données séparées et volumes WAL: Utilisez toujourswalVolumeClaimSpecpour placer WAL sur un PVC dédié. Cela empêche les activités WAL lourdes en écriture d'entrer en conflit avec les E/S de données.
  • Utilisez le stockage à IOPS élevé: gp3 (AWS), Premium SSD v2 (Azure), pd-ssd (GCP) ou Longhorn soutenu par NVMe sur du métal nu. Les modèles d'E/S aléatoires du PostgreSQL nécessitent un stockage à faible latence.
  • Extension de volume: assurez-vous que votre StorageClass dispose deallowVolumeExpansion: true. PGO peut étendre les PVC sans interruption sur les fournisseurs de stockage pris en charge.
Budgets de perturbation des pods

PGO crée automatiquement des PDB pour vos instances PostgreSQL, mais vérifiez qu'elles conviennent à vos exigences HA.

# Check PDBs
kubectl get pdb -n databases
NAME                    MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
production-db-pgha1     1               N/A               2                     7d

Demandes et limites de ressources

  • Définissez les demandes de mémoire égales aux limites des pods de base de données pour éviter les suppressions de MOO et garantir la classe QoS.
  • Réglez les demandes du CPU de manière prudente et limitez-les plus haut pour permettre l'éclatement pendant les opérations de vide ou de maintenance.
  • Surveillez l'utilisation réelle via les métriques pgMonitor et ajustez-la tous les trimestres.

Gestion des connexions

  • Connectez-vous toujours via PgBouncer, pas directement à PostgreSQL.
  • Définissezmax_connectionsdans PostgreSQL sur une valeur qui prend en compte la taille du pool de PgBouncer ainsi que les connexions système (réplication, surveillance, superutilisateur).
  • Utiliser le mode de regroupement de transactions pour les applications Web. Basculez vers le regroupement de sessions uniquement si votre application utilise des instructions préparées ou un état au niveau de la session (par exemple, commandesSET, tables temporaires).

Validation de sauvegarde

  • Testez régulièrement les restaurations en créant un cluster cloné à partir de la sauvegarde et en exécutant des tests de fumée au niveau de l'application.
  • Surveillez l'alertePgBackRestStaleBackuppour garantir que les sauvegardes se terminent dans les délais.
  • Validez PITR en restaurant des horodatages spécifiques et en vérifiant la cohérence des données.
# Clone cluster for backup validation
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
  name: backup-validation
  namespace: databases
spec:
  postgresVersion: 16
  image: registry.crunchydata.com/crunchydata/crunchy-postgres:ubi8-16.6-1
  dataSource:
    postgresCluster:
      clusterName: production-db
      repoName: repo1
      options:
        - --type=time
        - --target="2026-04-12 06:00:00+00"
  instances:
    - name: pgha1
      replicas: 1
      dataVolumeClaimSpec:
        storageClassName: gp3-csi
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 100Gi
  backups:
    pgbackrest:
      repos:
        - name: repo1
          volume:
            volumeClaimSpec:
              accessModes: ["ReadWriteOnce"]
              resources:
                requests:
                  storage: 50Gi
Politiques réseau

# Restrict PostgreSQL traffic to known namespaces
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: postgres-network-policy
  namespace: databases
spec:
  podSelector:
    matchLabels:
      postgres-operator.crunchydata.com/cluster: production-db
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              app-access: database
        - podSelector:
            matchLabels:
              postgres-operator.crunchydata.com/cluster: production-db
      ports:
        - port: 5432
          protocol: TCP
        - port: 9187
          protocol: TCP
Liste de contrôle de surveillance du

  • Retard de réplication: Alerte lorsqu'une réplique dépasse 100 Mo ou 60 secondes de décalage.
  • Saturation des connexions: Alerte lorsque les connexions actives dépassent 80% dumax_connections.
  • Anomalies de taux de transaction: Basez votre TPS et alertez sur les écarts significatifs.
  • Utilisation du disque: Alerte aux seuils de 70 % et 85 % avec les runbooks d'extension de volume.
  • Fraîcheur de la sauvegarde: Alerte lorsque la dernière sauvegarde complète est plus ancienne que votre fenêtre RPO.
  • Conflit de verrous: Alerte sur les verrous maintenus longtemps (> 30 secondes) pouvant indiquer des bugs d'application.
  • Santé de l'autovacuum: Alerte lorsque les tables n'ont pas été aspirées depuis plus de 24 heures.
Runbook de récupération après sinistre

Un plan de reprise après sinistre n'est utile que s'il a été testé. Le runbook suivant décrit les procédures clés pour la récupération après des scénarios de défaillance courants.

Panne d'un seul pod

Patroni et Kubernetes gèrent cela automatiquement. Si le pod principal tombe en panne, Patroni promeut une réplique dans les 10 à 30 secondes. Kubernetes redémarre le pod défaillant, qui rejoint en tant que réplique.

Défaillance d'un nœud unique

Si un nœud exécutant un pod PostgreSQL meurt, Kubernetes replanifie le pod sur un nœud sain. Le pod se connecte à son PVC existant (si le stockage est connecté au réseau) ou restaure à partir d'une sauvegarde (si le stockage local a été utilisé). Les règles d'anti-affinité des pods garantissent que les instances restantes continuent de diffuser le trafic.

Perte complète du cluster

Si l'intégralité du cluster Kubernetes est perdue, déployez un nouveau cluster, installez PGO et créez un nouveauPostgresClusteravec undataSourcepointant vers le référentiel de sauvegarde. PGO restaure la dernière sauvegarde et relit WAL au point disponible le plus récent.

Basculement régional

Si la région principale est perdue, promouvez le cluster de secours en définissantstandby.enabled: false. Mettez à jour votre DNS ou votre équilibreur de charge pour pointer vers la nouvelle région principale. Une fois la région d'origine récupérée, vous pouvez reconstruire la relation de veille à l'envers.

# Promote standby cluster
kubectl patch postgrescluster production-db-standby -n databases --type merge \
  -p '{"spec":{"standby":{"enabled":false}}}'

# Verify the cluster is now an independent primary
kubectl exec -it production-db-standby-pgha1-0 -n databases -- patronictl list
Référence rapide des commandes opérationnelles du

# Cluster status
kubectl get postgrescluster -n databases
kubectl describe postgrescluster production-db -n databases

# Patroni status
kubectl exec -it production-db-pgha1-0 -n databases -- patronictl list
kubectl exec -it production-db-pgha1-0 -n databases -- patronictl history

# Connect to PostgreSQL
kubectl exec -it production-db-pgha1-0 -n databases -- psql -U postgres

# Backup info
kubectl exec -it production-db-pgha1-0 -n databases -- pgbackrest info --stanza=db

# Manual backup
kubectl annotate postgrescluster production-db -n databases \
  postgres-operator.crunchydata.com/pgbackrest-backup="$(date +%s)" --overwrite

# Restart PostgreSQL (rolling)
kubectl annotate postgrescluster production-db -n databases \
  postgres-operator.crunchydata.com/restart="$(date +%s)" --overwrite

# Logs
kubectl logs production-db-pgha1-0 -n databases -c database
kubectl logs production-db-pgha1-0 -n databases -c pgbackrest
kubectl logs production-db-pgha1-0 -n databases -c exporter

# PgBouncer status
kubectl exec -it $(kubectl get pod -l postgres-operator.crunchydata.com/role=pgbouncer -n databases -o name | head -1) -n databases -- psql -U pgbouncer pgbouncer -c "SHOW POOLS;"

# Scale replicas
kubectl patch postgrescluster production-db -n databases --type merge \
  -p '{"spec":{"instances":[{"name":"pgha1","replicas":5}]}}'

Conclusion

Crunchy Data PGO transforme PostgreSQL sur Kubernetes d'une charge opérationnelle en un système déclaratif gérable. LePostgresClusterCRD capture l'intégralité du déploiement (instances, réplication, sauvegarde, pooling, surveillance, TLS) dans une seule ressource contrôlée en version. Patroni propose un basculement automatique éprouvé. pgBackRest offre une sauvegarde de niveau entreprise avec une restauration ponctuelle sur n'importe quel magasin d'objets cloud. PgBouncer gère le regroupement de connexions exigé par le modèle processus par connexion de PostgreSQL à grande échelle. Et pgMonitor alimente les métriques dont vous avez besoin dans Prometheus et Grafana pour une visibilité opérationnelle.

Les modèles de déploiement sur AWS EKS, Azure AKS, GCP GKE et Bare Metal k3s partagent la même spécification de basePostgresCluster: ce qui change, c'est la classe de stockage, la configuration du référentiel de sauvegarde et la couche réseau. Cette cohérence constitue la véritable valeur d'une approche basée sur les opérateurs : votre équipe apprend un seul outil, un seul modèle opérationnel et un seul ensemble de runbooks qui fonctionnent partout.

Commencez avec un cluster à trois instances, PgBouncer en mode pooling de transactions, une planification de sauvegarde hebdomadaire complète et différentielle quotidienne et les alertes Prometheus principales. Validez votre procédure de restauration de sauvegarde dès le premier jour, et non lorsque vous en avez besoin pour la première fois. Étendez-vous aux clusters de secours multirégionaux, à la réplication synchrone et au réglage avancé à mesure que vos besoins en disponibilité et votre maturité opérationnelle augmentent. L'opérateur s'occupe de la mécanique ; votre responsabilité est de bien comprendre l’architecture pour faire les bons compromis en fonction de votre charge de travail.