Skip to content
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

[bitnami/postgresql] Better documentation needed on major version upgrades #14926

Open
brsolomon-deloitte opened this issue Feb 16, 2023 · 31 comments
Assignees
Labels
feature-request on-hold Issues or Pull Requests with this label will never be considered stale postgresql

Comments

@brsolomon-deloitte
Copy link
Contributor

Name and Version

bitnami/postgresql 12.2.0

What is the problem this feature will solve?

Currently the upgrading section of bitnami/postgresql is simply an external link to the PostgreSQL docs on how to upgrade major versions. This is insufficient for providing a bare minimum level of information on how to upgrade the PostgreSQL major version when using the Bitnami PostgreSQL Helm chart.

I am opening this issue to suggest that Bitnami could be more prescriptive and detailed as to how to upgrade the postgresql chart + image major version, giving specific consideration to PostgreSQL being deployed to Kubernetes, beyond simply linking to the PostgreSQL docs.

A well known paint point of PostgreSQL is that major-version upgrades require generally one of two steps to un-break things: pg_dumpall or pg_upgrade. In the absence of these, the PostgreSQL upgrade will fail with FATAL database files are incompatible with server and indicate that

The data directory was initialized by PostgreSQL version <old-version>,
which is not compatible with this version <old-version>.

The Bitnami documentation could at the very least make a recommendation between one of these two methods, or provide a complete, working, and minimal example for upgrading.

What is the feature you are proposing to solve the problem?

To more easily upgrade the PostgreSQL major version, either because we have bumped the Bitnami chart major version or explicitly bumped the postgresql.image.tag.

What alternatives have you considered?

@brsolomon-deloitte
Copy link
Contributor Author

brsolomon-deloitte commented Feb 16, 2023

Here is a full test of #8025 (comment) that ends in failure:

kubectl create namespace pgtest
argocd app create pgtest \
    --core \
    --dest-namespace pgtest \
    --repo https://charts.bitnami.com/bitnami \
    --helm-chart postgresql \
    --revision '11.9.13' \
    --dest-server https://kubernetes.default.svc \
    --helm-set-string 'auth.postgresPassword=098a981677'
argocd app sync --assumeYes --core pgtest

kubectl logs --tail 10 -n pgtest sts/pgtest-postgresql
# postgresql 18:46:45.53 INFO  ==> ** PostgreSQL setup finished! **

# postgresql 18:46:45.54 INFO  ==> ** Starting PostgreSQL **
# 2023-02-16 18:46:45.559 GMT [1] LOG:  pgaudit extension initialized
# 2023-02-16 18:46:45.566 GMT [1] LOG:  starting PostgreSQL 14.5 on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
# 2023-02-16 18:46:45.566 GMT [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
# 2023-02-16 18:46:45.566 GMT [1] LOG:  listening on IPv6 address "::", port 5432
# 2023-02-16 18:46:45.570 GMT [1] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
# 2023-02-16 18:46:45.574 GMT [131] LOG:  database system was shut down at 2023-02-16 18:46:45 GMT
# 2023-02-16 18:46:45.580 GMT [1] LOG:  database system is ready to accept connections

kubectl exec -it -n pgtest sts/pgtest-postgresql -- bash
I have no name!@pgtest-postgresql-0:/$ id
uid=1001 gid=0(root) groups=0(root),1001
I have no name!@pgtest-postgresql-0:/$ postgres --version
postgres (PostgreSQL) 14.5
I have no name!@pgtest-postgresql-0:/$ printenv POSTGRES_PASSWORD
098a981677
I have no name!@pgtest-postgresql-0:/$ PGPASSWORD=$POSTGRES_PASSWORD psql --host 127.0.0.1 -U postgres -d postgres -p 5432
psql (14.5)
Type "help" for help.

