Workstation Logo
Produtos
Labs de IAAgentes OpenAIAgentes ClaudeGrok BotWorkstation CRM (WSL CRM)MarketingTodos os Produtos
Soluções IA
Estações de Trabalho IAAI SME PackagesIA PrivadaClusters GPUIA EdgeLaboratório IA EmpresarialIA por Indústria
Serviços
Modernização de plataformaEngenharia digitalFundações de dados e IAOperações autónomasConsultoria de IAAutomação DevOpsCibersegurançaDesenvolvimento de softwareConstrução de agentesConfiguração MLOps
Sobre Nós
ParceirosHistórias de Clientes
Artigos
Documentação
WSL ProxyRing PromoterWSL VaultJobshoutSysOps 24/7
Blog
Contacte-nosLogin
Workstation

Estações de trabalho de IA, software multiagente de IA, infraestrutura de GPU e soluções de agentes inteligentes para empresas modernas.

Contacte-nos

Soluções de IA

Estações de Trabalho IAAI SME PackagesIA PrivadaClusters GPUIA EdgeLaboratório IA EmpresarialIA por Indústria

Produtos

Todos os ProdutosWSL CRM e ERPMarketingAgentes OpenAIWSL ProxyRing PromoterWSL VaultJobshoutSysOps 24/7

Empresa

Sobre NósPor que WorkstationParceirosHistórias de ClientesPreçosContato

Recursos

ArtigosDocumentaçãoBlogPesquisarMapa do Site
Escritório Reino Unido
77-79 Marlowes, Hemel Hempstead HP1 1LFComo chegar: pegue a saída 20 da M25, Outer LondonN.º da empresa: 11641870Seg - Sex: 9:00 - 18:00 GMT
+44 7515 356 146
Escritório Bélgica
Workstation SRL, Rue Vanderkindere 34, 1180 Uccle, BrusselsBE 0751.518.683Seg - Sex: 9:00 - 18:00 CET
+32 492 45 67 46
Escritório Índia
#159 Sector 9, Pocket 1, DDA Flats, 110077 Dwarka, New Delhi
+91 98881 98841

© 2026 Workstation AI. Todos os direitos reservados.

PrivacidadeCookiesTermos de ServiçoMapa do site

Loading blog...

Home / Blog
DatabaseKubernetesDevOpsBackend

Alta disponibilidade PostgreSQL com Zalando Postgres Operator: Guia de implantação Multi-Cloud Kubernetes

Implante PostgreSQL HA de nível de produção com Zalando Operator em qualquer plataforma Kubernetes

Balinder Walia12 de abril de 202628 min read
Introdução ao

: Por que a alta disponibilidade do PostgreSQL no Kubernetes é importante

A execução do PostgreSQL em produção exige alta disponibilidade (HA). O tempo de inatividade medido em minutos pode custar às empresas milhões de dólares em receitas perdidas, minar a confiança do cliente e violar acordos de nível de serviço. O Kubernetes se tornou a plataforma de fato para orquestrar cargas de trabalho em contêineres, mas a execução de serviços com estado como o PostgreSQL no Kubernetes apresenta desafios únicos: gerenciamento de armazenamento persistente, eleição de líder, failover automático, orquestração de backup e pooling de conexões.

OZalando Postgres Operatoré uma solução de código aberto testada em batalha que a Zalando – o maior varejista de moda online da Europa – construiu para gerenciar centenas de clusters PostgreSQL em produção. Ele aproveitaPatronipara eleição de líder baseada em consenso,Spilocomo imagem de contêiner PostgreSQL,WAL-Gpara arquivamento contínuo e recuperação pontual ePgBouncerpara pool de conexões. Juntos, esses componentes oferecem uma implantação PostgreSQL totalmente automatizada e com autocorreção que funciona em qualquer distribuição Kubernetes, desde serviços de nuvem gerenciados como AWS EKS, Azure AKS e Google GKE até clusters bare-metal executando k3s com Rancher.

Neste guia abrangente, exploraremos a arquitetura do operador Zalando Postgres, percorreremos a instalação e configuração em várias plataformas Kubernetes, nos aprofundaremos em replicação, backups, recuperação de desastres, monitoramento e ajuste de produção. Ao final, você terá o conhecimento necessário para implantar e operar clusters PostgreSQL HA de nível de produção em qualquer infraestrutura Kubernetes.

Arquitetura do operador

Zalando Postgres

Compreender a arquitetura é essencial antes da implantação. O operador Zalando Postgres segue o padrão do operador Kubernetes: ele observa definições de recursos personalizados (CRDs) do tipopostgresqle reconcilia o estado desejado em recursos reais do Kubernetes. Aqui está como os componentes se encaixam:

Arquitetura do operadorZalando PostgresPostgreSQLCRDTipo: postgresqlOperadorPostgresRelógios e relógiosReconciliaStatefulSetgerencia o ciclo de vida do podPod primárioSpilo(PostgreSQL)Agente PatroniPod de réplica1Spilo(PostgreSQL)Agente PatroniPod de réplica2Spilo(PostgreSQL)Agente PatroniPatroni DCS (Kubernetes API)Eleição de lídere amp; Estado do clusterPgBouncerPool de conexõesWAL-GBackupspara S3/GCS/AzurePrimárioRéplicaConsenso/DCSBackupConjunto de conexões

Spilo: a imagem do contêiner PostgreSQL

Spiloé a imagem Docker da Zalando que inclui PostgreSQL com Patroni, WAL-G e extensões essenciais. Cada pod no StatefulSet executa um contêiner Spilo. Alças Spilo:

  • Servidor PostgreSQL— o próprio mecanismo de banco de dados, suportando as versões 13 a 16
  • Patroni— o agente HA que gerencia eleição de líder, replicação e failover
  • WAL-G— ferramenta de arquivamento WAL contínuo e backup básico
  • pg_cron, pg_stat_statements, PostGIS— extensões comumente necessárias pré-instaladas

Patroni: Eleição de Líder e Failover Automático

Patroni é o coração do mecanismo HA. Ele usa um Distributed Configuration Store (DCS) para manter o estado do cluster e realizar a eleição do líder. No contexto do operador Zalando, Patroni usa o próprioKubernetes APIcomo DCS (via Endpoints ou ConfigMaps), eliminando a necessidade de um cluster externo etcd ou ZooKeeper.

