CloudNativePG Pooler Configuration#
CloudNativePG provides native connection pooling through the Pooler CRD, which deploys a scalable set of PgBouncer pods between applications and a PostgreSQL cluster . A Pooler is always namespace-scoped to the same namespace as its target Cluster, and its lifecycle is independent — deleting the cluster does not remove the pooler and vice versa .
Prerequisite: PgBouncer version 1.19+ is required because CloudNativePG relies on the
auth_dbnamefeature introduced in that release .
Entry points:
- API types:
api/v1/pooler_types.go—PoolerSpec,PgBouncerSpec,PoolerStatus - Helper methods:
api/v1/pooler_funcs.go—IsAutomatedIntegration,IsMetricsTLSEnabled, TLS secret resolution - Admission webhook:
internal/webhook/v1/pooler_webhook.go— validation logic - Official docs:
docs/src/connection_pooling.md
Key API Fields (PgBouncerSpec)#
The spec.pgbouncer block (type PgBouncerSpec) is required. Key fields:
| Field | Default | Purpose |
|---|---|---|
poolMode | session | session or transaction pooling mode |
serverTLSSecret | — | PgBouncer's server_tls_key_file / server_tls_cert_file for connecting to PostgreSQL |
serverCASecret | — | server_tls_ca_file — root CA to validate PostgreSQL certs |
clientTLSSecret | — | client_tls_key_file / client_tls_cert_file — for accepting client connections |
clientCASecret | — | client_tls_ca_file — root CA to validate client certs |
authQuerySecret | — | Deprecated. Secret for the auth query user |
authQuery | SELECT usename, passwd FROM public.user_search($1) | Custom SQL for PgBouncer's auth_query |
parameters | — | Free-form PgBouncer parameters (validated against an allowlist — see Webhook section) |
pg_hba | — | Extra HBA lines appended to pg_hba.conf |
paused | false | Issues PgBouncer PAUSE; transitions pooler to Paused phase |
image / imageCatalogRef | — | Mutually exclusive ways to pin the PgBouncer container image |
spec.type targets the cluster service: rw (primary), ro (replicas), or r (all instances), defaulting to rw . spec.instances defaults to 1 . The spec.cluster reference is immutable after creation .
Automated vs. Manual Integration#
The operator distinguishes two modes via IsAutomatedIntegration():
- Automated (default): No
authQuery,authQuerySecret, orserverTLSSecretset. The operator fully manages the auth user, certificates, and lookup function. - Manual: Any of those three fields is set. The operator steps back and the user takes full responsibility for authentication setup. An admission warning is emitted in this case .
What automated integration provisions#
The operator automatically :
- Creates the
cnpg_pooler_pgbouncerPostgreSQL role - Creates the
public.user_search()function in thepostgresdatabase (with a pinnedsearch_pathfor security) - Issues a TLS certificate for that role
- Configures PgBouncer to use
cnpg_pooler_pgbouncerasauth_userandpostgresasauth_dbname - Cleans up everything when no poolers reference the cluster
The default auth query is SELECT usename, passwd FROM public.user_search($1) , and the auth secret name falls back to <cluster-name>-pooler (suffix -pooler) .
TLS: Certificates#
By default, PgBouncer reuses the cluster's own certificates :
- Server side (PgBouncer → PostgreSQL): falls back to
""(no custom secret; managed by the cluster) viaGetServerTLSSecretName(). The server CA falls back to the cluster's server CA viaGetServerCASecretNameOrDefault(). - Client side (application → PgBouncer):
clientTLSSecretfalls back to the cluster's server TLS secret viaGetClientTLSSecretNameOrDefault(). The client CA falls back to the cluster's client CA viaGetClientCASecretNameOrDefault().
Supported secret formats for custom secrets: Basic Auth, TLS, or Opaque (with keys tls.crt and tls.key) .
Important: Supplying your own
serverTLSSecret(orauthQuerySecret/authQuery) disables automated integration . You are then solely responsible for authentication configuration.
Admission Webhook Validation#
The PoolerCustomValidator (registered at /validate-postgresql-cnpg-io-v1-pooler) fires on create and update with failurePolicy=fail . It runs three validation passes :
1. PgBouncer config validation (validatePgBouncer)#
spec.pgbounceris required .authQuerySecret/serverTLSSecretandauthQuerymust be set together — each requires the other .- All keys in
spec.pgbouncer.parametersmust appear inAllowedPgbouncerGenericConfigurationParameters— an explicit allowlist of ~50 PgBouncer settings. Unknown parameters are rejected asInvalid.
2. Cluster reference validation (validateCluster)#
spec.cluster.namemust be non-empty and must not match the pooler's own name .
3. Monitoring TLS validation (validateMonitoring)#
- When
spec.monitoring.tls.enabled=trueandspec.monitoring.enablePodMonitor=true, aclientTLSSecretis required . Without it, the metrics endpoint would present the cluster's certificate (whose SANs cover cluster services, not the pooler), which is surfaced as a configuration error at admission time.
Admission warnings (non-blocking)#
- Manual integration mode emits a warning that the operator won't handle cluster integration .
- Use of the deprecated
authQuerySecretfield emits a deprecation warning . - Use of deprecated
spec.monitoringfields (e.g.,enablePodMonitor, relabeling configs) emits a warning to migrate to a manually createdPodMonitor.
Lifecycle & Status#
The Pooler progresses through four phases :
| Phase | Meaning |
|---|---|
active | Running normally, serving traffic |
paused | PgBouncer running but holding new connections (spec.pgbouncer.paused=true) |
inactive | Blocked on a missing prerequisite (cluster, secret, certificate); retries periodically |
failed | Configuration error prevents reconciliation |
status.phaseReason provides a human-readable explanation. status.secrets tracks ResourceVersions of all referenced TLS and auth secrets, enabling the controller to detect secret rotations. status.error records the latest admission validation error .
Helm Chart Support#
The cloudnative-pg/charts cluster chart renders Pooler resources from the poolers values array . Each entry supports name, instances, type, poolMode, authQuerySecret, authQuery, parameters, pg_hba, and template. TLS secret fields (serverTLSSecret, clientTLSSecret, etc.) are not yet surfaced in the chart template and must be added via the raw template escape hatch or a separate Pooler manifest.