Skip to content

Commit f197e6f

Browse files
committed
docs: import CloudNativePG v1.29.2
1 parent 6feecc3 commit f197e6f

36 files changed

Lines changed: 1293 additions & 94 deletions

website/versioned_docs/version-1.29/appendixes/object_stores.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,26 @@ spec:
168168
[...]
169169
```
170170

171+
:::note
172+
Recent changes to the [boto3 implementation](https://github.com/boto/boto3/issues/4392)
173+
of [Amazon S3 Data Integrity Protections](https://docs.aws.amazon.com/sdkref/latest/guide/feature-dataintegrity.html)
174+
may lead to the `x-amz-content-sha256` error. If you encounter this issue, you
175+
can apply the following workaround by setting specific environment variables at
176+
the cluster level through `spec.env`:
177+
178+
```yaml
179+
apiVersion: postgresql.cnpg.io/v1
180+
kind: Cluster
181+
[...]
182+
spec:
183+
env:
184+
- name: AWS_REQUEST_CHECKSUM_CALCULATION
185+
value: when_required
186+
- name: AWS_RESPONSE_CHECKSUM_VALIDATION
187+
value: when_required
188+
```
189+
:::
190+
171191
### Using Object Storage with a private CA
172192

173193
Suppose you configure an Object Storage provider which uses a certificate

website/versioned_docs/version-1.29/backup.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,12 @@ The schedule `"0 0 0 * * *"` triggers a backup every day at midnight
243243
(00:00:00). In Kubernetes CronJobs, the equivalent expression would be `0 0 * * *`,
244244
since seconds are not supported.
245245

246+
:::warning
247+
The `spec.cluster` field is immutable after creation. To schedule backups
248+
for a different `Cluster`, create a new `ScheduledBackup` resource instead
249+
of updating an existing one.
250+
:::
251+
246252
### Backup Frequency and RTO
247253

248254
:::tip[Hint]

website/versioned_docs/version-1.29/bootstrap.md

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,16 @@ Objects in each list will be processed sequentially.
384384
leaving the cluster incomplete and requiring manual intervention.
385385
:::
386386

387+
:::note
388+
These queries run with the standard `"$user", public` `search_path`, even
389+
though operator-issued connections otherwise pin a fixed `search_path` for
390+
security reasons.
391+
See [Schema resolution and `search_path` hardening](security.md#schema-resolution-and-search_path-hardening)
392+
for details.
393+
Schema-qualify object references if you need them to be independent of the
394+
`search_path`.
395+
:::
396+
387397
:::info[Important]
388398
Ensure the existence of entries inside the ConfigMaps or Secrets specified
389399
in `postInitSQLRefs`, `postInitTemplateSQLRefs`, and
@@ -614,7 +624,7 @@ file on the source PostgreSQL instance:
614624
host replication streaming_replica all md5
615625
```
616626

