Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ KubeBlocks add-ons.
| orchestrator | orchestrator-3.2.6 | Orchestrator is a MySQL high availability and replication management tool, runs as a service and provides command line access, HTTP API and Web interface. | ApeCloud |
| orioledb | orioledb-16.4.0 | OrioleDB is a new storage engine for PostgreSQL, bringing a modern approach to database capacity, capabilities and performance to the world's most-loved database platform. | ApeCloud |
| polardbx | polardbx-cdc-2.3.0<br>polardbx-cn-2.3.0<br>polardbx-dn-2.3.0<br>polardbx-gms-2.3.0 | PolarDB-X is a cloud native distributed SQL Database designed for high concurrency, massive storage, complex querying scenarios. | ApeCloud Vettal Wu |
| postgresql | postgresql-12.14.0<br>postgresql-12.14.1<br>postgresql-12.15.0<br>postgresql-12.22.0<br>postgresql-13.23.0<br>postgresql-14.18.0<br>postgresql-14.23.0<br>postgresql-14.7.2<br>postgresql-14.8.0<br>postgresql-15.13.0<br>postgresql-15.18.0<br>postgresql-15.7.0<br>postgresql-16.14.0<br>postgresql-16.4.0<br>postgresql-16.9.0<br>postgresql-17.10.0<br>postgresql-17.5.0<br>postgresql-18.1.0<br>postgresql-18.4.0 | A PostgreSQL (with Patroni HA) cluster definition Helm chart for Kubernetes | ldming dingshun-cmss |
| postgresql | pgbouncer-1.25.2<br>postgresql-12.14.0<br>postgresql-12.14.1<br>postgresql-12.15.0<br>postgresql-12.22.0<br>postgresql-13.23.0<br>postgresql-14.18.0<br>postgresql-14.23.0<br>postgresql-14.7.2<br>postgresql-14.8.0<br>postgresql-15.13.0<br>postgresql-15.18.0<br>postgresql-15.7.0<br>postgresql-16.14.0<br>postgresql-16.4.0<br>postgresql-16.9.0<br>postgresql-17.10.0<br>postgresql-17.5.0<br>postgresql-18.1.0<br>postgresql-18.4.0 | A PostgreSQL (with Patroni HA) cluster definition Helm chart for Kubernetes | ldming dingshun-cmss |
| pulsar | pulsar-bookies-recovery-2.11.2<br>pulsar-bookies-recovery-3.0.2<br>pulsar-bookies-recovery-4.0.6<br>pulsar-bookkeeper-2.11.2<br>pulsar-bookkeeper-3.0.2<br>pulsar-bookkeeper-4.0.6<br>pulsar-broker-2.11.2<br>pulsar-broker-3.0.2<br>pulsar-broker-4.0.6<br>pulsar-proxy-2.11.2<br>pulsar-proxy-3.0.2<br>pulsar-proxy-4.0.6<br>pulsar-zookeeper-2.11.2<br>pulsar-zookeeper-3.0.2 | Apache Pulsar is an open-source, distributed messaging and streaming platform built for the cloud. | cjc7373 caiq1nyu |
| qdrant | qdrant-1.10.0<br>qdrant-1.13.4<br>qdrant-1.15.4<br>qdrant-1.15.5<br>qdrant-1.16.3<br>qdrant-1.17.1<br>qdrant-1.18.2<br>qdrant-1.19.0<br>qdrant-1.5.0<br>qdrant-1.7.3<br>qdrant-1.8.1<br>qdrant-1.8.4 | High-performance, massive-scale Vector Database for the next generation of AI. | cjc7373 |
| rabbitmq | rabbitmq-3.10.25<br>rabbitmq-3.11.28<br>rabbitmq-3.12.14<br>rabbitmq-3.13.7<br>rabbitmq-3.8.34<br>rabbitmq-3.9.29<br>rabbitmq-4.0.9<br>rabbitmq-4.1.6<br>rabbitmq-4.2.1<br>rabbitmq-4.3.1 | RabbitMQ is a reliable and mature messaging and streaming broker. | xuriwuyun |
Expand Down
2 changes: 1 addition & 1 deletion addons-cluster/postgresql/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
apiVersion: v2
name: postgresql-cluster
type: application
version: 1.0.5
version: 1.0.6
description: A PostgreSQL (with Patroni HA) cluster Helm chart for KubeBlocks.