Veja como funciona o processo de failover do Patroni:

  1. Verificações de integridade— Cada agente Patroni monitora continuamente sua instância PostgreSQL local e relata a integridade ao DCS.
  2. Bloqueio líder— O primário mantém um bloqueio líder no DCS (um objeto Endpoint Kubernetes). O bloqueio possui um TTL (padrão 30 segundos).
  3. Detecção de falha— Se o primário não conseguir renovar seu bloqueio dentro do TTL, as réplicas detectam a ausência.
  4. Eleição— As réplicas elegíveis competem pelo bloqueio de líder. A réplica com o menor atraso de replicação vence.
  5. Promoção
  6. — A réplica vencedora se promove para primária, atualiza o DCS e o endpoint do serviço Kubernetesmasteré atualizado automaticamente.
  7. Esgrima— O antigo primário é cercado (parado ou rebaixado para réplica) para evitar divisão cerebral.

Todo esse processo de failover normalmente é concluído em15 a 30 segundos, garantindo tempo de inatividade mínimo para seus aplicativos.

WAL-G: Arquivamento e Backup Contínuos

WAL-G é uma ferramenta de arquivamento de última geração para PostgreSQL que oferece suporte a backup para S3, Google Cloud Storage (GCS) e Azure Blob Storage. Ele fornece:

  • Backups básicos— Backups físicos completos usandopg_basebackup
  • Arquivamento WAL— Envio contínuo de log write-ahead para recuperação pontual
  • Backups delta— Backups incrementais que armazenam apenas páginas alteradas
  • Criptografia
  • — Criptografia AES-256 de backups em repouso
  • Compressão
  • — Compressão LZ4 ou ZSTD para custos de armazenamento reduzidos
Hierarquia de recursos

Kubernetes

Quando você cria um recurso personalizadopostgresql, o operador cria um conjunto abrangente de recursos Kubernetes para gerenciar o cluster. Compreender esta hierarquia é importante para solução de problemas e monitoramento:

Hierarquia de recursosKubernetes - Operador Zalandopostgresql CRDOperadorPostgresStatefulSetServiço(mestre)Serviço(réplica)TerminaisPDBMódulosPVCsSegredos doImplantarPgBouncerServiço(pooler)PrimárioRéplicaRéplicaLinhas sólidas = criação direta | Linhas tracejadas = criação condicionalRecursos

criados pelo operador

  • StatefulSet— Gerencia os pods PostgreSQL com identidades de rede estáveis e implantação ordenada
  • Serviços— Dois serviços ClusterIP:<cluster-name>para o primário e<cluster-name>-replpara réplicas de leitura
  • Endpoints— Patroni atualiza endpoints para apontar para o líder atual para failover contínuo
  • PodDisruptionBudgets (PDB)— Garante que pelo menos uma instância permaneça disponível durante interrupções voluntárias
  • Secrets— Superusuário PostgreSQL, replicação e credenciais de aplicativo armazenadas como Kubernetes Secrets
  • PersistentVolumeClaims (PVCs)— Um PVC por pod para PostgreSQL armazenamento de dados
  • PgBouncer Deployment— Pooler de conexão opcional implantado como uma implantação separada com seu próprio serviço
Instalação do

em múltiplas plataformas Kubernetes

Pré-requisitos do

Antes de instalar o Zalando Postgres Operator, certifique-se de ter:

  • Um cluster Kubernetes em execução (v1.25+)
  • kubectlconfigurado com acesso de administrador de cluster
  • helmv3 instalado
  • Um StorageClass padrão configurado
Instalação do operador

via Helm

O método de instalação recomendado usa Helm. Isso funciona de forma consistente em todas as plataformas Kubernetes:

# Add the Zalando Postgres Operator Helm repository
helm repo add postgres-operator-charts https://opensource.zalando.com/postgres-operator/charts/postgres-operator
helm repo add postgres-operator-ui-charts https://opensource.zalando.com/postgres-operator/charts/postgres-operator-ui
helm repo update

# Create a dedicated namespace
kubectl create namespace postgres-operator

# Install the operator with custom values
helm install postgres-operator postgres-operator-charts/postgres-operator \
  --namespace postgres-operator \
  --set configKubernetes.enable_pod_antiaffinity=true \
  --set configKubernetes.pod_environment_configmap=postgres-pod-config \
  --set configAwsOrGcp.aws_region=us-east-1 \
  --set configLoadBalancer.db_hosted_zone=db.example.com \
  --set configConnectionPooler.connection_pooler_default_cpu_request=500m \
  --set configConnectionPooler.connection_pooler_default_memory_request=100Mi

# Optionally install the operator UI for visual management
helm install postgres-operator-ui postgres-operator-ui-charts/postgres-operator-ui \
  --namespace postgres-operator

Verifique se o operador está em execução:

kubectl get pods -n postgres-operator
# Expected output:
# NAME                                 READY   STATUS    RESTARTS   AGE
# postgres-operator-7f8b9c6d4-x2k9j   1/1     Running   0          2m
Especificações de implantação do

AWS EKS

Amazon EKS requer configuração específica para desempenho ideal do PostgreSQL:

# EKS-specific Helm values (eks-values.yaml)
configAwsOrGcp:
  aws_region: us-east-1
  enable_ebs_gp3_migration: true
  additional_secret_mount: "aws-iam-token"

configKubernetes:
  enable_pod_antiaffinity: true
  pod_environment_configmap: "postgres-pod-config"
  spilo_privileged: false
  storage_resize_mode: pvc

# Use EBS gp3 StorageClass for better performance
# Create the StorageClass first:
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ebs-gp3-postgres
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  iops: "6000"
  throughput: "400"
  encrypted: "true"
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true

Para backups WAL-G no EKS, configure funções IAM para contas de serviço (IRSA):

# Create IAM policy for WAL-G S3 access
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:ListBucket",
        "s3:DeleteObject",
        "s3:GetBucketLocation"
      ],
      "Resource": [
        "arn:aws:s3:::my-pg-backups",
        "arn:aws:s3:::my-pg-backups/*"
      ]
    }
  ]
}
Implantação

Azure AKS

Azure AKS usa disco Azure para armazenamento persistente e identidade gerenciada para autenticação de backup:

# AKS-specific StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: managed-premium-postgres
provisioner: disk.csi.azure.com
parameters:
  skuName: Premium_LRS
  cachingMode: ReadOnly
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
---
# WAL-G backup to Azure Blob Storage environment variables
apiVersion: v1
kind: ConfigMap
metadata:
  name: postgres-pod-config
  namespace: default