617-
The following manifest creates a new PostgreSQL 18.3 cluster,
627+
The following manifest creates a new PostgreSQL 18.4 cluster,
618628
called `target-db`, using the `pg_basebackup` bootstrap method
619629
to clone an external PostgreSQL cluster defined as `source-db`
620630
(in the `externalClusters` array). As you can see, the `source-db`
@@ -629,7 +639,7 @@ metadata:
629639
name: target-db
630640
spec:
631641
instances: 3
632-
imageName: ghcr.io/cloudnative-pg/postgresql:18.3-system-trixie
642+
imageName: ghcr.io/cloudnative-pg/postgresql:18.4-system-trixie
633643
634644
bootstrap:
635645
pg_basebackup:
@@ -649,7 +659,7 @@ spec:
649659
```
650660

651661
All the requirements must be met for the clone operation to work, including
652-
the same PostgreSQL version (in our case 18.3).
662+
the same PostgreSQL version (in our case 18.4).
653663

654664
#### TLS certificate authentication
655665

@@ -665,7 +675,7 @@ in the same Kubernetes cluster.
665675
outside the Kubernetes cluster.
666676
:::
667677

668-
The manifest defines a new PostgreSQL 18.3 cluster called `cluster-clone-tls`,
678+
The manifest defines a new PostgreSQL 18.4 cluster called `cluster-clone-tls`,
669679
which is bootstrapped using the `pg_basebackup` method from the `cluster-example`
670680
external cluster. The host is identified by the read/write service
671681
in the same cluster, while the `streaming_replica` user is authenticated
@@ -680,7 +690,7 @@ metadata:
680690
name: cluster-clone-tls
681691
spec:
682692
instances: 3
683-
imageName: ghcr.io/cloudnative-pg/postgresql:18.3-system-trixie
693+
imageName: ghcr.io/cloudnative-pg/postgresql:18.4-system-trixie
684694
685695
bootstrap:
686696
pg_basebackup:

website/versioned_docs/version-1.29/cloudnative-pg.v1.md

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,24 @@ _Appears in:_
429429
| `secret` _[LocalObjectReference](https://pkg.go.dev/github.com/cloudnative-pg/machinery/pkg/api#LocalObjectReference)_ | Name of the secret containing the initial credentials for the<br />owner of the user database. If empty a new secret will be<br />created from scratch | | | |
430430

431431

432+
#### CatalogComponentImage
433+
434+
435+
436+
CatalogComponentImage is a named image entry for a non-PostgreSQL component.
437+
438+
439+
440+
_Appears in:_
441+
442+
- [ImageCatalogSpec](#imagecatalogspec)
443+
444+
| Field | Description | Required | Default | Validation |
445+
| --- | --- | --- | --- | --- |
446+
| `key` _string_ | Key is the unique identifier for this image within the catalog. | True | | MaxLength: 63 <br />Pattern: `^[a-z0-9]([-a-z0-9]*[a-z0-9])?$` <br /> |
447+
| `image` _string_ | Image is the container image reference. | True | | |
448+
449+
432450
#### CatalogImage
433451

434452

@@ -638,6 +656,7 @@ _Appears in:_
638656
| --- | --- | --- | --- | --- |
639657
| `instances` _integer_ | The total number of PVC Groups detected in the cluster. It may differ from the number of existing instance pods. | | | |
640658
| `readyInstances` _integer_ | The total number of ready instances in the cluster. It is equal to the number of ready instance pods. | | | |
659+
| `selector` _string_ | Selector is the serialized form of the label selector that identifies<br />the pods managed by this cluster. Populated by the operator and exposed<br />through the scale sub-resource so an autoscaler (such as HPA or VPA)<br />can discover the managed instance pods. | | | |
641660
| `instancesStatus` _object (keys:[PodStatus](#podstatus), values:string array)_ | InstancesStatus indicates in which status the instances are | | | |
642661
| `instancesReportedState` _object (keys:[PodName](#podname), values:[InstanceReportedState](#instancereportedstate))_ | The reported state of the instances during the last reconciliation loop | | | |
643662
| `managedRolesStatus` _[ManagedRoles](#managedroles)_ | ManagedRolesStatus reports the state of the managed roles in the cluster | | | |
@@ -680,6 +699,7 @@ _Appears in:_
680699
| `onlineUpdateEnabled` _boolean_ | OnlineUpdateEnabled shows if the online upgrade is enabled inside the cluster | | | |
681700
| `image` _string_ | Image contains the image name used by the pods | | | |
682701
| `pgDataImageInfo` _[ImageInfo](#imageinfo)_ | PGDataImageInfo contains the details of the latest image that has run on the current data directory. | | | |
702+
| `targetPgDataImageInfo` _[ImageInfo](#imageinfo)_ | TargetPGDataImageInfo contains the details of the target image for an<br />in-progress major upgrade. It is set before the upgrade Job is created,<br />and cleared on successful completion or when the upgrade is rolled back. | | | |
683703
| `pluginStatus` _[PluginStatus](#pluginstatus) array_ | PluginStatus is the status of the loaded plugins | | | |
684704
| `switchReplicaClusterStatus` _[SwitchReplicaClusterStatus](#switchreplicaclusterstatus)_ | SwitchReplicaClusterStatus is the status of the switch to replica cluster | | | |
685705
| `demotionToken` _string_ | DemotionToken is a JSON token containing the information<br />from pg_controldata such as Database system identifier, Latest checkpoint's<br />TimeLineID, Latest checkpoint's REDO location, Latest checkpoint's REDO<br />WAL file, and Time of latest checkpoint | | | |
@@ -990,7 +1010,7 @@ _Appears in:_
9901010

9911011
| Field | Description | Required | Default | Validation |
9921012
| --- | --- | --- | --- | --- |
993-
| `name` _string_ | The name of the extension, required | True | | MinLength: 1 <br />Pattern: `^[a-z0-9]([-a-z0-9_]*[a-z0-9])?$` <br /> |
1013+
| `name` _string_ | The name of the extension, required. The limit of 59 characters<br />leaves room for the prefix the operator adds when deriving the<br />extension's Kubernetes Volume name (capped at 63 characters). | True | | MaxLength: 59 <br />MinLength: 1 <br />Pattern: `^[a-z0-9]([-a-z0-9_]*[a-z0-9])?$` <br /> |
9941014
| `image` _[ImageVolumeSource](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#imagevolumesource-v1-core)_ | The image containing the extension. | | | |
9951015
| `extension_control_path` _string array_ | The list of directories inside the image which should be added to extension_control_path.<br />If not defined, defaults to "/share". | | | |
9961016
| `dynamic_library_path` _string array_ | The list of directories inside the image which should be added to dynamic_library_path.<br />If not defined, defaults to "/lib". | | | |
@@ -1186,6 +1206,7 @@ _Appears in:_
11861206
| Field | Description | Required | Default | Validation |
11871207
| --- | --- | --- | --- | --- |
11881208
| `images` _[CatalogImage](#catalogimage) array_ | List of CatalogImages available in the catalog | True | | MaxItems: 8 <br />MinItems: 1 <br /> |
1209+
| `componentImages` _[CatalogComponentImage](#catalogcomponentimage) array_ | ComponentImages is a list of named images for components other than PostgreSQL<br />(e.g. pgbouncer). Keys must be unique within a catalog. | | | MaxItems: 32 <br /> |
11891210

11901211

11911212
#### ImageInfo
@@ -1451,7 +1472,7 @@ _Appears in:_
14511472
| Field | Description | Required | Default | Validation |
14521473
| --- | --- | --- | --- | --- |
14531474
| `byStatus` _object (keys:[RoleStatus](#rolestatus), values:string array)_ | ByStatus gives the list of roles in each state | | | |
1454-
| `cannotReconcile` _object (keys:string, values:string array)_ | CannotReconcile lists roles that cannot be reconciled in PostgreSQL,<br />with an explanation of the cause | | | |
1475+
| `cannotReconcile` _object (keys:string, values:string array)_ | CannotReconcile lists roles that cannot be reconciled, with an<br />explanation of the cause. Failures may originate in PostgreSQL<br />(e.g. dropping a role that owns objects) or in Kubernetes (e.g.<br />the referenced password Secret cannot be fetched). | | | |
14551476
| `passwordStatus` _object (keys:string, values:[PasswordState](#passwordstate))_ | PasswordStatus gives the last transaction id and password secret version for each managed role | | | |
14561477

14571478

@@ -2398,7 +2419,7 @@ _Appears in:_
23982419
| `name` _string_ | Name of the role | True | | |
23992420
| `comment` _string_ | Description of the role | | | |
24002421
| `ensure` _[EnsureOption](#ensureoption)_ | Ensure the role is `present` or `absent` - defaults to "present" | | present | Enum: [present absent] <br /> |
2401-
| `passwordSecret` _[LocalObjectReference](https://pkg.go.dev/github.com/cloudnative-pg/machinery/pkg/api#LocalObjectReference)_ | Secret containing the password of the role (if present)<br />If null, the password will be ignored unless DisablePassword is set | | | |
2422+
| `passwordSecret` _[LocalObjectReference](https://pkg.go.dev/github.com/cloudnative-pg/machinery/pkg/api#LocalObjectReference)_ | Secret containing the password of the role (if present).<br />If null, the password will be ignored unless DisablePassword is set.<br />When set, the secret must follow the `kubernetes.io/basic-auth` format<br />and contain both a `username` and a `password` field. | | | |
24022423
| `connectionLimit` _integer_ | If the role can log in, this specifies how many concurrent<br />connections the role can make. `-1` (the default) means no limit. | | -1 | |
24032424
| `validUntil` _[Time](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#time-v1-meta)_ | Date and time after which the role's password is no longer valid.<br />When omitted, the password will never expire (default). | | | |
24042425
| `inRoles` _string array_ | List of one or more existing roles to which this role will be<br />immediately added as a new member. Default empty. | | | |

website/versioned_docs/version-1.29/cnpg_i.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@ TCP gRPC endpoint behind a Service, with **mTLS** for secure communication.
9494
Standalone plugins are discovered dynamically by watching for Services with the
9595
required labels and annotations — no operator restart is needed.
9696
97+
When a standalone plugin's pods are rolled (for example, after upgrading its
98+
image), the operator detects the change through the EndpointSlices backing the
99+
plugin Service and reconciles every cluster using that plugin, so they start
100+
interacting with the new pods promptly instead of waiting for the periodic
101+
resync.
102+
97103
Example Deployment:
98104
99105
```yaml

