diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 07a5bd1ba..feb4ed984 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -11,10 +11,10 @@ on: jobs: linter: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: fetch-depth: 0 @@ -25,7 +25,7 @@ jobs: - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: - python-version: 3.7 + python-version: 3.12 - name: Set up chart-testing uses: helm/chart-testing-action@e6669bcd63d7cb57cb4380c33043eebe5d111992 # v2.6.1 diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml index 350caf243..255c1a357 100644 --- a/.github/workflows/release-pr.yml +++ b/.github/workflows/release-pr.yml @@ -13,10 +13,10 @@ permissions: jobs: create-pull-request: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 - name: Create Pull Request id: create-pr env: diff --git a/.github/workflows/release-publish.yml b/.github/workflows/release-publish.yml index aec6959af..69d2aeb36 100644 --- a/.github/workflows/release-publish.yml +++ b/.github/workflows/release-publish.yml @@ -12,10 +12,10 @@ permissions: jobs: release: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: fetch-depth: 0 # important for fetching all history to run comparison against @@ -65,7 +65,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Install sigstore/cosign - uses: sigstore/cosign-installer@4959ce089c160fddf62f7b42464195ba1a56d382 # v3.6.0 + uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3.7.0 - name: Push charts to GHCR env: diff --git a/.github/workflows/tests-cluster-chainsaw.yaml b/.github/workflows/tests-cluster-chainsaw.yaml index 555b3fe07..ca59dd8b6 100644 --- a/.github/workflows/tests-cluster-chainsaw.yaml +++ b/.github/workflows/tests-cluster-chainsaw.yaml @@ -7,13 +7,16 @@ on: jobs: test-cluster-standalone: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: fetch-depth: 0 + - name: Install Cosign + uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3.7.0 + - name: Setup kind uses: ./.github/actions/setup-kind @@ -26,7 +29,9 @@ jobs: helm install prometheus-crds prometheus-community/prometheus-operator-crds - name: Install Chainsaw - uses: kyverno/action-install-chainsaw@b2f61a8d0459a65c476ac802514d88e1612b3396 # v0.2.9 + uses: kyverno/action-install-chainsaw@d311eacde764f806c9658574ff64c9c3b21f8397 # v0.2.11 + with: + verify: true - name: Setup MinIO run: | diff --git a/.github/workflows/tests-operator.yml b/.github/workflows/tests-operator.yml index a8fe41d20..2a4372bf3 100644 --- a/.github/workflows/tests-operator.yml +++ b/.github/workflows/tests-operator.yml @@ -7,10 +7,10 @@ on: jobs: deploy_operator: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 with: fetch-depth: 0 diff --git a/charts/cluster/README.md b/charts/cluster/README.md index 5b3fcd204..134588a77 100644 --- a/charts/cluster/README.md +++ b/charts/cluster/README.md @@ -160,9 +160,13 @@ refer to the [CloudNativePG Documentation](https://cloudnative-pg.io/documentat | cluster.initdb | object | `{}` | BootstrapInitDB is the configuration of the bootstrap process when initdb is used. See: https://cloudnative-pg.io/documentation/current/bootstrap/ See: https://cloudnative-pg.io/documentation/current/cloudnative-pg.v1/#postgresql-cnpg-io-v1-bootstrapinitdb | | cluster.instances | int | `3` | Number of instances | | cluster.logLevel | string | `"info"` | The instances' log level, one of the following values: error, warning, info (default), debug, trace | -| cluster.monitoring.customQueries | list | `[]` | Custom Prometheus metrics | +| cluster.monitoring.customQueries | list | `[]` | Custom Prometheus metrics Will be stored in the ConfigMap | +| cluster.monitoring.customQueriesSecret | list | `[]` | The list of secrets containing the custom queries | +| cluster.monitoring.disableDefaultQueries | bool | `false` | Whether the default queries should be injected. Set it to true if you don't want to inject default queries into the cluster. | | cluster.monitoring.enabled | bool | `false` | Whether to enable monitoring | | cluster.monitoring.podMonitor.enabled | bool | `true` | Whether to enable the PodMonitor | +| cluster.monitoring.podMonitor.metricRelabelings | list | `[]` | The list of metric relabelings for the PodMonitor. Applied to samples before ingestion. | +| cluster.monitoring.podMonitor.relabelings | list | `[]` | The list of relabelings for the PodMonitor. Applied to samples before scraping. | | cluster.monitoring.prometheusRule.enabled | bool | `true` | Whether to enable the PrometheusRule automated alerts | | cluster.monitoring.prometheusRule.excludeRules | list | `[]` | Exclude specified rules | | cluster.postgresGID | int | `-1` | The GID of the postgres user inside the image, defaults to 26 | @@ -191,6 +195,8 @@ refer to the [CloudNativePG Documentation](https://cloudnative-pg.io/documentat | pooler.instances | int | `3` | Number of PgBouncer instances | | pooler.monitoring.enabled | bool | `false` | Whether to enable monitoring | | pooler.monitoring.podMonitor.enabled | bool | `true` | Whether to enable the PodMonitor | +| pooler.monitoring.podMonitor.metricRelabelings | list | `[]` | The list of metric relabelings for the PodMonitor. Applied to samples before ingestion. | +| pooler.monitoring.podMonitor.relabelings | list | `[]` | The list of relabelings for the PodMonitor. Applied to samples before scraping. | | pooler.parameters | object | `{"default_pool_size":"25","max_client_conn":"1000"}` | PgBouncer configuration parameters | | pooler.poolMode | string | `"transaction"` | PgBouncer pooling mode | | pooler.template | object | `{}` | Custom PgBouncer deployment template. Use to override image, specify resources, etc. | diff --git a/charts/cluster/examples/pgbouncer.yaml b/charts/cluster/examples/pgbouncer.yaml index cfa641e45..94d4987e6 100644 --- a/charts/cluster/examples/pgbouncer.yaml +++ b/charts/cluster/examples/pgbouncer.yaml @@ -1,9 +1,34 @@ type: postgresql mode: standalone + cluster: instances: 1 + monitoring: + enabled: true + podMonitor: + enabled: true + backups: enabled: false -pooler: - enabled: true - instances: 1 + +poolers: + - name: rw + type: rw + instances: 1 + monitoring: + enabled: true + podMonitor: + enabled: true + relabelings: + - targetLabel: type + replacement: rw + - name: ro + type: ro + instances: 1 + monitoring: + enabled: true + podMonitor: + enabled: true + relabelings: + - targetLabel: type + replacement: ro diff --git a/charts/cluster/templates/NOTES.txt b/charts/cluster/templates/NOTES.txt index 6a28fa592..eed368607 100644 --- a/charts/cluster/templates/NOTES.txt +++ b/charts/cluster/templates/NOTES.txt @@ -78,7 +78,7 @@ Configuration {{- end }} │ Storage │ {{ printf "%-56s" .Values.cluster.storage.size }} │ │ Storage Class │ {{ printf "%-56s" (default "Default" .Values.cluster.storage.storageClass) }} │ -│ PGBouncer │ {{ printf "%-56s" (ternary "Enabled" "Disabled" .Values.pooler.enabled) }} │ +│ PGBouncer │ {{ printf "%-56s" (ternary "Enabled" "Disabled" (gt (len .Values.poolers) 0)) }} │ │ Monitoring │ {{ include (printf "%s%s" "cluster.color-" (ternary "ok" "error" .Values.cluster.monitoring.enabled)) (printf "%-56s" (ternary "Enabled" "Disabled" .Values.cluster.monitoring.enabled)) }} │ ╰───────────────────┴──────────────────────────────────────────────────────────╯ diff --git a/charts/cluster/templates/cluster.yaml b/charts/cluster/templates/cluster.yaml index c1879cfef..169683fef 100644 --- a/charts/cluster/templates/cluster.yaml +++ b/charts/cluster/templates/cluster.yaml @@ -60,12 +60,12 @@ spec: {{- toYaml . | nindent 6 }} {{- end }} {{- with .Values.cluster.postgresql }} - parameters: - {{- toYaml .parameters | nindent 6 }} pg_hba: {{- toYaml .pg_hba | nindent 6 }} pg_ident: {{- toYaml .pg_ident | nindent 6 }} + parameters: + {{- toYaml .parameters | nindent 6 }} {{ end }} managed: @@ -76,10 +76,29 @@ spec: monitoring: enablePodMonitor: {{ and .Values.cluster.monitoring.enabled .Values.cluster.monitoring.podMonitor.enabled }} + disableDefaultQueries: {{ .Values.cluster.monitoring.disableDefaultQueries }} {{- if not (empty .Values.cluster.monitoring.customQueries) }} customQueriesConfigMap: - name: {{ include "cluster.fullname" . }}-monitoring key: custom-queries {{- end }} + {{- if not (empty .Values.cluster.monitoring.customQueriesSecret) }} + {{- with .Values.cluster.monitoring.customQueriesSecret }} + customQueriesSecret: + {{- toYaml . | nindent 6 }} + {{ end }} + {{- end }} + {{- if not (empty .Values.cluster.monitoring.podMonitor.relabelings) }} + {{- with .Values.cluster.monitoring.podMonitor.relabelings }} + podMonitorRelabelings: + {{- toYaml . | nindent 6 }} + {{ end }} + {{- end }} + {{- if not (empty .Values.cluster.monitoring.podMonitor.metricRelabelings) }} + {{- with .Values.cluster.monitoring.podMonitor.metricRelabelings }} + podMonitorMetricRelabelings: + {{- toYaml . | nindent 6 }} + {{ end }} + {{- end }} {{ include "cluster.bootstrap" . | nindent 2 }} {{ include "cluster.backup" . | nindent 2 }} diff --git a/charts/cluster/templates/pooler.yaml b/charts/cluster/templates/pooler.yaml index 5e01fe498..8e1b8f9ee 100644 --- a/charts/cluster/templates/pooler.yaml +++ b/charts/cluster/templates/pooler.yaml @@ -1,21 +1,36 @@ -{{ if .Values.pooler.enabled }} +{{- range .Values.poolers }} +--- apiVersion: postgresql.cnpg.io/v1 kind: Pooler metadata: - name: {{ include "cluster.fullname" . }}-pooler-rw + name: {{ include "cluster.fullname" $ }}-pooler-{{ .name }} spec: cluster: - name: {{ include "cluster.fullname" . }} - instances: {{ .Values.pooler.instances }} - type: {{ .Values.pooler.type }} + name: {{ include "cluster.fullname" $ }} + instances: {{ .instances }} + type: {{ default "rw" .type }} pgbouncer: - poolMode: {{ .Values.pooler.poolMode }} + poolMode: {{ default "session" .poolMode }} + {{- with .parameters }} parameters: - {{- .Values.pooler.parameters | toYaml | nindent 6 }} + {{- toYaml . | nindent 6 }} + {{- end }} + {{ with .monitoring }} monitoring: - enablePodMonitor: {{ and .Values.pooler.monitoring.enabled .Values.pooler.monitoring.podMonitor.enabled }} - {{- with .Values.pooler.template }} + {{- if not (empty .podMonitor) }} + enablePodMonitor: {{ and .enabled .podMonitor.enabled }} + {{- with .podMonitor.relabelings }} + podMonitorRelabelings: + {{- toYaml . | nindent 6 }} + {{ end }} + {{- with .podMonitor.metricRelabelings }} + podMonitorMetricRelabelings: + {{- toYaml . | nindent 6 }} + {{ end }} + {{- end }} + {{- end }} + {{- with .template }} template: {{- . | toYaml | nindent 4 }} {{- end }} -{{ end }} +{{- end }} diff --git a/charts/cluster/test/monitoring/01-monitoring_cluster-assert.yaml b/charts/cluster/test/monitoring/01-monitoring_cluster-assert.yaml index d69c702c0..ce6544e2e 100644 --- a/charts/cluster/test/monitoring/01-monitoring_cluster-assert.yaml +++ b/charts/cluster/test/monitoring/01-monitoring_cluster-assert.yaml @@ -1,3 +1,37 @@ +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + name: monitoring-cluster + labels: + foo: bar + annotations: + foo: bar +spec: + instances: 2 + storage: + size: 256Mi + storageClass: standard + monitoring: + disableDefaultQueries: true + customQueriesConfigMap: + - name: monitoring-cluster-monitoring + key: custom-queries + enablePodMonitor: true + podMonitorRelabelings: + - action: replace + replacement: test + targetLabel: environment + - action: replace + replacement: alpha + targetLabel: team + podMonitorMetricRelabelings: + - action: replace + sourceLabels: + - cluster + targetLabel: cnpg_cluster + - action: labeldrop + regex: cluster +--- apiVersion: monitoring.coreos.com/v1 kind: PodMonitor metadata: @@ -6,6 +40,22 @@ spec: selector: matchLabels: cnpg.io/cluster: monitoring-cluster + podMetricsEndpoints: + - bearerTokenSecret: + key: '' + name: '' + relabelings: + - targetLabel: environment + replacement: test + - targetLabel: team + replacement: alpha + metricRelabelings: + - action: replace + sourceLabels: + - cluster + targetLabel: cnpg_cluster + - action: labeldrop + regex: cluster --- apiVersion: monitoring.coreos.com/v1 kind: PodMonitor @@ -15,6 +65,51 @@ spec: selector: matchLabels: cnpg.io/poolerName: monitoring-cluster-pooler-rw + podMetricsEndpoints: + - bearerTokenSecret: + key: '' + name: '' + relabelings: + - targetLabel: type + replacement: rw + action: replace + - targetLabel: team + replacement: alpha + action: replace + metricRelabelings: + - action: replace + sourceLabels: + - cluster + targetLabel: cnpg_cluster + - action: labeldrop + regex: cluster +--- +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: monitoring-cluster-pooler-ro +spec: + selector: + matchLabels: + cnpg.io/poolerName: monitoring-cluster-pooler-ro + podMetricsEndpoints: + - bearerTokenSecret: + key: '' + name: '' + relabelings: + - targetLabel: type + replacement: ro + action: replace + - targetLabel: team + replacement: alpha + action: replace + metricRelabelings: + - action: replace + sourceLabels: + - cluster + targetLabel: cnpg_cluster + - action: labeldrop + regex: cluster --- apiVersion: monitoring.coreos.com/v1 kind: PrometheusRule diff --git a/charts/cluster/test/monitoring/01-monitoring_cluster.yaml b/charts/cluster/test/monitoring/01-monitoring_cluster.yaml index 2e94c2fc0..3dc3cf648 100644 --- a/charts/cluster/test/monitoring/01-monitoring_cluster.yaml +++ b/charts/cluster/test/monitoring/01-monitoring_cluster.yaml @@ -7,6 +7,7 @@ cluster: storageClass: standard monitoring: enabled: true + disableDefaultQueries: true customQueries: - name: "pg_cache_hit_ratio" query: "SELECT current_database() as datname, sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read)) as ratio FROM pg_statio_user_tables;" @@ -17,10 +18,61 @@ cluster: - ratio: usage: GAUGE description: "Cache hit ratio" + podMonitor: + relabelings: + - targetLabel: environment + replacement: test + - targetLabel: team + replacement: alpha + metricRelabelings: + - action: replace + sourceLabels: + - cluster + targetLabel: cnpg_cluster + - action: labeldrop + regex: cluster + additionalLabels: + foo: bar + annotations: + foo: bar backups: enabled: false -pooler: - enabled: true - instances: 1 - monitoring: - enabled: true +poolers: + - name: rw + type: rw + instances: 1 + monitoring: + enabled: true + podMonitor: + enabled: true + relabelings: + - targetLabel: type + replacement: rw + - targetLabel: team + replacement: alpha + metricRelabelings: + - action: replace + sourceLabels: + - cluster + targetLabel: cnpg_cluster + - action: labeldrop + regex: cluster + - name: ro + type: ro + instances: 1 + monitoring: + enabled: true + podMonitor: + enabled: true + relabelings: + - targetLabel: type + replacement: ro + - targetLabel: team + replacement: alpha + metricRelabelings: + - action: replace + sourceLabels: + - cluster + targetLabel: cnpg_cluster + - action: labeldrop + regex: cluster \ No newline at end of file diff --git a/charts/cluster/test/pooler/01-pooler_cluster-assert.yaml b/charts/cluster/test/pooler/01-pooler_cluster-assert.yaml index 1b6178394..4a27037ca 100644 --- a/charts/cluster/test/pooler/01-pooler_cluster-assert.yaml +++ b/charts/cluster/test/pooler/01-pooler_cluster-assert.yaml @@ -5,6 +5,13 @@ metadata: status: readyReplicas: 2 --- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: pooler-cluster-pooler-ro +status: + readyReplicas: 2 +--- apiVersion: postgresql.cnpg.io/v1 kind: Pooler metadata: @@ -14,5 +21,17 @@ spec: name: pooler-cluster instances: 2 pgbouncer: - poolMode: transaction + poolMode: session type: rw +--- +apiVersion: postgresql.cnpg.io/v1 +kind: Pooler +metadata: + name: pooler-cluster-pooler-ro +spec: + cluster: + name: pooler-cluster + instances: 2 + pgbouncer: + poolMode: session + type: ro diff --git a/charts/cluster/test/pooler/01-pooler_cluster.yaml b/charts/cluster/test/pooler/01-pooler_cluster.yaml index 3f197ce7e..8933e3d75 100644 --- a/charts/cluster/test/pooler/01-pooler_cluster.yaml +++ b/charts/cluster/test/pooler/01-pooler_cluster.yaml @@ -7,6 +7,10 @@ cluster: storageClass: standard backups: enabled: false -pooler: - enabled: true - instances: 2 +poolers: + - name: rw + type: rw + instances: 2 + - name: ro + type: ro + instances: 2 diff --git a/charts/cluster/values.schema.json b/charts/cluster/values.schema.json index 9e35d7a90..81899f1cd 100644 --- a/charts/cluster/values.schema.json +++ b/charts/cluster/values.schema.json @@ -214,6 +214,12 @@ "customQueries": { "type": "array" }, + "customQueriesSecret": { + "type": "array" + }, + "disableDefaultQueries": { + "type": "boolean" + }, "enabled": { "type": "boolean" }, @@ -222,6 +228,12 @@ "properties": { "enabled": { "type": "boolean" + }, + "metricRelabelings": { + "type": "array" + }, + "relabelings": { + "type": "array" } } }, @@ -326,52 +338,8 @@ "nameOverride": { "type": "string" }, - "pooler": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "instances": { - "type": "integer" - }, - "monitoring": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "podMonitor": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - } - } - } - } - }, - "parameters": { - "type": "object", - "properties": { - "default_pool_size": { - "type": "string" - }, - "max_client_conn": { - "type": "string" - } - } - }, - "poolMode": { - "type": "string" - }, - "template": { - "type": "object" - }, - "type": { - "type": "string" - } - } + "poolers": { + "type": "array" }, "recovery": { "type": "object", diff --git a/charts/cluster/values.yaml b/charts/cluster/values.yaml index 6c51b10c5..8a31a1470 100644 --- a/charts/cluster/values.yaml +++ b/charts/cluster/values.yaml @@ -220,13 +220,23 @@ cluster: podMonitor: # -- Whether to enable the PodMonitor enabled: true + # --The list of relabelings for the PodMonitor. + # Applied to samples before scraping. + relabelings: [] + # -- The list of metric relabelings for the PodMonitor. + # Applied to samples before ingestion. + metricRelabelings: [] prometheusRule: # -- Whether to enable the PrometheusRule automated alerts enabled: true # -- Exclude specified rules excludeRules: [] # - CNPGClusterZoneSpreadWarning + # -- Whether the default queries should be injected. + # Set it to true if you don't want to inject default queries into the cluster. + disableDefaultQueries: false # -- Custom Prometheus metrics + # Will be stored in the ConfigMap customQueries: [] # - name: "pg_cache_hit_ratio" # query: "SELECT current_database() as datname, sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read)) as ratio FROM pg_statio_user_tables;" @@ -237,6 +247,10 @@ cluster: # - ratio: # usage: GAUGE # description: "Cache hit ratio" + # -- The list of secrets containing the custom queries + customQueriesSecret: [] + # - name: custom-queries-secret + # key: custom-queries postgresql: # -- PostgreSQL configuration options (postgresql.conf) @@ -356,27 +370,48 @@ imageCatalog: # - image: ghcr.io/your_repo/your_image:your_tag # major: 16 -pooler: - # -- Whether to enable PgBouncer - enabled: false - # -- PgBouncer type of service to forward traffic to. - type: rw - # -- PgBouncer pooling mode - poolMode: transaction - # -- Number of PgBouncer instances - instances: 3 - # -- PgBouncer configuration parameters - parameters: - max_client_conn: "1000" - default_pool_size: "25" - - monitoring: - # -- Whether to enable monitoring - enabled: false - podMonitor: - # -- Whether to enable the PodMonitor - enabled: true - - # -- Custom PgBouncer deployment template. - # Use to override image, specify resources, etc. - template: {} +poolers: [] + # - + # # -- Pooler name + # name: rw + # # -- PgBouncer type of service to forward traffic to. + # type: rw + # # -- PgBouncer pooling mode + # poolMode: transaction + # # -- Number of PgBouncer instances + # instances: 3 + # # -- PgBouncer configuration parameters + # parameters: + # max_client_conn: "1000" + # default_pool_size: "25" + # monitoring: + # # -- Whether to enable monitoring + # enabled: false + # podMonitor: + # # -- Whether to enable the PodMonitor + # enabled: true + # # -- Custom PgBouncer deployment template. + # # Use to override image, specify resources, etc. + # template: {} + # - + # # -- Pooler name + # name: ro + # # -- PgBouncer type of service to forward traffic to. + # type: ro + # # -- PgBouncer pooling mode + # poolMode: transaction + # # -- Number of PgBouncer instances + # instances: 3 + # # -- PgBouncer configuration parameters + # parameters: + # max_client_conn: "1000" + # default_pool_size: "25" + # monitoring: + # # -- Whether to enable monitoring + # enabled: false + # podMonitor: + # # -- Whether to enable the PodMonitor + # enabled: true + # # -- Custom PgBouncer deployment template. + # # Use to override image, specify resources, etc. + # template: {}