简体   繁体   English

如何在 Kubernetes 吊舱内升级 postgresql?

[英]How to upgrade postgresql inside a Kubernetes pod?

I have a kubernetes cluster running an app.我有一个运行应用程序的 kubernetes 集群。 Part of the cluster is a postgresql pod, currently running version 10.4.集群的一部分是 postgresql pod,当前运行版本 10.4。 Unfortunately, I discovered that I need to upgrade the postgresql version.不幸的是,我发现我需要升级 postgresql 版本。

The postgres yaml is as follow: postgres yaml 如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres
          image: postgres:10.4
          imagePullPolicy: "IfNotPresent"
          ports:
            - containerPort: 5432
          envFrom:
            - configMapRef:
                name: postgres-config
          volumeMounts:
            - mountPath: /var/lib/postgresql/data
              name: postgredb
      volumes:
        - name: postgredb
          persistentVolumeClaim:
            claimName: postgres-pv-claim

The postgresql database already has some data in it. postgresql 数据库中已经有一些数据。 I need to find a way to upgrade the cluster while in production.我需要找到一种在生产中升级集群的方法。

If I simply try to change the image to 12.0 and run kubectl apply I get an error:如果我只是尝试将映像更改为 12.0 并运行kubectl apply我会收到错误消息:

2020-11-15 22:48:08.332 UTC [1] DETAIL:  The data directory was initialized by PostgreSQL version 10, which is not compatible with this version 12.5 (Debian 12.5-1.pgdg100+1).

So I understand that I need to manually upgrade the postgres database inside the cluster, and only then I will be able to fix the yaml.所以我明白我需要手动升级集群内的postgres数据库,然后我才能修复yaml。 Is that correct?那是对的吗?

I tried @Justin method, but I encountered an issue that I couldn't stop current running postgres process inside the pod (for some reason inside the container there is no access to postgresql service. You can see more about that issue here )我尝试了@Justin 方法,但遇到了一个问题,即我无法停止 pod 内当前正在运行的 postgres 进程(由于某种原因,容器内无法访问 postgresql 服务。您可以在此处查看有关该问题的更多信息)

Since I couldn't upgrade the postgresql specifically inside the pod, what I did at the end is creating a parallel postgres pod in Kubernetes which holds the new version.由于我无法在 pod 内专门升级 postgresql,因此我最后所做的是在 Kubernetes 中创建一个并行的 postgres pod,该 pod 包含新版本。 Then I dumped database from old server, copied it to the new server, and used it to initialize the database there.然后我从旧服务器转储数据库,将其复制到新服务器,并用它来初始化那里的数据库。

Here are the steps one by one:以下是一一步骤:

  1. Create a parallel postgres service with the new version使用新版本创建并行 postgres 服务

  2. In old version pod:在旧版本的 pod 中:

pg_dumpall -U postgresadmin -h localhost -p 5432 > dumpall.sql
  1. In the host:在主机中:
kubectl cp postgres-old-pod:/dumpall.sql dumpall.sql
kubectl cp dumpall.sql postgres2-new-pod:/dumpall.sql
  1. ssh to new-pod ssh 到新的 pod

  2. extra step that I needed, becuase for some reason new pod didn't had 'postgres' user created: get into postgres client using your credentials:我需要的额外步骤,因为出于某种原因,新 pod 没有创建“postgres”用户:使用您的凭据进入 postgres 客户端:

psql postgresql://postgresadmin:pass1234@127.0.0.1:5432/postgresdb?sslmode=disable
postgresdb=# CREATE ROLE postgres LOGIN SUPERUSER PASSWORD 'somepassword123';

then exit postgres and exit to normal user然后退出 postgres 并退出到普通用户

  1. Finally update the database:最后更新数据库:
psql -U postgres -W -f dumpall.sql