postgres=# CREATE TABLE IF NOT EXISTS app_user (
postgres(#   username varchar(45) NOT NULL,
postgres(#   password varchar(450) NOT NULL,
postgres(#   enabled integer NOT NULL DEFAULT '1',
postgres(#   PRIMARY KEY (username)
postgres(# );
CREATE TABLE
postgres=# exit


argocd app set pgtest --core --revision '12.2.0'

argocd app set pgtest --core \
    --helm-set 'primary.containerSecurityContext.runAsUser=0' \
    --helm-set 'diagnosticMode.enabled=true' \
    --helm-set-string 'auth.postgresPassword=098a981677'

$ argocd app diff --core pgtest

===== /Secret pgtest/pgtest-postgresql ======
12c12
<     helm.sh/chart: postgresql-11.9.13
---
>     helm.sh/chart: postgresql-12.2.0

===== /Service pgtest/pgtest-postgresql ======
12c12
<     helm.sh/chart: postgresql-11.9.13
---
>     helm.sh/chart: postgresql-12.2.0

===== /Service pgtest/pgtest-postgresql-hl ======
12c12
<     helm.sh/chart: postgresql-11.9.13
---
>     helm.sh/chart: postgresql-12.2.0

===== apps/StatefulSet pgtest/pgtest-postgresql ======
13c13
<     helm.sh/chart: postgresql-11.9.13
---
>     helm.sh/chart: postgresql-12.2.0
226c226
<         helm.sh/chart: postgresql-11.9.13
---
>         helm.sh/chart: postgresql-12.2.0
238,239d237
<               namespaces:
<               - pgtest
243c241,245
<       - env:
---
>       - args:
>         - infinity
>         command:
>         - sleep
>         env:
245c247
<           value: "false"
---
>           value: "true"
273c275
<         image: docker.io/bitnami/postgresql:14.5.0-debian-11-r35
---
>         image: docker.io/bitnami/postgresql:15.2.0-debian-11-r0
275,285d276
<         livenessProbe:
<           exec:
<             command:
<             - /bin/sh
<             - -c
<             - exec pg_isready -U "postgres" -h 127.0.0.1 -p 5432
<           failureThreshold: 6
<           initialDelaySeconds: 30
<           periodSeconds: 10
<           successThreshold: 1
<           timeoutSeconds: 5
291,304d281
<         readinessProbe:
<           exec:
<             command:
<             - /bin/sh
<             - -c
<             - -e
<             - |
<               exec pg_isready -U "postgres" -h 127.0.0.1 -p 5432
<               [ -f /opt/bitnami/postgresql/tmp/.initialized ] || [ -f /bitnami/postgresql/.initialized ]
<           failureThreshold: 6
<           initialDelaySeconds: 5
<           periodSeconds: 10
<           successThreshold: 1
<           timeoutSeconds: 5

argocd app sync --core pgtest


# now do the upgrade

kubectl exec -it -n pgtest sts/pgtest-postgresql -- bash

postgres --version
. /opt/bitnami/scripts/libos.sh
ensure_group_exists postgres -i 1002
ensure_user_exists postgres -i 1002 -g postgres
mv /bitnami/postgresql/data /bitnami/postgresql/olddata
mkdir -p /bitnami/postgresql/data /bitnami/postgresql/oldbin
chown -R postgres:postgres /bitnami/postgresql/data /bitnami/postgresql/olddata /bitnami/postgresql/oldbin
cd /tmp
# get the old version
apt-get update -y && apt-get install -y --no-install-recommends curl
export OLD_PG_VERSION='14.7.0-0'
export OLD_PG_VERSION_MMP='14.7.0'
curl --remote-name --silent https://downloads.bitnami.com/files/stacksmith/postgresql-${OLD_PG_VERSION}-linux-amd64-debian-11.tar.gz
tar --extract --directory /bitnami/postgresql/oldbin/ \
    --file postgresql-${OLD_PG_VERSION}-linux-amd64-debian-11.tar.gz \
    --strip-components=4 \
    postgresql-${OLD_PG_VERSION_MMP}-linux-amd64-debian-11/files/postgresql/bin
ls /bitnami/postgresql/oldbin/
gosu postgres initdb -E UTF8 -D /bitnami/postgresql/data -U postgres
gosu postgres pg_upgrade -c -b /bitnami/postgresql/oldbin -B /opt/bitnami/postgresql/bin -d /bitnami/postgresql/olddata -D /bitnami/postgresql/data

Performing Consistency Checks
-----------------------------
Checking cluster versions                                   ok

*failure*
Consult the last few lines of "/bitnami/postgresql/data/pg_upgrade_output.d/20230216T192921.303/log/pg_upgrade_server.log" for
the probable cause of the failure.

connection to server on socket "/tmp/.s.PGSQL.50432" failed: No such file or directory
    Is the server running locally and accepting connections on that socket?

could not connect to source postmaster started with the command:
"/bitnami/postgresql/oldbin/pg_ctl" -w -l "/bitnami/postgresql/data/pg_upgrade_output.d/20230216T192921.303/log/pg_upgrade_server.log" -D "/bitnami/postgresql/olddata" -o "-p 50432 -b  -c listen_addresses='' -c unix_socket_permissions=0700 -c unix_socket_directories='/tmp'" start
Failure, exiting
root@pgtest-postgresql-0:/tmp# cat /bitnami/postgresql/data/pg_upgrade_output.d/20230216T192921.303/log/pg_upgrade_server.log
-----------------------------------------------------------------
  pg_upgrade run on Thu Feb 16 19:29:21 2023
-----------------------------------------------------------------

command: "/bitnami/postgresql/oldbin/pg_ctl" -w -l "/bitnami/postgresql/data/pg_upgrade_output.d/20230216T192921.303/log/pg_upgrade_server.log" -D "/bitnami/postgresql/olddata" -o "-p 50432 -b  -c listen_addresses='' -c unix_socket_permissions=0700 -c unix_socket_directories='/tmp'" start >> "/bitnami/postgresql/data/pg_upgrade_output.d/20230216T192921.303/log/pg_upgrade_server.log" 2>&1
waiting for server to start....postgres: could not access the server configuration file "/bitnami/postgresql/olddata/postgresql.conf": No such file or directory
 stopped waiting
pg_ctl: could not start server
Examine the log output.

@bitnami-bot bitnami-bot assigned Mauraza and unassigned javsalgar Feb 17, 2023
@github-actions github-actions bot added in-progress and removed triage Triage is needed labels Feb 17, 2023
@Mauraza
Copy link
Contributor

Mauraza commented Feb 20, 2023

Hi @brsolomon-deloitte,

We are open to contributions! If you want you can create a PR with the things you think are necessary to upgrade, we will be happy to review it!

@brsolomon-deloitte
Copy link
Contributor Author

brsolomon-deloitte commented Feb 20, 2023

Hi @brsolomon-deloitte,

We are open to contributions! If you want you can create a PR with the things you think are necessary to upgrade, we will be happy to review it!

I don't have much to contribute here since my attempt above ends in an error. I would think that the Bitnami team would have a full reproducible solution here with the latest postgres chart and images (v 14.x/15.x). That's why I opened this issue.

@hanbinloop
Copy link

I execute the following command and there is an error in my minikube:

helm repo add bitnami https://charts.bitnami.com/bitnami
helm install my-release bitnami/keycloak

image
The data directory was initialized by PostgreSQL version 11, which is not compatible with this version 15.2

@hanbinloop
Copy link

@Mauraza

@Mauraza
Copy link
Contributor

Mauraza commented Feb 21, 2023

Hi @hanbinloop,

Could you create another issue with this? This issue is related to the PostgreSQL Chart no with Keycloak.
Thanks!

@github-actions
Copy link

This Issue has been automatically marked as "stale" because it has not had recent activity (for 15 days). It will be closed if no further activity occurs. Thanks for the feedback.

@github-actions github-actions bot added the stale 15 days without activity label Mar 10, 2023
@brsolomon-deloitte
Copy link
Contributor Author

not stale

@Mauraza
Copy link
Contributor

Mauraza commented Mar 10, 2023

Hi @brsolomon-deloitte,

I have created a task internally to review this error. We currently have a lot on our plate. For this reason, we will update this thread when we update the documentation.

@Mauraza Mauraza added the on-hold Issues or Pull Requests with this label will never be considered stale label Mar 10, 2023
@github-actions github-actions bot removed the stale 15 days without activity label Mar 11, 2023
@hatharom
Copy link

hatharom commented Mar 31, 2023

bump (anti-stale message)

@hatharom
Copy link

This seems a serious issue.

Because of lack of proper documentation and/or built-in solution I was forced to do some hand-made hack like:
modifiying the image version then stepping into the pod and perform pg_upgrade or pg_dumpall according to this
#8025 (comment)

Needless to say non of them worked out
pg_upgrade fails because of OS version change between the postgresimage v11 and v15
pg_dump fails because of permission stuff... I got tired to debug further

Native postgres upgrade seems a piece of cake compared to this bitnamichart ecosystem....

@github-actions github-actions bot added on-hold Issues or Pull Requests with this label will never be considered stale and removed triage Triage is needed labels Oct 24, 2023
@Gwojda
Copy link

Gwojda commented Nov 8, 2023

Hi all,
Same issue here, any solution/documentation to help on that ? The last 17.x.x release for keycloak use the new version of postgre, but no documentation is provided to migrate pg 15 to 16.

@github-actions github-actions bot added triage Triage is needed and removed on-hold Issues or Pull Requests with this label will never be considered stale labels Nov 8, 2023
@cjvirtucio87
Copy link

what about keycloak just set:

postgresql:
  image:
    tag: 15.4.0-debian-11-r54

I don't think it's a postgres chart problem.

This helped as a stopgap. Might also be worth noting this comment, though that wasn't necessarily applicable, since I have a source of truth for my secrets.

I haven't actually started on a migration path, but after a quick look at the official keycloak docs, I'd imagine it'd go something like:

  1. backup your data
  2. create external uplevel postgres deployment
  3. helm upgrade but point host to external uplevel postgres deployment
  4. let automatic migration run
  5. helm upgrade again without the external DB configs
  6. stream pg dump from external uplevel postgres deployment into default uplevel postgres deployment
  7. soak time
  8. done!

Certainly doable, but would be nice if the keycloak folks had something like this out of the box.

@headyj
Copy link

headyj commented Nov 17, 2023

I successfully updated from Chart v15 to v17 (and so from postgresql 15 to 16) using the following process:

  • Update Chart version, keeping the same postgresql version (for now) by editing the values.yaml.
  • Add a new fresh and separated postgresql instance with latest version, using the same credentials

Chart.yaml

apiVersion: v2
name: keycloak
type: application
version: 1.0.0
appVersion: "1.0.0"
dependencies:
- name: keycloak
  version: 17.3.1
  repository: https://charts.bitnami.com/bitnami
- name: postgresql
  alias: postgresql-16
  version: 13.2.9
  repository: https://charts.bitnami.com/bitnami

values.yaml

keycloak:
[...]
  postgresql:
    enabled: true
    image:
      registry: docker.io
      repository: bitnami/postgresql
      tag: 15.3.0-debian-11-r74
[...]
postgresql-16:
  architecture: standalone
  auth:
    username: keycloak
    database: keycloak
    existingSecret: keycloak-psql-secret
  • connect on current postgresql pod and backup:
export PGPASSWORD=$POSTGRES_PASSWORD
pg_dumpall -U postgres > bitnami/postgresql/backup.sql
  • copy the file into your new postgresql:
kubectl cp -n keycloak keycloak-postgresql-0:/bitnami/postgresql/backup.sql /tmp/backup.sql
kubectl cp -n keycloak /tmp/backup.sql keycloak-postgresql-16-0:/bitnami/postgresql/backup.sql
  • connect to new postgresql pod and restore:
export PGPASSWORD=$POSTGRES_PASSWORD
psql -U postgres -h localhost -f /bitnami/postgresql/backup.sql
  • be sure to check you have a key named db-password which match the password key in your psql secret. For any reason, the chart is not using the same key for internal vs external db:
$ kubectl get secret -n keycloak keycloak-psql-secret -o yaml
apiVersion: v1
data:
  db-password: ****
  password: ****
  postgres-password: ****
kind: Secret
[...]
  • Change the configuration of your keycloak:
[...]
  postgresql:
    enabled: false ############################ Disable the current DB
    image:
      registry: docker.io
      repository: bitnami/postgresql
      tag: 15.3.0-debian-11-r74
    architecture: standalone
    auth:
      username: keycloak
      database: keycloak
      existingSecret: keycloak-psql-secret
  externalDatabase: ########################### Setup the new one
    host: keycloak-postgresql-16
    user: keycloak
    database: keycloak
    existingSecret: keycloak-psql-secret

I know It's not ideal, but it's working and is the only way I could safely update it. Also it should not lead to any downtime, except during restart if you're not in HA. You will just have to ensure that no data are created between backup and restore procedures.

Copy link

github-actions bot commented Dec 6, 2023

This Issue has been automatically marked as "stale" because it has not had recent activity (for 15 days). It will be closed if no further activity occurs. Thanks for the feedback.

@github-actions github-actions bot added the stale 15 days without activity label Dec 6, 2023
@brsolomon-deloitte
Copy link
Contributor Author

Not stale

@4censord
Copy link

4censord commented Dec 6, 2023

Do we already have an idea how to best solve this?

My instinct would be to add an init container that checks the current version against the version of the datafiles on disk.

If they match 
-> Launch the normal postgres container as always

If they do not match
  when version_on_disk is exactly one (1) below the container version
  	create a backup
  	perform the upgrade
  	  when this fails
  	  	restore the backup to the old location
  	    abort
  	  on success		
  		-> Launch the normal postgres container as always
  when not
  	abort

I'd have made this behaviour optional.

@christf
Copy link

christf commented Dec 6, 2023 via email

@joelparker
Copy link
Contributor

I ran into this using the bitnami/mastodon chart. I landed up disabling the Postgresql installation bundled with mastodon and using a separate Postgresql. Now I have 2 helm charts to update but I suppose now that I've migrated the data to new new version I I could migrate my data back and reenable using the Mastodon provided one.

My older Postgresql 15 pod was named mastodon-postgresql-0 and the fresh installed Postresql 16 had a service named postgresql. I was able to exec into mastodon-postgresql-0, dump the database, and import into the new install by running the following:

exec --stdin --tty mastodon-postgresql-0 -- /opt/bitnami/scripts/postgresql/entrypoint.sh /bin/bash

#Run the following command to dump the postgresql DB
PGPASSWORD='MY_SECRET_PASSWORD' pg_dump --create -U postgres bitnami_mastodon > /bitnami/postgresql/mastodon.sql 

#Upgrade the data to use Postgres 16
PGPASSWORD="MY_OTHER_SECRET_PASSWORD" psql -U postgres --host postgresql < /bitnami/postgresql/mastodon.sql

I then updated the Mastodon chart to disable the provided Postgresql and use my external installation for version 16.

I didn't know how to make helm upgrade do this. It's essentially what @headyj did in #14926 (comment) above.

@github-actions github-actions bot removed the stale 15 days without activity label Dec 7, 2023
@carrodher carrodher added in-progress and removed triage Triage is needed labels Dec 11, 2023
@github-actions github-actions bot assigned migruiz4 and unassigned CeliaGMqrz Dec 11, 2023
@migruiz4 migruiz4 added the on-hold Issues or Pull Requests with this label will never be considered stale label Dec 21, 2023
@exfly
Copy link

exfly commented Dec 25, 2023

I wrote a script for automatic major version upgrade bitnami/postgres-ha based on job under k8s for reference.

https://github.com/exfly/bitnami-pg-upgrade
https://exfly.github.io/postgres-upgrade-bitnami-ha/

@JosefWN
Copy link

JosefWN commented Jan 8, 2024

For more complex scenarios (such as in-place major version upgrades), perhaps it would be good to consider an operator rather than this helm chart?

Examples:
https://github.com/cloudnative-pg/cloudnative-pg
https://github.com/zalando/postgres-operator
https://github.com/CrunchyData/postgres-operator

peterstorm added a commit to peterstorm/.dotfiles that referenced this issue Jan 22, 2024
@cjvirtucio87
Copy link

I successfully updated from Chart v15 to v17 (and so from postgresql 15 to 16) using the following process:

* Update Chart version, keeping the same postgresql version (for now) by editing the values.yaml.

* Add a new fresh and separated postgresql instance with latest version, using the same credentials

Chart.yaml

apiVersion: v2
name: keycloak
type: application
version: 1.0.0
appVersion: "1.0.0"
dependencies:
- name: keycloak
  version: 17.3.1
  repository: https://charts.bitnami.com/bitnami
- name: postgresql
  alias: postgresql-16
  version: 13.2.9
  repository: https://charts.bitnami.com/bitnami

values.yaml

keycloak:
[...]
  postgresql:
    enabled: true
    image:
      registry: docker.io
      repository: bitnami/postgresql
      tag: 15.3.0-debian-11-r74
[...]
postgresql-16:
  architecture: standalone
  auth:
    username: keycloak
    database: keycloak
    existingSecret: keycloak-psql-secret
* connect on current postgresql pod and backup:
export PGPASSWORD=$POSTGRES_PASSWORD
pg_dumpall -U postgres > bitnami/postgresql/backup.sql
* copy the file into your new postgresql:
kubectl cp -n keycloak keycloak-postgresql-0:/bitnami/postgresql/backup.sql /tmp/backup.sql
kubectl cp -n keycloak /tmp/backup.sql keycloak-postgresql-16-0:/bitnami/postgresql/backup.sql
* connect to new postgresql pod and restore:
export PGPASSWORD=$POSTGRES_PASSWORD
psql -U postgres -h localhost -f /bitnami/postgresql/backup.sql
* be sure to check you have a key named `db-password` which match the `password` key in your psql secret. For any reason, the chart is not using the same key for internal vs external db:
$ kubectl get secret -n keycloak keycloak-psql-secret -o yaml
apiVersion: v1
data:
  db-password: ****
  password: ****
  postgres-password: ****
kind: Secret
[...]
* Change the configuration of your keycloak:
[...]
  postgresql:
    enabled: false ############################ Disable the current DB
    image:
      registry: docker.io
      repository: bitnami/postgresql
      tag: 15.3.0-debian-11-r74
    architecture: standalone
    auth:
      username: keycloak
      database: keycloak
      existingSecret: keycloak-psql-secret
  externalDatabase: ########################### Setup the new one
    host: keycloak-postgresql-16
    user: keycloak
    database: keycloak
    existingSecret: keycloak-psql-secret

I know It's not ideal, but it's working and is the only way I could safely update it. Also it should not lead to any downtime, except during restart if you're not in HA. You will just have to ensure that no data are created between backup and restore procedures.

this is what I did, as well. it's looking like relying on the embedded postgresql for keycloak isn't viable long-term. I also opted for neither using this chart nor the embedded postgresql on the keycloak chart and just managing postgresql entirely by myself.

slightly different steps that I took that's potentially a bit more scriptable:

  1. Dump the database:
    kubectl --namespace sso-dev exec --stdin keycloakx-postgresql-0 -- sh -c "PGPASSWORD=${KEYCLOAKX_POSTGRESQL_POSTGRES_PASSWORD} pg_dumpall --username=postgres --host=127.0.0.1 --port=5432 | base64" > /tmp/keycloakx-postgresql.sql.base64
  2. Scale down the statefulsets/keycloakx-postgresql:
    kubectl --namespace sso-dev scale --replicas=0 statefulsets/keycloakx-postgresql
  3. Delete the pvc:
    kubectl --namespace sso-dev delete pvc/data-keycloakx-postgresql-0
  4. Bump up the postgresql image version and redeploy
  5. Restore the database:
    kubectl --namespace sso-dev exec --stdin keycloakx-postgresql-0 -- sh -c "base64 -d | PGPASSWORD=${KEYCLOAKX_POSTGRESQL_POSTGRES_PASSWORD} psql --username=postgres --host=127.0.0.1 --port=5432 -f -" < /tmp/keycloakx-postgresql.sql.base64

@amorabito
Copy link

@cjvirtucio87 @headyj maybe I am doing these upgrades wrong but after importing the dump into postgres-16 and pointing keycloak to new postgres it is missing all clients and realms from old setup.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request on-hold Issues or Pull Requests with this label will never be considered stale postgresql
Projects
None yet
Development

No branches or pull requests