dependencies:
Expand Down
2 changes: 1 addition & 1 deletion addons/postgresql/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: A PostgreSQL (with Patroni HA) cluster definition Helm chart for Ku

type: application

version: 1.0.5
version: 1.0.6

# The helm chart contains multiple kernel versions of PostgreSQL (with Patroni HA),
# appVersion should be consistent with the highest PostgreSQL (with Patroni HA) kernel version.
Expand Down
177 changes: 177 additions & 0 deletions addons/postgresql/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ PostgreSQL (Postgres) is an open source object-relational database known for rel
|------------------|------------------------|-----------------------|-------------------|-----------|------------|-----------|--------|------------|
| replication | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |

The `replication` topology includes a managed, stateless PgBouncer component.
An omitted PgBouncer component has zero replicas. At zero replicas, clients
connect directly to PostgreSQL on 5432. One or more replicas activate the
pooled endpoint on 6432 while the Cluster keeps the same topology.

### Backup and Restore

| Feature | Method | Description |
Expand Down Expand Up @@ -166,6 +171,178 @@ NAME VERSIONS
postgresql 18.4.0,18.1.0,17.10.0,17.5.0,16.14.0,16.9.0,16.4.0,15.18.0,15.13.0,15.7.0,14.23.0,14.18.0,14.8.0,14.7.2,13.23.0,12.22.0,12.15.0,12.14.1,12.14.0 Available Xd
```

### PgBouncer connection pool

The managed component runs PgBouncer 1.25.2. Zero replicas keep client traffic
on the direct PostgreSQL endpoint. One or more replicas activate the managed
pool. The default PgBouncer resources are 100m CPU and 128Mi memory requests,
with 500m CPU and 512Mi memory limits.

#### Enable and disable

To activate PgBouncer when creating a Cluster, add it to the `replication`
topology:

```yaml
apiVersion: apps.kubeblocks.io/v1
kind: Cluster
metadata:
name: pg-cluster
namespace: demo
spec:
clusterDef: postgresql
topology: replication
terminationPolicy: Delete
componentSpecs:
- name: postgresql
serviceVersion: "14.23.0"
replicas: 2
resources:
requests: {cpu: "500m", memory: 512Mi}
limits: {cpu: "500m", memory: 512Mi}
volumeClaimTemplates:
- name: data
spec:
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 20Gi
- name: pgbouncer
replicas: 2
resources:
requests: {cpu: "100m", memory: 128Mi}
limits: {cpu: "500m", memory: 512Mi}
```

For a Cluster that already contains the `pgbouncer` component, activate two
replicas with a HorizontalScaling OpsRequest:

```yaml
apiVersion: operations.kubeblocks.io/v1alpha1
kind: OpsRequest
metadata:
name: pg-pgbouncer-enable
namespace: demo
spec:
clusterName: pg-cluster
type: HorizontalScaling
horizontalScaling:
- componentName: pgbouncer
scaleOut:
replicaChanges: 2
```

Return the component to zero replicas with a second HorizontalScaling
OpsRequest:

```yaml
apiVersion: operations.kubeblocks.io/v1alpha1
kind: OpsRequest
metadata:
name: pg-pgbouncer-disable
namespace: demo
spec:
clusterName: pg-cluster
type: HorizontalScaling
horizontalScaling:
- componentName: pgbouncer
scaleIn:
replicaChanges: 2
```

Clusters created with Addon 1.0.5 retain their in-Pod PgBouncer sidecar. After
upgrading such a Cluster, add the managed `pgbouncer` component at zero replicas
before using the scaling operations above.

#### Connect

The managed endpoint uses the following in-cluster address:

```text
<cluster-name>-pgbouncer.<namespace>.svc:6432
```

For the example Cluster, connect to `pg-cluster-pgbouncer.demo.svc:6432`.
The Service receives endpoints after at least one PgBouncer replica reaches
Ready. Check the endpoint before publishing the address:

```bash
kubectl get endpoints -n demo pg-cluster-pgbouncer
```

#### Configure

PgBouncer starts with the following per-instance settings:

| Parameter | Default | Allowed values | Scope |
|-----------|---------|----------------|-------|
| `pool_mode` | `session` | `session`, `transaction`, `statement` | New client connections |
| `max_client_conn` | `500` | `1..999999` | Client connections per PgBouncer instance |
| `default_pool_size` | `20` | `1..999999` | Backend connections per user/database pool |
| `min_pool_size` | `5` | `0..999999` | Retained backend connections per user/database pool |
| `reserve_pool_size` | `5` | `0..999999` | Reserve connections per user/database pool |
| `max_db_connections` | `80` | `0..999999`; `0` means unlimited | Backend connections per database and PgBouncer instance |
| `max_user_connections` | `80` | `0..999999`; `0` means unlimited | Backend connections per user and PgBouncer instance |

PostgreSQL `max_connections` remains the global connection limit. Review the
PgBouncer settings after changing PostgreSQL capacity, database or user counts,
or the PgBouncer replica count. Also size memory and file descriptors for the
selected client limit.

Apply parameter changes with a Reconfiguring OpsRequest. A successful
OpsRequest means that KubeBlocks accepted and rendered the requested
configuration. The KubeBlocks config manager then makes an asynchronous,
best-effort SIGHUP attempt for each running PgBouncer instance; the OpsRequest
status does not confirm that every instance has completed its reload. Pods are
not restarted by this reload action:

```yaml
apiVersion: operations.kubeblocks.io/v1alpha1
kind: OpsRequest
metadata:
name: pg-pgbouncer-reconfigure
namespace: demo
spec:
type: Reconfiguring
clusterName: pg-cluster
reconfigures:
- componentName: pgbouncer
parameters:
- key: max_client_conn
value: "1000"
- key: default_pool_size
value: "30"
- key: max_db_connections
value: "60"
- key: max_user_connections
value: "40"
```

KubeBlocks validates values against the documented ranges before applying
them.

Configuration propagation and reload complete asynchronously across running
replicas. Confirm that each instance reports the requested values with
PgBouncer `SHOW CONFIG` before relying on new connection limits.

#### Runtime behavior and requirements

- Readiness requires a successful connection through PgBouncer to the writable
PostgreSQL primary. The same PgBouncer Pod becomes Ready automatically after
PostgreSQL recovers.
- Dynamic parameter reload uses the KubeBlocks 1.0 config-manager sidecar with
a shared process namespace and UID 0. The target namespace Pod Security policy
must permit this runtime; use a policy less restrictive than the Kubernetes
Restricted profile. The PgBouncer container continues to run as UID/GID 70
with privilege escalation disabled and all capabilities dropped.
- Applications reconnect with backoff after a PostgreSQL primary change and
retry any interrupted transaction. Transaction and statement pooling modes
also require application compatibility testing.
- TLS-enforced Clusters use the direct PostgreSQL endpoint on 5432 in this
release.
- Clusters using the managed PgBouncer component stay on PostgreSQL Addon 1.0.6
or later.

### Horizontal scaling

#### Scale-out
Expand Down
52 changes: 52 additions & 0 deletions addons/postgresql/config/pgbouncer-config-constraint.cue
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#PgBouncerParameter: {
// Pooling mode used for new client connections.
pool_mode?: "session" | "transaction" | "statement" | *"session"

// Maximum number of client connections accepted by one PgBouncer instance.
max_client_conn?: int & >=1 & <=999999 | *500

// Default number of backend connections for each user/database pool.
default_pool_size?: int & >=1 & <=999999 | *20

// Minimum number of backend connections retained for each user/database pool.
min_pool_size?: int & >=0 & <=999999 | *5

// Additional backend connections allowed when a pool is exhausted.
reserve_pool_size?: int & >=0 & <=999999 | *5

// Maximum number of backend connections to one database per PgBouncer instance. Zero means unlimited.
max_db_connections?: int & >=0 & <=999999 | *80

// Maximum number of backend connections for one user per PgBouncer instance. Zero means unlimited.
max_user_connections?: int & >=0 & <=999999 | *80
}

#PgBouncerConfig: {
#PgBouncerParameter

listen_addr: "*"
listen_port: 6432
unix_socket_dir: "/tmp"
unix_socket_mode: "0770"
auth_file: "/etc/pgbouncer/userlist.txt"
auth_type: "md5"
auth_user: "postgres"
auth_query: "SELECT rolname, CASE WHEN rolvaliduntil IS NOT NULL AND rolvaliduntil < pg_catalog.now() THEN NULL ELSE rolpassword END FROM pg_catalog.pg_authid WHERE rolname=$1 AND rolcanlogin"
auth_dbname: "postgres"
admin_users: "postgres"
stats_users: "postgres"
client_tls_sslmode: "disable"
server_tls_sslmode: "disable"
ignore_startup_parameters: "extra_float_digits"
reserve_pool_timeout: 5
server_idle_timeout: 600
server_lifetime: 3600
query_wait_timeout: 120
client_idle_timeout: 0
}

#PgBouncerConfiguration: {
pgbouncer: #PgBouncerConfig
}

configuration: #PgBouncerConfiguration
36 changes: 21 additions & 15 deletions addons/postgresql/config/pgbouncer-ini.tpl
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
[pgbouncer]
listen_addr = *
listen_port = 6432
unix_socket_dir = /tmp/
unix_socket_mode = 0777
auth_file = /opt/bitnami/pgbouncer/conf/userlist.txt
auth_user = postgres
auth_query = SELECT usename, passwd FROM pg_shadow WHERE usename=$1
pidfile =/opt/bitnami/pgbouncer/tmp/pgbouncer.pid
logfile =/opt/bitnami/pgbouncer/logs/pgbouncer.log
unix_socket_dir = /tmp
unix_socket_mode = 0770
auth_file = /etc/pgbouncer/userlist.txt
auth_type = md5
auth_user = postgres
auth_query = SELECT rolname, CASE WHEN rolvaliduntil IS NOT NULL AND rolvaliduntil < pg_catalog.now() THEN NULL ELSE rolpassword END FROM pg_catalog.pg_authid WHERE rolname=$1 AND rolcanlogin
auth_dbname = postgres
admin_users = postgres
stats_users = postgres
pool_mode = session
client_tls_sslmode = disable
server_tls_sslmode = disable
ignore_startup_parameters = extra_float_digits
{{- $max_client_conn := 10000 }}
{{- $phy_memory := getContainerMemory ( index $.podSpec.containers 0 ) }}
{{- if gt $phy_memory 0 }}
{{- $max_client_conn = min ( div $phy_memory 9531392 ) 5000 }}
{{- end }}
max_client_conn = {{ $max_client_conn }}
admin_users = postgres
;;; [database]
max_client_conn = 500
default_pool_size = 20
min_pool_size = 5
reserve_pool_size = 5
reserve_pool_timeout = 5
max_db_connections = 80
max_user_connections = 80
server_idle_timeout = 600
server_lifetime = 3600
query_wait_timeout = 120
client_idle_timeout = 0
Loading
Loading