website/versioned_docs/version-1.29/connection_pooling.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ spec:
5959
The pooler name can't be the same as any cluster name in the same namespace.
6060
:::
6161
62+
:::warning
63+
The `spec.cluster` field is immutable after creation. To point a pooler at
64+
a different `Cluster`, create a new `Pooler` resource instead of updating
65+
an existing one.
66+
:::
67+
6268
This example creates a `Pooler` resource called `pooler-example-rw`
6369
that's strictly associated with the Postgres `Cluster` resource called
6470
`cluster-example`. It points to the primary, identified by the read/write
@@ -192,15 +198,26 @@ GRANT CONNECT ON DATABASE postgres TO cnpg_pooler_pgbouncer;
192198

193199
Create the lookup function for password verification. This function is created
194200
in the `postgres` database with `SECURITY DEFINER` privileges and is used by
195-
PgBouncer’s `auth_query` option:
201+
PgBouncer’s `auth_query` option. Because it runs as the function owner, its
202+
`search_path` is pinned to `pg_catalog, pg_temp` so that the function body
203+
cannot resolve operators or objects through a caller- or
204+
tenant-controlled `search_path`:
196205

197206
```sql
198207
CREATE OR REPLACE FUNCTION public.user_search(uname TEXT)
199208
RETURNS TABLE (usename name, passwd text)
200-
LANGUAGE sql SECURITY DEFINER AS
209+
LANGUAGE sql SECURITY DEFINER
210+
SET search_path = pg_catalog, pg_temp AS
201211
'SELECT usename, passwd FROM pg_catalog.pg_shadow WHERE usename=$1;';
202212
```
203213