data:
  AZURE_STORAGE_ACCOUNT: "pgbackupsstorage"
  AZURE_STORAGE_ACCESS_KEY: "" # Use Managed Identity instead
  WALG_AZ_PREFIX: "azure://pg-wal-backups/$(SCOPE)"
  USE_WALG_BACKUP: "true"
  USE_WALG_RESTORE: "true"
  BACKUP_SCHEDULE: "0 2 * * *"
  BACKUP_NUM_TO_RETAIN: "7"
Implantação do Google GKE

Google Kubernetes Engine usa disco permanente e identidade de carga de trabalho para acesso de backup do GCS:

# GKE StorageClass for SSD Persistent Disks
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ssd-postgres
provisioner: pd.csi.storage.gke.io
parameters:
  type: pd-ssd
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
---
# GCS backup configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: postgres-pod-config
  namespace: default
data:
  WALG_GS_PREFIX: "gs://my-pg-backups/$(SCOPE)"
  USE_WALG_BACKUP: "true"
  USE_WALG_RESTORE: "true"
  GOOGLE_APPLICATION_CREDENTIALS: "/var/secrets/google/key.json"
  BACKUP_SCHEDULE: "0 2 * * *"
  BACKUP_NUM_TO_RETAIN: "7"

Bare Metal k3s/Rancher com armazenamento Longhorn

Para implantações locais, o k3s fornece uma distribuição Kubernetes leve e o Longhorn oferece armazenamento em bloco distribuído. Essa combinação é ideal quando você precisa de controle total sobre sua infraestrutura sem dependência de um fornecedor de nuvem.

# Install k3s on all nodes
# Master node:
curl -sfL https://get.k3s.io | sh -s - server \
  --cluster-init \
  --disable traefik \
  --write-kubeconfig-mode 644

# Worker nodes:
curl -sfL https://get.k3s.io | sh -s - agent \
  --server https://master-ip:6443 \
  --token $(cat /var/lib/rancher/k3s/server/node-token)

# Install Longhorn for persistent storage
helm repo add longhorn https://charts.longhorn.io
helm install longhorn longhorn/longhorn \
  --namespace longhorn-system \
  --create-namespace \
  --set defaultSettings.defaultReplicaCount=3 \
  --set defaultSettings.defaultDataPath=/mnt/longhorn

# Install MetalLB for LoadBalancer services
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.5/config/manifests/metallb-native.yaml

# Configure MetalLB IP pool
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: postgres-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.1.200-192.168.1.210
k3s / Implantação de metal nu RancherServidor de gerenciamento de fazendeiroNó 1(servidor k3s)PostgreSQL PrimárioSpilo + PatroniOperador ZalandoPiscinaPgBouncerVolume Longhorn/mnt/longhorn (3 réplicas)Nó 2(servidor k3s)RéplicaPostgreSQLSpilo + PatroniPiscinaPgBouncerPrometheus ExportadorVolume Longhorn/mnt/longhorn (3 réplicas)Nó 3 (agente k3s)RéplicaPostgreSQLSpilo + PatroniPiscinaPgBouncerPainelGrafanaVolume Longhorn/mnt/longhorn (3 réplicas)HAProxy / MetalLB LoadBalancerWAL-G Backupscompatível com NFS / MinIO S3PrimárioRéplicaPgBouncerChifre LongoReplicação de streamingEspecificação

PostgreSQL Cluster CRD

O núcleo da implantação de um O cluster PostgreSQL com o operador Zalando é o recurso personalizadopostgresql. Este manifesto YAML declara o estado desejado do seu cluster e o operador o transforma em realidade. Abaixo está uma especificação CRD abrangente e pronta para produção:

apiVersion: acid.zalan.do/v1
kind: postgresql
metadata:
  name: pg-production-cluster
  namespace: databases
  labels:
    team: platform
    environment: production
spec:
  teamId: "platform"
  volume:
    size: 100Gi
    storageClass: ebs-gp3-postgres
  numberOfInstances: 3
  enableConnectionPooler: true
  enableReplicaConnectionPooler: true
  connectionPooler:
    numberOfInstances: 2
    mode: transaction
    schema: pooler
    user: pooler
    resources:
      requests:
        cpu: 500m
        memory: 100Mi
      limits:
        cpu: "1"
        memory: 256Mi
  users:
    app_user:
    - superuser
    - createdb
    readonly_user: []
  databases:
    app_database: app_user
  postgresql:
    version: "16"
    parameters:
      shared_buffers: "2GB"
      max_connections: "200"
      work_mem: "64MB"
      maintenance_work_mem: "512MB"
      effective_cache_size: "6GB"
      random_page_cost: "1.1"
      effective_io_concurrency: "200"
      wal_buffers: "64MB"
      max_wal_size: "4GB"
      min_wal_size: "1GB"
      checkpoint_completion_target: "0.9"
      default_statistics_target: "100"
      log_statement: "ddl"
      log_min_duration_statement: "1000"
      idle_in_transaction_session_timeout: "600000"
      lock_timeout: "30000"
      statement_timeout: "60000"
  patroni:
    initdb:
      encoding: "UTF8"
      locale: "en_US.UTF-8"
      data-checksums: "true"
    pg_hba:
    - hostssl all all 0.0.0.0/0 md5
    - host    all all 0.0.0.0/0 md5
    ttl: 30
    loop_wait: 10
    retry_timeout: 10
    synchronous_mode: false
    synchronous_mode_strict: false
    maximum_lag_on_failover: 33554432
  resources:
    requests:
      cpu: "2"
      memory: 8Gi
    limits:
      cpu: "4"
      memory: 16Gi
  podAnnotations:
    prometheus.io/scrape: "true"
    prometheus.io/port: "9187"
  tolerations:
  - key: "database"
    operator: "Equal"
    value: "postgres"
    effect: "NoSchedule"
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: workload-type
          operator: In
          values:
          - database
  enableShmVolume: true
  spiloRunAsUser: 101
  spiloRunAsGroup: 103
  spiloFSGroup: 103
Campos chave CRD

