-
Notifications
You must be signed in to change notification settings - Fork 1
feat: enable connection pooling unicorn #201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
37ca8ce
feat: add unicorn flavor
Racer159 cfe7f6d
fix my dumb
Racer159 d40942f
fix image
Racer159 51478f0
feat(pepr): add pgbouncer module with configuration and custom Pepr m…
mkm29 35f53ab
Merge branch 'main' into feat/enable-connection-pooling-unicorn
mkm29 a698647
feat(pepr): enhance pgbouncer module documentation and update build t…
mkm29 93e759f
feat: remove unused configuration files and add copyright headers
mkm29 5fb70c9
docs(pepr): properly documented Pepr module
mkm29 92eeb9d
feat(pg-bouncer): implement FIPS connection pooler via Pepr module
mkm29 cc8535b
feat(releaser): update datasource for unicorn flavor to FIPS complian…
mkm29 3351d01
feat(pg-bouncer): enhance connection pooler configuration and refacto…
mkm29 e7f80fd
feat(pepr): update secrets and build timestamps for pgbouncer configu…
mkm29 f128b9b
feat(pepr): add license header to generated pgbouncer manifest
mkm29 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,7 +6,6 @@ yaml-files: | |
| ignore: | ||
| - '**/chart/templates**' | ||
|
|
||
|
|
||
| rules: | ||
| anchors: enable | ||
| braces: enable | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| # 2. Configure the distroless connection pooler with a Pepr module | ||
|
|
||
| Date: 2026-06-04 | ||
|
|
||
| ## Status | ||
|
|
||
| Proposed | ||
|
|
||
| ## Context | ||
|
|
||
| The Zalando postgres-operator launches the connection-pooler container with only an image and environment variables — no `command`/`args` — and relies on the image's entrypoint to render `pgbouncer.ini` (and the `userlist.txt` auth file) from those env vars and then exec PgBouncer. | ||
|
|
||
| The `unicorn` flavor uses a distroless PgBouncer image (`pgbouncer-fips`) that is the bare binary with no entrypoint script, template, or shell. Launched argument-less it prints usage and exits, so the pooler crash-loops. The operator does not let us set the pooler container's command, volumes, or config, and it reconciles the pooler Deployment, so any manual patch is eventually reverted. | ||
|
|
||
| We need a way to supply PgBouncer's config, auth file, and launch command that (a) works with a distroless image, (b) survives operator reconciliation, and (c) is coupled to this package's lifecycle. A one-shot `kubectl`/Job patch was rejected (the operator reverts it on its next write). | ||
|
|
||
| ## Decision | ||
|
|
||
| We ship a [Pepr](https://github.com/defenseunicorns/pepr) module (`src/pepr`, capability `pgbouncer-pooler`), bundled as a manifest in the `unicorn` component, that: | ||
|
|
||
| 1. reconciles the operator's pooler credential Secret into a derived `pgbouncer-userlist` Secret (the PgBouncer `auth_file`), | ||
| 2. mutates each pooler Deployment to mount that Secret plus a chart-shipped `pgbouncer-config` ConfigMap at `/etc/pgbouncer` and to set the PgBouncer launch command, and | ||
| 3. bootstraps pre-existing pooler Deployments on startup so the mutation also applies when the module is installed onto a running cluster. | ||
|
|
||
| The static `pgbouncer.ini` is rendered by the `uds-postgres-config` chart. Only the `unicorn` flavor ships the module; `registry1`/`upstream` use self-configuring PgBouncer images and need none of it. | ||
|
|
||
| ## Consequences | ||
|
|
||
| The distroless FIPS pooler now starts and proxies correctly, and because admission mutation re-applies on every operator write there is no reconcile-drift window (`failurePolicy: Ignore` keeps a webhook outage from blocking the operator). | ||
|
|
||
| This adds a TypeScript/Node module and a long-lived Pepr controller (admission webhook) to a previously YAML-only package — new build tooling (Node.js, `pepr build`) and an additional component to maintain. The built manifest is committed at `manifests/pepr-module-pgbouncer.yaml`; its shared `pepr-system` Namespace is stripped so package removal does not affect `pepr-uds-core`. The replica pooler is not yet supported (the rendered config targets the primary), and `registry1` would need a similar approach if it ever moves to a distroless pooler image. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| # Copyright 2024 Defense Unicorns | ||
| # SPDX-License-Identifier: AGPL-3.0-or-later OR LicenseRef-Defense-Unicorns-Commercial | ||
|
|
||
| {{- if and .Values.postgresql.enabled (or .Values.postgresql.enableConnectionPooler .Values.postgresql.enableReplicaConnectionPooler) }} | ||
| apiVersion: v1 | ||
| kind: ConfigMap | ||
| metadata: | ||
| name: pgbouncer-config | ||
| namespace: postgres | ||
| data: | ||
| {{- with .Values.postgresql.configConnectionPooler -}} | ||
| pgbouncer.ini: | | ||
| [databases] | ||
| * = host=pg-cluster.postgres.svc.cluster.local port=5432 auth_user=pooler | ||
| postgres = host=pg-cluster.postgres.svc.cluster.local port=5432 auth_user=pooler | ||
|
|
||
| [pgbouncer] | ||
| pool_mode = {{ .connection_pooler_mode | default "transaction" }} | ||
| listen_port = {{ .connection_pooler_listen_port | default 5432 }} | ||
| listen_addr = * | ||
| admin_users = pooler | ||
| auth_dbname = postgres | ||
| auth_file = /etc/pgbouncer/userlist.txt | ||
| auth_query = SELECT * FROM pooler.user_lookup($1) | ||
| auth_type = scram-sha-256 | ||
| server_tls_sslmode = require | ||
| log_connections = 0 | ||
| log_disconnections = 0 | ||
| max_prepared_statements = 200 | ||
| default_pool_size = {{ .connection_pooler_default_pool_size | default 20 }} | ||
| reserve_pool_size = {{ .connection_pooler_reserve_pool_size | default 10 }} | ||
| max_client_conn = {{ .connection_pooler_max_client_conn | default 10000 }} | ||
| max_db_connections = {{ .connection_pooler_max_db_connections | default 60 }} | ||
| idle_transaction_timeout = 600 | ||
| server_login_retry = 5 | ||
| ignore_startup_parameters = extra_float_digits,options | ||
| {{- end -}} | ||
| {{- end }} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assuming there is literally no other way to accomplish this, which I am skeptical of without diving much deeper into this I would much rather see if the other pgbouncer image in chainguard's catalogue works or even use the
-devvariant over this approach.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think a deep dive is critical here. The postgres-operator itself generates the pooler Deployment (per
postgresqlCR), there does not appear to be any templates that can be overriden so changes will need to be made to the Go code. In the meantime, this mutation addresses this issue.All pgbouncer images on chainguard only have the pgbouncer binary as the entrypoint, with no args. If you inspect the upstream zalando pgbouncer image, the entrypoint is a script that uses envsubst to create the ini config file and then calls pgbouncer with this ini file as the only argument. This can be verified with:
entrypoint.sh
You can verify that any CGR image defaults to just calling
pgbouncer --help:I will move this PR to draft and work with the Zalando team to get the operator itself updated.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. Working with the zalando team and/or chainguard is definitely the correct approach to this problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you need something in the meantime, consider that it is probably possible to build this image with the necessary changes to match the zalando one internal to the repo and part of an onCreate action or otherwise and then use that.
It would be preferable to just get a solution using the upstream providers, but I am providing another alternative if it is time sensitive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks! tbh I prefer to wait for zalando to make it happen, so going to hold off until then