214+
:::note
215+
Clusters created with an earlier version of CloudNativePG carry a
216+
`user_search` function without the pinned `search_path`. The operator
217+
recreates the function with the `SET search_path` clause automatically
218+
during reconciliation when the cluster is upgraded.
219+
:::
220+
204221
Restrict and grant permissions on the lookup function:
205222

206223
```sql

website/versioned_docs/version-1.29/database_import.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ As a result, the instructions in this section are suitable for both:
2424
- importing one or more databases from an existing PostgreSQL instance, even
2525
outside Kubernetes
2626
- importing the database from any PostgreSQL version to one that is either the
27-
same or newer, enabling *major upgrades* of PostgreSQL (e.g. from version 13.x
28-
to version 17.x)
27+
same or newer, enabling *major upgrades* of PostgreSQL (e.g. from version 14.x
28+
to version 18.x)
2929

3030
:::warning
3131
When performing major upgrades of PostgreSQL you are responsible for making

website/versioned_docs/version-1.29/declarative_database_management.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ The `Database` object must reference a specific `Cluster`, determining where
7171
the database will be created. It is managed by the cluster's primary instance,
7272
ensuring the database is created or updated as needed.
7373

74+
:::warning
75+
The `spec.cluster` field is immutable after creation. To target a
76+
different `Cluster`, create a new `Database` resource instead of updating
77+
an existing one.
78+
:::
79+
7480
:::info
7581
The distinction between `metadata.name` and `spec.name` allows multiple
7682
`Database` resources to reference databases with the same name across different
@@ -150,6 +156,11 @@ spec:
150156
Deleting this `Database` object will automatically remove the `two` database
151157
from the `cluster-example` cluster.
152158

159+
On a replica cluster the database is read-only, so deleting a `Database` object
160+
releases its finalizer and removes the Kubernetes object without dropping the
161+
PostgreSQL database, even with `databaseReclaimPolicy: delete`. Dropping the
162+
database is left to the primary cluster, which owns it.
163+
153164
### Declaratively Setting `ensure: absent`
154165

155166
To remove a database, set the `ensure` field to `absent` like in the following

website/versioned_docs/version-1.29/declarative_hibernation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ $ kubectl cnpg status <cluster-name>
5757
Cluster Summary
5858
Name: cluster-example
5959
Namespace: default
60-
PostgreSQL Image: ghcr.io/cloudnative-pg/postgresql:18.3-system-trixie
60+
PostgreSQL Image: ghcr.io/cloudnative-pg/postgresql:18.4-system-trixie
6161
Primary instance: cluster-example-2
6262
Status: Cluster in healthy state
6363
Instances: 3

website/versioned_docs/version-1.29/declarative_role_management.md

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -179,23 +179,74 @@ stringData:
179179
password: SCRAM-SHA-256$<iteration count>:<salt>$<StoredKey>:<ServerKey>
180180
```
181181

182+
:::warning
183+
The example above uses `stringData:`, where Kubernetes encodes the value
184+
for you, which is the safest path for pre-hashed passwords. If you must
185+
use `data:`, encode the bytes exactly with `printf '%s' "$hash" | base64`
186+
(or `echo -n "$hash" | base64`). A trailing newline from a naive
187+
`echo "$hash" | base64` makes the value miss the SCRAM/MD5 shadow-format
188+
check, so the operator falls back to treating it as cleartext and
189+
re-hashes it, and login stops working.
190+
:::
191+
182192
### Safety when transmitting cleartext passwords
183193

184-
While role passwords are safely managed in Kubernetes using Secrets,
185-
there is still a risk on the PostgreSQL side. If creating/altering a role with
186-
password, PostgreSQL may print the password as part of the query statement
187-
in some `postgres` logs, as mentioned in the [PostgreSQL documentation](https://www.postgresql.org/docs/current/sql-createrole.html):
194+
Role passwords are safely managed in Kubernetes using Secrets, but the
195+
SQL path between the operator and PostgreSQL is also a concern. As noted
196+
in the [PostgreSQL documentation](https://www.postgresql.org/docs/current/sql-createrole.html):
188197

189198
> The password will be transmitted to the server in cleartext, and it might
190199
> also be logged in the client's command history or the server log
191200

192-
CloudNativePG adds a safety layer by temporarily suppressing both statement
193-
logging (`log_statement`) and error statement logging
194-
(`log_min_error_statement`) for any CREATE or ALTER operation on a role with
195-
password, thus preventing leakage in both success and failure scenarios.
201+
CloudNativePG protects this path in two complementary ways:
202+
203+
1. Before emitting `CREATE`/`ALTER ROLE ... PASSWORD '...'`, the operator
204+
SCRAM-SHA-256 encodes any cleartext password operator-side (client-side
205+
from PostgreSQL's point of view). This is the standard PostgreSQL
206+
practice for keeping cleartext out of server logs and extensions like
207+
`pg_stat_statements` or `pgaudit`, and is the same encoding that
208+
`psql \password` and libpq's `PQencryptPasswordConn` perform. The
209+
literal PostgreSQL receives is the SCRAM-SHA-256 verifier stored in
210+
`pg_authid.rolpassword`. Passwords already provided in MD5 or
211+
SCRAM-SHA-256 shadow form are forwarded unchanged.
212+
2. The same `CREATE`/`ALTER ROLE` statements are executed inside a
213+
transaction that temporarily suppresses both statement logging
214+
(`log_statement`) and error statement logging
215+
(`log_min_error_statement`), preventing leakage to the PostgreSQL log
216+
in both success and failure scenarios.
217+
196218
The Status section of the cluster does not print the query statement for any
197219
managed role operation.
198220

221+
#### Opting out of operator-side encoding
222+
223+
If you need PostgreSQL (not the operator) to decide how the password is
224+
hashed (for example, on a cluster running `password_encryption = md5`),
225+
set the annotation `cnpg.io/passwordPassthrough: "enabled"` on the
226+
basic-auth Secret. The operator will then forward the password value
227+
verbatim.
228+
229+
:::warning
230+
The `cnpg.io/passwordPassthrough` annotation must be set on the
231+
**basic-auth Secret** itself, not on the `Cluster` resource. Placing it
232+
on the `Cluster` has no effect, and the operator will continue to apply
233+
SCRAM-SHA-256 encoding to the password before sending it to PostgreSQL.
234+
:::
235+
236+
The opt-in is per-Secret and applies to every basic-auth Secret the
237+
operator consumes (managed-role secrets, but also the superuser and
238+
application-user secrets), so a single cluster can mix passthrough
239+
secrets and operator-encoded secrets freely. The statement-logging
240+
suppression layer described above still applies in both modes.
241+
242+
:::warning
243+
With `cnpg.io/passwordPassthrough: "enabled"`, the operator forwards
244+
the Secret's `password` value verbatim. If that value is cleartext (the
245+
common case on a `password_encryption = md5` cluster), extensions such
246+
as `pg_stat_statements` or `pgaudit` will observe it. This is the
247+
expected trade-off for letting PostgreSQL choose the hash format.
248+
:::
249+
199250
## Unrealizable role configurations
200251

201252
In PostgreSQL, in some cases, commands cannot be honored by the database and

0 commit comments

Comments
 (0)