explicados

  • numberOfInstances— Número total de pods. O operador designa automaticamente um como primário e o restante como réplicas de streaming.
  • enableConnectionPooler— Implanta sidecar PgBouncer para o serviço primário, reduzindo a sobrecarga de conexão.
  • enableReplicaConnectionPooler— Implanta um PgBouncer separado para o serviço de réplica, essencial para cargas de trabalho com uso intenso de leitura.
  • postgresql.parameters— Parâmetros de configuração diretos do PostgreSQL passados parapostgresql.conf.
  • patroni— Configura o comportamento do Patroni incluindo TTL, espera de loop, tempo limite de nova tentativa e modo de replicação síncrona.
  • volume.storageClass— Mapeia para o StorageClass específico da plataforma (EBS gp3 no AWS, Premium SSD no Azure, SSD PD no GCP, Longhorn no k3s).
  • enableShmVolume— Monta umtmpfsem/dev/shmpara memória compartilhada PostgreSQL, fundamental para desempenho.
Pool de conexões

com PgBouncer

O modelo de processo por conexão do

PostgreSQL torna caro lidar com um grande número de conexões de clientes. Cada conexão consome aproximadamente 10 MB de RAM. O PgBouncer resolve isso multiplexando milhares de conexões de clientes em um pequeno conjunto de conexões PostgreSQL reais.

O operador Zalando suporta nativamente a implantação do PgBouncer. Ao definirenableConnectionPooler: trueno CRD, o operador cria:

  • Uma implantação PgBouncer com contagem de réplicas configurável
  • Um serviço dedicado (<cluster-name>-pooler) para conexões em pool
  • Sincronização automática de credenciais com PostgreSQL
Modos de configuração do PgBouncer

# PgBouncer connection pooler modes:
#
# transaction (recommended for most workloads)
#   - Connection returned to pool after each transaction
#   - Best balance of efficiency and compatibility
#   - Cannot use session-level features (prepared statements, temp tables)
#
# session
#   - Connection held for entire client session
#   - Full PostgreSQL compatibility
#   - Lower pooling efficiency
#
# statement
#   - Connection returned after each statement
#   - Most efficient but most restrictive
#   - Only works with autocommit queries

# Custom PgBouncer configuration via operator
spec:
  connectionPooler:
    numberOfInstances: 3
    mode: transaction
    schema: pooler
    user: pooler
    defaultPoolSize: 25
    maxDBConnections: 100
    resources:
      requests:
        cpu: 250m
        memory: 128Mi
      limits:
        cpu: "1"
        memory: 256Mi

Para aplicativos que precisam de instruções preparadas ou recursos em nível de sessão, conecte-se diretamente aos serviços PostgreSQL ignorando o PgBouncer ou use o modo de poolingsessioncom a compensação de menor eficiência de conexão.

Replicação PostgreSQL multirregional

Para aplicações globais que exigem leituras de baixa latência de vários locais geográficos ou recuperação de desastres entre regiões, a replicação multirregional é essencial. O operador Zalando oferece suporte a isso por meio de clusters de espera que replicam de um cluster primário por meio de replicação de streaming ou arquivos WAL-G.

Replicação de streaming PostgreSQL multirregionalUS-EAST-1 (AWS EKS)CLUSTER PRIMÁRIOpg-prod-us (3 cápsulas)PrimárioRéplicaReplicação de sincronizaçãodentro de AZWAL-G → S3 (contínuo)PoolerPgBouncerEU-OESTE-1 (Azure AKS)CLUSTER EM ESPERApg-standby-eu (2 pods)em esperaRéplicaReplicação em cascataWAL-G → Blob AzurePgBouncer (somente leitura)AP-SUDESTE (GCP GKE)CLUSTER EM ESPERApg-standby-ap (2 pods)em esperaRéplicaReplicação em cascataWAL-G → Balde GCSPgBouncer (somente leitura)AssíncronoASYNC (envio WAL)Topologia de replicaçãoPrimário (US-EAST) → Streaming assíncrono para EU-WEST e EU-WEST. Clusters de espera AP-SOUTHEAST | RPO: ~segundos | RTO: <5 min com promoção manualReplicação de sincronizaçãoReplicação assíncronaPrimárioLíder de esperaLer RéplicaConfiguração de replicação de streaming

A replicação de streaming

PostgreSQL é a base do HA na operadora Zalando. Ele funciona enviando registros Write-Ahead Log (WAL) do primário para réplicas quase em tempo real. O operador configura isso automaticamente, mas compreender os detalhes ajuda no ajuste e na solução de problemas.

  • Replicação síncrona— O primário espera por pelo menos uma réplica para confirmar o recebimento do WAL antes de confirmar uma transação. Isso garante zero perda de dados (RPO=0), mas adiciona latência. Habilite compatroni.synchronous_mode: true.
  • Replicação assíncrona— O principal confirma imediatamente e envia o WAL de forma assíncrona. Latência um pouco menor, mas potencial perda de dados durante o failover. Este é o padrão.
  • Replicação em cascata— As réplicas podem ser replicadas de outras réplicas em vez da primária, reduzindo a carga na primária em clusters grandes.
# Enable synchronous replication for zero data loss
spec:
  patroni:
    synchronous_mode: true
    synchronous_mode_strict: false  # Allow async if no sync replica available
    synchronous_node_count: 1       # Number of sync replicas required
  postgresql:
    parameters:
      synchronous_commit: "on"      # Matches Patroni synchronous_mode
      max_wal_senders: "10"         # Maximum WAL sender processes
      wal_keep_size: "1GB"          # WAL retention for replica catch-up
      hot_standby: "on"             # Allow queries on replicas
      hot_standby_feedback: "on"    # Reduce query conflicts on replicas
Backup e recuperação

com WAL-G

Configuração de backup

WAL-G

A configuração adequada de backup é crítica para a recuperação de desastres. A operadora Zalando integra WAL-G para backup contínuo para armazenamento de objetos. Aqui está uma configuração completa para armazenamento compatível com S3:

# ConfigMap for WAL-G backup configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: postgres-pod-config
  namespace: databases
data:
  # S3 backup configuration
  AWS_ENDPOINT: "https://s3.us-east-1.amazonaws.com"
  AWS_S3_FORCE_PATH_STYLE: "false"
  AWS_REGION: "us-east-1"
  WALG_S3_PREFIX: "s3://my-pg-backups/$(SCOPE)"
  WALG_DISABLE_S3_SSE: "false"
  WALG_S3_SSE: "aws:kms"
  WALG_S3_SSE_KMS_ID: "arn:aws:kms:us-east-1:123456789:key/mrk-abcdef"

  # Backup scheduling and retention
  USE_WALG_BACKUP: "true"
  USE_WALG_RESTORE: "true"
  BACKUP_SCHEDULE: "0 1 * * *"       # Daily at 1 AM UTC
  BACKUP_NUM_TO_RETAIN: "14"          # Keep 14 daily backups

  # WAL archiving
  WALG_COMPRESSION_METHOD: "zstd"     # Better compression than lz4
  WALG_DELTA_MAX_STEPS: "6"           # Delta backups between full backups
  WALG_UPLOAD_CONCURRENCY: "4"        # Parallel upload streams
  WALG_DOWNLOAD_CONCURRENCY: "4"      # Parallel download for restore
  WALG_UPLOAD_DISK_CONCURRENCY: "4"   # Disk read concurrency

  # Clone configuration
  CLONE_AWS_ENDPOINT: "https://s3.us-east-1.amazonaws.com"
  CLONE_AWS_REGION: "us-east-1"
  CLONE_WALG_S3_PREFIX: "s3://my-pg-backups/$(CLONE_SCOPE)"
  CLONE_METHOD: "CLONE_WITH_WALG"
  CLONE_USE_WALG_RESTORE: "true"

Recuperação pontual (PITR)

O

PITR permite restaurar seu banco de dados para qualquer momento específico – fundamental para a recuperação de exclusão acidental ou corrupção de dados. A operadora Zalando suporta PITR através do mecanismo de clone:

# Clone a cluster with PITR
apiVersion: acid.zalan.do/v1
kind: postgresql
metadata:
  name: pg-restored-cluster
  namespace: databases
spec:
  teamId: "platform"
  volume:
    size: 100Gi
    storageClass: ebs-gp3-postgres
  numberOfInstances: 3
  postgresql:
    version: "16"
  clone:
    cluster: "pg-production-cluster"
    timestamp: "2026-04-11T14:30:00+00:00"  # Restore to this exact moment
    s3_wal_path: "s3://my-pg-backups/wal/16/pg-production-cluster"
    s3_endpoint: "https://s3.us-east-1.amazonaws.com"
    s3_access_key_id: ""      # Use IAM role instead
    s3_secret_access_key: ""  # Use IAM role instead

Quando este CRD é aplicado, o operador executa os seguintes passos:

  1. Encontra o backup base mais recente antes do timestamp alvo
  2. Restaura o backup base para o pod primário do novo StatefulSet
  3. reproduz segmentos WAL até o carimbo de data/hora especificado
  4. Abre o banco de dados para operações de leitura e gravação
  5. Configura a replicação de streaming para os pods de réplica
Cluster de espera

para recuperação de desastres

Um cluster de espera replica continuamente a partir de um cluster primário, fornecendo uma espera quente que pode ser promovida durante um desastre. Isso é diferente das réplicas dentro de um cluster: um cluster em espera é um recurso Kubernetes completamente independente que pode ser executado em um namespace, cluster ou até mesmo região diferente.

# Standby cluster in a different region
apiVersion: acid.zalan.do/v1
kind: postgresql
metadata:
  name: pg-standby-eu
  namespace: databases
spec:
  teamId: "platform"
  volume:
    size: 100Gi
    storageClass: managed-premium-postgres
  numberOfInstances: 2
  postgresql:
    version: "16"
  standby:
    standby_host: "pg-production-cluster.databases.svc.cluster.local"
    standby_port: "5432"
    # Alternative: replicate from S3 WAL archive
    # s3_wal_path: "s3://my-pg-backups/wal/16/pg-production-cluster"
  enableConnectionPooler: true
  enableReplicaConnectionPooler: true

Para promover um cluster standby a primário independente (durante a recuperação de desastres), basta remover a seçãostandbydo CRD e aplicar:

# Edit the standby cluster CRD to remove standby section
kubectl patch postgresql pg-standby-eu -n databases --type json \
  -p '[{"op": "remove", "path": "/spec/standby"}]'

# The operator will promote the standby to primary
# Update your application DNS/service mesh to point to the new primary
Monitoramento

com Prometheus e Grafana

O monitoramento abrangente não é negociável para implantações de produção PostgreSQL. A operadora Zalando oferece suporte à exportação de métricas Prometheus por meio do sidecarpostgres_exporter. Veja como configurar uma pilha de monitoramento completa:

Monitor de serviço

para Prometheus

# ServiceMonitor for PostgreSQL metrics
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: postgres-monitor
  namespace: databases
  labels:
    team: platform
    release: prometheus
spec:
  selector:
    matchLabels:
      team: platform
  namespaceSelector:
    matchNames:
    - databases
  endpoints:
  - port: exporter
    interval: 15s
    scrapeTimeout: 10s
    path: /metrics
    relabelings:
    - sourceLabels: [__meta_kubernetes_pod_label_spilo_role]
      targetLabel: role
    - sourceLabels: [__meta_kubernetes_pod_label_cluster_name]
      targetLabel: cluster
---
# PodMonitor alternative (scrapes pods directly)
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
  name: postgres-pod-monitor
  namespace: databases
spec:
  selector:
    matchLabels:
      application: spilo
  podMetricsEndpoints:
  - port: exporter
    interval: 15s
    path: /metrics
Principais métricas do

para monitorar o

Estas são as métricas PostgreSQL mais críticas para rastrear em seus painéis Grafana:

  • pg_stat_replication_lag— Atraso de replicação em bytes e segundos. Alerte se o atraso exceder seu limite de RPO.
  • pg_stat_activity_count— Conexões ativas por estado. Alerta sobre o esgotamento do pool de conexões.
  • pg_stat_database_tup_fetched/retornado/inserido/atualizado/excluído— Métricas de rendimento de consulta.
  • pg_stat_bgwriter_buffers_checkpoint/clean/backend— Eficiência no gerenciamento de buffer.
  • pg_database_size_bytes— Crescimento do tamanho do banco de dados ao longo do tempo para planejamento de capacidade.
  • pg_locks_count— Contenção de bloqueio. Alerta sobre bloqueios de espera excessivos.
  • pg_stat_statements_calls/mean_time— Consulta estatísticas de desempenho para otimização.
  • patroni_postgres_running— Estado de saúde do Patroni (1 = em execução, 0 = inativo).
  • patroni_master— Qual pod é o primário atual (1 = mestre, 0 = réplica).
  • pg_up— Sonda básica de disponibilidade do PostgreSQL.