Using this How to upgrade postgresql database from 10 to 12 without losing data for openproject as the basis for my post.使用这篇如何将 postgresql 数据库从 10 升级到 12 而不会丢失 openproject 的数据作为我帖子的基础。 I'm converting it to a container-with-volume friendly approach.我正在将其转换为容器体积友好的方法。 I am assuming you're using the official Postgresql image on Docker Hub.我假设您使用的是 Docker Hub 上的官方 Postgresql 映像。

  1. Backup the data - Out of scope for this answer.备份数据 - 超出此答案的范围。 There are other people better suited to answering that question.还有其他人更适合回答这个问题。

  2. Upgrade postgres from inside the pod and migrate the data Get a shell in your postgres pod从 pod 内部升级 postgres 并迁移数据 在你的 postgres pod 中获取一个 shell

# insert your pod and namespace here
kubectl exec -it postgresl-shsdjkfshd -n default /bin/sh 

Run the following inside the container在容器内运行以下命令

apt update
apt-get install postgresql-12 postgresql-server-dev-12
service postgresql stop
# Migrate the data
su postgres
/usr/lib/postgresql/12/bin/pg_upgrade \
     --old-datadir=/var/lib/postgresql/10/main \
     --new-datadir=/var/lib/postgresql/12/main \
     --old-bindir=/usr/lib/postgresql/10/bin \
     --new-bindir=/usr/lib/postgresql/12/bin \
     --old-options '-c config_file=/etc/postgresql/10/main/postgresql.conf' \
     --new-options '-c config_file=/etc/postgresql/12/main/postgresql.conf'
exit # exits the postgres user

The next bit is verbatim taken from the linked post:下一位是从链接的帖子中逐字提取的:

  1. Swap the ports the old and new postgres versions.交换新旧 postgres 版本的端口。
     vim /etc/postgresql/12/main/postgresql.conf
     #change port to 5432
     vim /etc/postgresql/10/main/postgresql.conf
     #change port to 5433
  1. Start the postgresql service启动 postgresql 服务
     service postgresql start
  1. Log in as postgres user以 postgres 用户身份登录
     su postgres
  1. Check your new postgres version检查您的新 postgres 版本
     psql -c "SELECT version();"
  1. Run the generated new cluster script运行生成的新集群脚本
     ./analyze_new_cluster.sh
  1. Return as a normal(default user) user and cleanup up the old version's mess以普通(默认用户)用户身份返回并清理旧版本的混乱
     apt-get remove postgresql-10 postgresql-server-dev-10
     #uninstalls postgres packages
     rm -rf /etc/postgresql/10/
     #removes the old postgresql directory
     su postgres
     #login as postgres user
     ./delete_old_cluster.sh
     #delete the old cluster data
  1. Now change the deployment YAML image reference to the Postgres 12 and kubectl apply现在将部署 YAML 图像引用更改为 Postgres 12 和kubectl apply

  2. Check the logs to see if it started up correctly.检查日志以查看它是否正确启动。

Thanks to @justadev for the answer.感谢@justadev 的回答。 Some additions:一些补充:

psql -U postgres -d keycloak -W -f dumpall.sql

I had to add the -d keycloak database flag because while the psql log was OK during the import, the data was missing in the database afterwards.我必须添加-d keycloak数据库标志,因为虽然psql日志在导入过程中正常,但之后数据库中的数据丢失了。 You need to explicitly indicate the database for psql .您需要明确指出psql的数据库。

So, check the psql flags here: https://www.postgresql.org/docs/current/app-psql.html因此,请在此处检查psql标志: https://www.postgresql.org/docs/current/app-psql.html

By the way, I managed to upgrade from Postgres 11 to Posgres 14.5 this way.顺便说一句,我设法通过这种方式从 Postgres 11 升级到 Posgres 14.5。

Also, I want to add this: tar may be absent on a pod, this means that kubectl cp will not work.另外,我想补充一点: tar可能在 pod 上不存在,这意味着kubectl cp将不起作用。

Here is the workaround:这是解决方法:

  1. Copy data from a pod to a local machine:将数据从 pod 复制到本地机器:
kubectl exec -n ${namespace} ${postgresql_pod} -- cat db_dump.sql  > db_dump.sql
  1. Copy data from a local machine to a pod:将数据从本地机器复制到 pod:
cat db_dump.sql | kubectl exec -i -n ${namespace} ${postgresql_pod} "--" sh -c "cat > db_dump.sql"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM