Merge branch 'master' into gh-pages

This commit is contained in:
Felix Kunde
2026-07-28 00:55:23 +02:00
184 changed files with 17953 additions and 9396 deletions
+104 -25
View File
@@ -65,7 +65,10 @@ the `PGVERSION` environment variable is set for the database pods. Since
In-place major version upgrades can be configured to be executed by the
operator with the `major_version_upgrade_mode` option. By default, it is
enabled (mode: `manual`). In any case, altering the version in the manifest
will trigger a rolling update of pods to update the `PGVERSION` env variable.
will update the desired `PGVERSION`. If `maintenanceWindows` are configured,
major-version-related pod rotation is deferred until the next maintenance
window. Without maintenance windows, the operator will trigger a rolling
update of pods to apply the new `PGVERSION`.
Spilo's [`configure_spilo`](https://github.com/zalando/spilo/blob/master/postgres-appliance/scripts/configure_spilo.py)
script will notice the version mismatch but start the current version again.
@@ -92,10 +95,11 @@ Thus, the `full` mode can create drift between desired and actual state.
### Upgrade during maintenance windows
When `maintenanceWindows` are defined in the Postgres manifest the operator
will trigger a major version upgrade only during these periods. Make sure they
are at least twice as long as your configured `resync_period` to guarantee
that operator actions can be triggered.
When `maintenanceWindows` are defined in the Postgres manifest or in the global
config the operator will trigger major-version-related pod rotation and the
major version upgrade only during these periods. Make sure they are at least
twice as long as your configured `resync_period` to guarantee that operator
actions can be triggered.
### Upgrade annotations
@@ -635,9 +639,11 @@ masters in single-node clusters and/or the last remaining running instance in a
cluster.
## PDB for critical operations
The `MinAvailable` parameter of this PDB is equal to the `numberOfInstances` set in the
cluster manifest, while label selector includes `critical-operation=true` condition. This
allows to protect all pods of a cluster, given they are labeled accordingly.
The `MaxUnavailable` parameter of this PDB is set to `0`, while label selector includes
`critical-operation=true` condition. This blocks voluntary disruptions for all pods of a
cluster that are labeled accordingly, without leaving an unsatisfiable budget behind when
no pods carry the label (which previously kept monitoring alerts like
`KubePdbNotEnoughHealthyPods` firing permanently).
For example, Operator labels all Spilo pods with `critical-operation=true` during the major
version upgrade run. You may want to protect cluster pods during other critical operations
by assigning the label to pods yourself or using other means of automation.
@@ -647,7 +653,14 @@ The PDB is only relaxed in two scenarios:
* If a cluster is scaled down to `0` instances (e.g. for draining nodes)
* If the PDB is disabled in the configuration (`enable_pod_disruption_budget`)
The PDBs are still in place having `MinAvailable` set to `0`. Disabling PDBs
The PDBs are still in place but fully relaxed: the primary PDB with `MinAvailable`
set to `0` and the critical operations PDB with `MaxUnavailable` set to `100%`.
The two PDBs intentionally use different budget fields matching their purposes:
the primary PDB guarantees a minimum count of always-present pods
(`MinAvailable`), while the critical operations PDB freezes disruptions for
whatever pods currently carry the `critical-operation=true` label - a
usually-empty set, which `MaxUnavailable: 0` expresses without producing an
unsatisfiable budget while idle. Disabling PDBs
helps avoiding blocking Kubernetes upgrades in managed K8s environments at the
cost of prolonged DB downtime. See PR [#384](https://github.com/zalando/postgres-operator/pull/384)
for the use case.
@@ -721,9 +734,9 @@ that cannot be overridden to guarantee core functionality. Only variables with
shipping to be specified differently. There are three ways to specify extra
environment variables (or override existing ones) for database pods:
* [Via ConfigMap](#via-configmap)
* [Via Secret](#via-secret)
* [Via Postgres Cluster Manifest](#via-postgres-cluster-manifest)
* [Globally via ConfigMap](#via-configmap)
* [Globally via Secret](#via-secret)
* [Locally via Postgres Cluster Manifest](#via-postgres-cluster-manifest)
The first two options must be referenced from the operator configuration
making them global settings for all Postgres cluster the operator watches.
@@ -732,10 +745,10 @@ environment variables. Another case could be to provide custom cloud
provider or backup settings.
The last options allows for specifying environment variables individual to
every cluster via the `env` section in the manifest. For example, if you use
individual backup locations for each of your clusters. Or you want to disable
WAL archiving for a certain cluster by setting `WAL_S3_BUCKET`, `WAL_GS_BUCKET`
or `AZURE_STORAGE_ACCOUNT` to an empty string.
every cluster via the `env` or `envFrom` section in the manifest. For example,
if you use individual backup locations for each of your clusters. Or you want
to disable WAL archiving for a certain cluster by setting `WAL_S3_BUCKET`,
`WAL_GS_BUCKET` or `AZURE_STORAGE_ACCOUNT` to an empty string.
The operator will give precedence to environment variables in the following
order (e.g. a variable defined in 4. overrides a variable with the same name
@@ -749,6 +762,9 @@ in 5.):
6. Pod environment config map via operator config
7. WAL and logical backup settings from operator config
The `envFrom` section is treated separately and allows for a very flexible
local configuration referencing a ConfigMap or a Secret.
### Via ConfigMap
The ConfigMap with the additional settings is referenced in the operator's
@@ -887,15 +903,13 @@ cluster manifest. In the case any of these variables are omitted from the
manifest, the operator configuration settings `enable_master_load_balancer` and
`enable_replica_load_balancer` apply. Note that the operator settings affect
all Postgresql services running in all namespaces watched by the operator.
If load balancing is enabled two default annotations will be applied to its
services:
If load balancing is enabled the following default annotation will be applied to
its services:
- `external-dns.alpha.kubernetes.io/hostname` with the value defined by the
operator configs `master_dns_name_format` and `replica_dns_name_format`.
This value can't be overwritten. If any changing in its value is needed, it
MUST be done changing the DNS format operator config parameters; and
- `service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout` with
a default value of "3600".
There are multiple options to specify service annotations that will be merged
with each other and override in the following order (where latter take
@@ -926,6 +940,41 @@ For the `external-dns.alpha.kubernetes.io/hostname` annotation the `-pooler`
suffix will be appended to the cluster name used in the template which is
defined in `master|replica_dns_name_format`.
## Node Ports
Alternatively to Load Balancers Node Ports can be used. Kubernetes services with type
`NodePort` redirect traffic from a specified port on your kubernetes nodes to your service.
To expose your services to an external network with NodePorts you can set `enableMasterNodePort` and/or `enableReplicaNodePort` to `true`
in your cluster manifest. In the case any of these variables are omitted from the manifest, the operator configuration settings `enable_master_node_port` and `enable_replica_node_port` apply.
Note that the operator settings affect all Postgresql services running in all namespaces watched
by the operator.
**Enabling a NodePort configuration will override the corresponding LoadBalancer configuration.**
There are multiple options to specify service annotations that will be merged
with each other and override in the following order (where latter take
precedence):
1. Globally configured `custom_service_annotations`
2. `serviceAnnotations` specified in the cluster manifest
3. `masterServiceAnnotations` and `replicaServiceAnnotations` specified in the cluster manifest
Load-Balancer specific annotations are not applied.
Node port services can also be configured for the [connection pooler](user.md#connection-pooler) pods
with the manifest flags `enableMasterPoolerNodePort` and/or `enableReplicaPoolerNodePort` or in the operator configuration with `enable_master_pooler_node_port`
and/or `enable_replica_pooler_node_port`.
To configure which ports Kubernetes should use for your NodePort service you can configure ports in your cluster manifest
for each type:
- masterNodePort
- masterPoolerNodePort
- replicaNodePort
- replicaPoolerNodePort
When not defined or set to 0 kubernetes will choose a port for you from [your kubernetes cluster's configured range](https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport).
## Running periodic 'autorepair' scans of K8s objects
The Postgres Operator periodically scans all K8s objects belonging to each
@@ -1057,6 +1106,32 @@ configuration:
wal_s3_bucket: your-backup-path
```
Alternatively, if your cluster uses EKS with OIDC, you can use
[IRSA](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html)
(IAM Roles for Service Accounts) instead of kube2iam. Set `irsa_role_arn` to
the full ARN of the IAM role:
**OperatorConfiguration**
```yaml
apiVersion: "acid.zalan.do/v1"
kind: OperatorConfiguration
metadata:
name: postgresql-operator-configuration
configuration:
aws_or_gcp:
aws_region: eu-central-1
irsa_role_arn: arn:aws:iam::123456789012:role/postgres-pod-role
wal_s3_bucket: your-backup-path
```
When `irsa_role_arn` is set the operator annotates the pod service account with
`eks.amazonaws.com/role-arn` on every reconcile. The EKS OIDC webhook then
injects an AWS web identity token into each pod, which takes precedence over
the EC2 metadata credentials used by kube2iam. Both `kube_iam_role` and
`irsa_role_arn` can coexist during a migration — existing pods retain the
kube2iam annotation until they are rotated, at which point only IRSA is used.
The referenced IAM role should contain the following privileges to make sure
Postgres can send compressed WAL files to the given S3 bucket:
@@ -1167,6 +1242,7 @@ aws_or_gcp:
# additional_secret_mount_path: ""
# aws_region: eu-central-1
# kube_iam_role: ""
# irsa_role_arn: ""
# log_s3_bucket: ""
# wal_s3_bucket: ""
wal_gs_bucket: "postgres-backups-bucket-28302F2" # name of bucket on where to save the WAL-E logs
@@ -1216,6 +1292,7 @@ aws_or_gcp:
additional_secret_mount_path: "/var/secrets/google" # or where ever you want to mount the file
# aws_region: eu-central-1
# kube_iam_role: ""
# irsa_role_arn: ""
# log_s3_bucket: ""
# wal_s3_bucket: ""
wal_gs_bucket: "postgres-backups-bucket-28302F2" # name of bucket on where to save the WAL-E logs
@@ -1312,7 +1389,7 @@ aws_or_gcp:
If cluster members have to be (re)initialized restoring physical backups
happens automatically either from the backup location or by running
[pg_basebackup](https://www.postgresql.org/docs/17/app-pgbasebackup.html)
[pg_basebackup](https://www.postgresql.org/docs/18/app-pgbasebackup.html)
on one of the other running instances (preferably replicas if they do not lag
behind). You can test restoring backups by [cloning](user.md#how-to-clone-an-existing-postgresql-cluster)
clusters.
@@ -1346,10 +1423,12 @@ If you are using [additional environment variables](#custom-pod-environment-vari
to access your backup location you have to copy those variables and prepend
the `STANDBY_` prefix for Spilo to find the backups and WAL files to stream.
Alternatively, standby clusters can also stream from a remote primary cluster.
Standby clusters can also stream from a remote primary cluster.
You have to specify the host address. Port is optional and defaults to 5432.
Note, that only one of the options (`s3_wal_path`, `gs_wal_path`,
`standby_host`) can be present under the `standby` top-level key.
You can combine `standby_host` with either `s3_wal_path` or `gs_wal_path`
for additional redundancy. Note that `s3_wal_path` and `gs_wal_path` are
mutually exclusive. At least one of `s3_wal_path`, `gs_wal_path`, or
`standby_host` must be specified under the `standby` top-level key.
## Logical backups
@@ -1498,7 +1577,7 @@ make docker
# build in image in minikube docker env
eval $(minikube docker-env)
docker build -t ghcr.io/zalando/postgres-operator-ui:v1.15.1 .
docker buildx build --load -t ghcr.io/zalando/postgres-operator-ui:v2.0.0 .
# apply UI manifests next to a running Postgres Operator
kubectl apply -f manifests/