Regras de alerta

# PrometheusRule for PostgreSQL alerts
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: postgres-alerts
  namespace: databases
spec:
  groups:
  - name: postgresql.rules
    rules:
    - alert: PostgreSQLDown
      expr: pg_up == 0
      for: 1m
      labels:
        severity: critical
      annotations:
        summary: "PostgreSQL instance {{ $labels.instance }} is down"
    - alert: PostgreSQLReplicationLag
      expr: pg_stat_replication_pg_wal_lsn_diff > 100000000
      for: 5m
      labels:
        severity: warning
      annotations:
        summary: "Replication lag is {{ $value }} bytes on {{ $labels.instance }}"
    - alert: PostgreSQLHighConnections
      expr: sum(pg_stat_activity_count) by (instance) > 180
      for: 5m
      labels:
        severity: warning
      annotations:
        summary: "{{ $value }} active connections on {{ $labels.instance }}"
    - alert: PostgreSQLDeadlocks
      expr: rate(pg_stat_database_deadlocks[5m]) > 0
      for: 1m
      labels:
        severity: warning
      annotations:
        summary: "Deadlocks detected on {{ $labels.datname }}"
    - alert: PatroniFailover
      expr: changes(patroni_master[5m]) > 0
      labels:
        severity: critical
      annotations:
        summary: "Patroni failover occurred in cluster {{ $labels.cluster }}"
Guia de ajuste de produção

O ajuste adequado é essencial para extrair o máximo desempenho da PostgreSQL na Kubernetes. Os parâmetros a seguir devem ser ajustados com base nos limites de recursos do pod e nas características da carga de trabalho.

Configuração de memória

# For a pod with 16GB memory limit:
postgresql:
  parameters:
    # shared_buffers: 25% of total memory
    shared_buffers: "4GB"

    # effective_cache_size: 75% of total memory
    # (tells planner how much OS cache to expect)
    effective_cache_size: "12GB"

    # work_mem: shared_buffers / (max_connections * 2)
    # Conservative to prevent OOM
    work_mem: "10MB"

    # maintenance_work_mem: 5-10% of total memory
    # Used for VACUUM, CREATE INDEX, ALTER TABLE
    maintenance_work_mem: "1GB"

    # temp_buffers: memory for temp tables per session
    temp_buffers: "32MB"

    # huge_pages: try to use huge pages (requires OS config)
    huge_pages: "try"

WAL e configuração de ponto de verificação

postgresql:
  parameters:
    # WAL settings
    wal_buffers: "64MB"           # 1/32 of shared_buffers, max 64MB
    wal_compression: "zstd"        # Compress WAL (PG 15+)
    max_wal_size: "8GB"            # Before forced checkpoint
    min_wal_size: "2GB"            # WAL disk reservation
    wal_level: "replica"           # Required for replication

    # Checkpoint settings
    checkpoint_completion_target: "0.9"  # Spread I/O over 90% of interval
    checkpoint_timeout: "15min"          # Max time between checkpoints
Planejador de consultas e E/S

postgresql:
  parameters:
    # Cost parameters for SSD storage
    random_page_cost: "1.1"          # SSD: close to seq_page_cost
    seq_page_cost: "1.0"             # Sequential I/O baseline
    effective_io_concurrency: "200"   # Concurrent I/O for SSD

    # Planner behavior
    default_statistics_target: "200"  # More accurate statistics
    from_collapse_limit: 12           # JOIN planning threshold
    join_collapse_limit: 12           # JOIN planning threshold

    # Parallel queries
    max_parallel_workers_per_gather: "4"
    max_parallel_workers: "8"
    max_parallel_maintenance_workers: "4"
    parallel_tuple_cost: "0.01"
    parallel_setup_cost: "1000"
Conexão e registro do

postgresql:
  parameters:
    # Connection limits
    max_connections: "200"                   # Keep low, use PgBouncer
    superuser_reserved_connections: "5"       # Reserve for admin access

    # Logging for troubleshooting
    log_statement: "ddl"                     # Log DDL statements
    log_min_duration_statement: "500"         # Log queries > 500ms
    log_checkpoints: "on"                    # Log checkpoint activity
    log_connections: "off"                   # Too noisy in production
    log_disconnections: "off"                # Too noisy in production
    log_lock_waits: "on"                     # Log lock waits
    log_temp_files: "0"                      # Log all temp file usage
    log_autovacuum_min_duration: "1000"       # Log slow autovacuum

    # Statement timeouts
    statement_timeout: "60000"               # 60 second query timeout
    lock_timeout: "30000"                    # 30 second lock timeout
    idle_in_transaction_session_timeout: "600000"  # 10 min idle txn timeout
Atualizações contínuas e atualizações de versão do

Atualizações de versão secundária do

As atualizações de versão secundária do

(por exemplo, 16.2 para 16.3) são tratadas automaticamente pelo operador quando você atualiza a tag de imagem do Spilo. O operador executa uma reinicialização contínua:

# Update the operator configuration to use a new Spilo image
helm upgrade postgres-operator postgres-operator-charts/postgres-operator \
  --namespace postgres-operator \
  --set configGeneral.docker_image=ghcr.io/zalando/spilo-16:3.1-p1 \
  --reuse-values

# The operator will perform rolling updates:
# 1. Restart replicas one at a time
# 2. Failover the primary to a freshly updated replica
# 3. Restart the old primary (now a replica)
Atualizações de versão principal do

As principais atualizações de versão (por exemplo, PostgreSQL 15 a 16) exigem um planejamento mais cuidadoso. A operadora Zalando oferece suporte a grandes atualizações locais usandopg_upgrade:

# Step 1: Update the CRD to the new major version
spec:
  postgresql:
    version: "16"  # Changed from "15"

# Step 2: The operator detects the version change and:
# a) Scales down the StatefulSet to 1 replica
# b) Runs pg_upgrade on the primary pod
# c) Scales back up to the desired numberOfInstances
# d) Replicas are rebuilt from the upgraded primary

# Step 3: Verify the upgrade
kubectl exec -it pg-production-cluster-0 -n databases -- \
  su postgres -c "psql -c 'SELECT version()'"

# Step 4: Run ANALYZE to update statistics after upgrade
kubectl exec -it pg-production-cluster-0 -n databases -- \
  su postgres -c "psql -c 'ANALYZE VERBOSE'"

Considerações importantes para atualizações importantes:

  • Sempre faça um novo backup antes de atualizar o
  • Teste a atualização em um cluster clonado primeiro
  • As principais atualizações requerem tempo de inatividade (normalmente de 5 a 30 minutos, dependendo do tamanho do banco de dados)
  • Revise as notas de lançamento do PostgreSQL para alterações significativas
  • Monitore o atraso na replicação após a reconstrução da réplica
  • ExecuteANALYZEem todos os bancos de dados para regenerar estatísticas do planejador de consultas
Padrões operacionais avançados

Backups lógicos

Além dos backups físicos WAL-G, a operadora suporta backups lógicos usandopg_dump. Os backups lógicos são úteis para migrações entre versões e restaurações seletivas de tabelas:

# Enable logical backups in the operator configuration
helm upgrade postgres-operator postgres-operator-charts/postgres-operator \
  --namespace postgres-operator \
  --set configLogicalBackup.logical_backup_schedule="0 3 * * *" \
  --set configLogicalBackup.logical_backup_s3_bucket="my-pg-logical-backups" \
  --set configLogicalBackup.logical_backup_s3_region="us-east-1" \
  --set configLogicalBackup.logical_backup_s3_sse="AES256" \
  --reuse-values

# The operator creates a CronJob for each cluster that:
# 1. Connects to the primary PostgreSQL instance
# 2. Runs pg_dumpall (or pg_dump per database)
# 3. Compresses and uploads to S3
Variáveis de ambiente de pod personalizado

Você pode injetar variáveis de ambiente em pods Spilo usando um ConfigMap. Isso é útil para configurar WAL-G, scripts personalizados ou ajustar parâmetros de nível de sistema operacional:

apiVersion: v1
kind: ConfigMap
metadata:
  name: postgres-pod-config
  namespace: databases
data:
  # Custom Spilo configurations
  SPILO_CONFIGURATION: |
    bootstrap:
      dcs:
        ttl: 30
        loop_wait: 10
        retry_timeout: 10
        maximum_lag_on_failover: 33554432
        postgresql:
          use_pg_rewind: true
          use_slots: true
          parameters:
            archive_mode: "on"
            archive_timeout: 1800s
  # Enable pg_stat_statements
  POSTGRESQL_SHARED_PRELOAD_LIBRARIES: "bg_mon,pg_stat_statements,pgextwlist,pg_auth_mon,set_user,timescaledb,pg_cron,pg_stat_kcache"
  # Cron jobs inside PostgreSQL
  ENABLE_PG_CRON: "true"
Políticas de rede

para segurança

Na produção, restrinja o acesso à rede aos pods PostgreSQL usando Kubernetes NetworkPolicies:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: postgres-network-policy
  namespace: databases
spec:
  podSelector:
    matchLabels:
      application: spilo
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: app-namespace
    - podSelector:
        matchLabels:
          app: backend
    ports:
    - protocol: TCP
      port: 5432
    - protocol: TCP
      port: 8008   # Patroni REST API
  - from:
    - namespaceSelector:
        matchLabels:
          name: monitoring
    ports:
    - protocol: TCP
      port: 9187   # Prometheus exporter
  egress:
  - to:
    - ipBlock:
        cidr: 0.0.0.0/0
    ports:
    - protocol: TCP
      port: 443    # S3/GCS/Azure for backups

Solução de problemas comuns

Mesmo com a automação, surgem problemas. Aqui estão os problemas mais comuns e suas soluções ao executar o PostgreSQL com o operador Zalando:

1. Pod preso em estado pendente

# Check events for the pod
kubectl describe pod pg-production-cluster-0 -n databases

# Common causes:
# - No nodes with matching tolerations/affinity
# - Insufficient CPU or memory on nodes
# - PVC cannot be provisioned (check StorageClass)

# Fix: Check node resources and storage availability
kubectl get nodes -o custom-columns=NAME:.metadata.name,CPU:.status.allocatable.cpu,MEM:.status.allocatable.memory
kubectl get pvc -n databases

2. Crescimento do atraso de replicação

# Check replication status on the primary
kubectl exec -it pg-production-cluster-0 -n databases -- \
  su postgres -c "psql -c 'SELECT client_addr, state, sent_lsn, write_lsn, flush_lsn, replay_lsn, write_lag, flush_lag, replay_lag FROM pg_stat_replication'"

# Common causes:
# - Replica CPU/IO saturation
# - Network bandwidth limits
# - Long-running queries on replica blocking WAL replay
# - Insufficient wal_keep_size

# Fix: Check replica resources and cancel blocking queries
kubectl exec -it pg-production-cluster-1 -n databases -- \
  su postgres -c "psql -c 'SELECT pg_cancel_backend(pid) FROM pg_stat_activity WHERE state = \"active\" AND query_start < now() - interval \"5 minutes\"'"

3. Failover não acionando

# Check Patroni cluster status
kubectl exec -it pg-production-cluster-0 -n databases -- \
  su postgres -c "patronictl list"

# Check Patroni logs
kubectl logs pg-production-cluster-0 -n databases -c postgres | grep -i patroni

# Manual failover (if auto-failover is stuck)
kubectl exec -it pg-production-cluster-0 -n databases -- \
  su postgres -c "patronictl failover --candidate pg-production-cluster-1 --force"

4. Falhas de backup

# Check WAL-G backup status
kubectl exec -it pg-production-cluster-0 -n databases -- \
  su postgres -c "envdir /run/etc/wal-e.d/env wal-g backup-list"

# Check backup CronJob logs
kubectl logs -l application=spilo,cluster-name=pg-production-cluster -n databases | grep -i wal-g

# Verify S3/GCS credentials
kubectl exec -it pg-production-cluster-0 -n databases -- \
  su postgres -c "envdir /run/etc/wal-e.d/env aws s3 ls s3://my-pg-backups/"
Práticas recomendadas de segurança

Proteger PostgreSQL em Kubernetes requer uma abordagem de defesa profunda:

  • Criptografia TLS— Habilite SSL para todas as conexões de cliente. O operador pode provisionar certificados automaticamente usando o cert-manager.
  • Gerenciamento de segredos— Use segredos Kubernetes (ou gerenciadores de segredos externos como o Vault) para credenciais de banco de dados. Nunca armazene senhas no ConfigMaps.
  • RBAC— Limita as permissões da ServiceAccount do operador. Use o acesso com privilégios mínimos para usuários do banco de dados do aplicativo.
  • NetworkPolicies— Restrinja a comunicação entre pods conforme mostrado na seção anterior.
  • pg_hba.conf— Configure a autenticação baseada em host para restringir quais IPs e usuários podem se conectar.
  • Registro de auditoria— Habilite a extensãopgauditpara registro de auditoria SQL em ambientes regulamentados.
  • Armazenamento criptografado— Use StorageClasses criptografadas (criptografia EBS, criptografia de disco Azure, etc.).
  • Pads de segurança de pod— Execute pods Spilo como não-root com contextos de segurança restritos.
# Security-hardened CRD settings
spec:
  spiloRunAsUser: 101
  spiloRunAsGroup: 103
  spiloFSGroup: 103
  enableShmVolume: true
  patroni:
    pg_hba:
    - hostssl all all 0.0.0.0/0 md5
    - host    replication standby all md5
    - hostssl replication standby all md5
  postgresql:
    parameters:
      ssl: "on"
      ssl_min_protocol_version: "TLSv1.3"
      password_encryption: "scram-sha-256"
  additionalVolumes:
  - name: postgres-tls
    mountPath: /tls
    secret:
      secretName: pg-tls-cert
      defaultMode: 0640
Planejamento e dimensionamento de capacidade

O dimensionamento adequado garante desempenho estável e economia. Use estas diretrizes como ponto de partida e ajuste com base nos dados de monitoramento de carga de trabalho:

Carga de trabalhoMemóriaArmazenamentoInstânciasDesenvolvimentoSSDSSDSSDSSD
CPU
500m1Gi10Gi1
Pequena Produção2 núcleos8Gi50Gi3
Média Produção4 núcleos16Gi200Gi3
Grande Produção8 núcleos32Gi500Gi5
Empresarial / Análise16+ núcleos64Gi+1Ti+5+

Exemplo completo de implantação ponta a ponta

Vamos juntar tudo com uma implantação completa do zero em um novo cluster Kubernetes:

# Step 1: Create namespace and configure storage
kubectl create namespace databases
kubectl create namespace postgres-operator

# Step 2: Install the Zalando Postgres Operator
helm repo add postgres-operator-charts \
  https://opensource.zalando.com/postgres-operator/charts/postgres-operator
helm repo update

helm install postgres-operator postgres-operator-charts/postgres-operator \
  --namespace postgres-operator \
  --set configKubernetes.enable_pod_antiaffinity=true \
  --set configKubernetes.pod_environment_configmap=databases/postgres-pod-config

# Step 3: Create backup configuration
kubectl apply -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: postgres-pod-config
  namespace: databases
data:
  USE_WALG_BACKUP: "true"
  USE_WALG_RESTORE: "true"
  WALG_S3_PREFIX: "s3://my-pg-backups/\$(SCOPE)"
  BACKUP_SCHEDULE: "0 1 * * *"
  BACKUP_NUM_TO_RETAIN: "14"
EOF

# Step 4: Deploy the PostgreSQL cluster
kubectl apply -f - <<EOF
apiVersion: acid.zalan.do/v1
kind: postgresql
metadata:
  name: pg-app-cluster
  namespace: databases
  labels:
    team: platform
spec:
  teamId: "platform"
  volume:
    size: 50Gi
  numberOfInstances: 3
  enableConnectionPooler: true
  enableReplicaConnectionPooler: true
  users:
    app_user:
    - superuser
    - createdb
  databases:
    app_db: app_user
  postgresql:
    version: "16"
    parameters:
      shared_buffers: "2GB"
      work_mem: "64MB"
      effective_cache_size: "6GB"
  resources:
    requests:
      cpu: "2"
      memory: 8Gi
    limits:
      cpu: "4"
      memory: 16Gi
EOF

# Step 5: Wait for cluster readiness
kubectl wait --for=condition=Running postgresql/pg-app-cluster \
  -n databases --timeout=300s

# Step 6: Verify cluster status
kubectl get postgresql -n databases
kubectl get pods -n databases -l cluster-name=pg-app-cluster
kubectl get svc -n databases -l cluster-name=pg-app-cluster

# Step 7: Get connection credentials
export PGPASSWORD=$(kubectl get secret app-user.pg-app-cluster.credentials.postgresql.acid.zalan.do \
  -n databases -o jsonpath='{.data.password}' | base64 -d)

# Step 8: Connect and verify
kubectl run pg-client --rm -it --image=postgres:16 -n databases -- \
  psql -h pg-app-cluster-pooler -U app_user -d app_db -c "SELECT version();"
Conclusão

O operador Zalando Postgres transforma PostgreSQL em Kubernetes de um desafio operacional complexo em uma implantação automatizada e gerenciável. Ao aproveitar o Patroni para failover baseado em consenso, o Spilo para uma imagem de contêiner com baterias, o WAL-G para backup e recuperação contínuos e o PgBouncer para um pool de conexões eficiente, você obtém uma plataforma de banco de dados de nível de produção que funciona de forma consistente em clusters AWS EKS, Azure AKS, Google GKE e k3s bare-metal.

As principais conclusões deste guia são:

  • Automatize tudo— Deixe o operador lidar com o gerenciamento, failover e agendamento de backup do StatefulSet. A intervenção manual deve ser a exceção.
  • Monitore agressivamente— Implante Prometheus e Grafana desde o primeiro dia. Atraso na replicação, contagens de conexões e contenção de bloqueios são seus primeiros sinais de alerta.
  • Planeje para desastres— Configure backups WAL-G, teste o PITR regularmente e mantenha um cluster de espera para cargas de trabalho críticas.
  • Ajuste para sua carga de trabalho— Os parâmetros PostgreSQL padrão são conservadores. Ajuste as configurações de shared_buffers, work_mem e checkpoint com base na alocação de recursos e nos padrões de consulta.
  • Seguro por padrão— Habilite TLS, use autenticação SCRAM-SHA-256, restrinja o acesso à rede e criptografe o armazenamento em repouso.
  • Testar atualizações— Sempre clone seu cluster e teste atualizações de versões principais antes de aplicá-las na produção.

Com essa base abrangente, você está bem equipado para implantar e operar clusters PostgreSQL altamente disponíveis em qualquer plataforma Kubernetes, atendendo aplicações que exigem confiabilidade, desempenho e integridade de dados em escala.