You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

K8s升级PostgreSQL9.6至14.x时保留旧文件的YAML配置问询

核心前提说明

直接修改PostgreSQL镜像版本无法直接启动,三个核心原因:

  • PostgreSQL跨大版本不兼容旧格式数据文件,9.6版本的数据文件无法被14版本直接加载,必须通过pg_upgrade做格式转换
  • 官方PostgreSQL镜像的版本二进制文件存放在容器内非持久化路径/usr/lib/postgresql/<版本号>/bin,Pod重建后旧版本bin文件会直接丢失,必须提前持久化留存
  • 你当前配置已经将/var/lib/postgresql挂载到PVC,旧版本9.6的数据文件已经持久化,不会因为Pod重建丢失
前置操作(仅需执行1次)

在修改Deployment YAML执行apply之前,先进入当前运行的9.6版本PostgreSQL Pod,将旧版本bin文件复制到持久化目录留存:

kubectl exec -it <当前运行的postgres Pod名称> -- bash -c "mkdir -p /var/lib/postgresql/bin/9.6 && cp -r /usr/lib/postgresql/9.6/bin/* /var/lib/postgresql/bin/9.6/"
修改后的完整Deployment YAML
apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        name: postgres
    spec:
      initContainers:
      - name: prep-new-version
        image: postgres:14
        imagePullPolicy: Never
        command:
        - bash
        - -c
        - |
          mkdir -p /pg-storage/bin/14 /pg-storage/14/data
          cp -r /usr/lib/postgresql/14/bin/* /pg-storage/bin/14/
          chown -R postgres:postgres /pg-storage/
          chmod 700 /pg-storage/9.6/data /pg-storage/14/data
        volumeMounts:
        - mountPath: /pg-storage
          name: postgres-persistent-storage
      containers:
      - name: postgres
        imagePullPolicy: Never
        image: postgres:14
        ports:
        - name: postgres
          containerPort: 5432
        env:
        - name: POSTGRES_INITDB_ARGS
          value: "--encoding=UTF8 --locale=C"
        command:
        - bash
        - -c
        - |
          # 首次启动检测新数据目录是否存在,不存在则执行升级
          if [ ! -f /var/lib/postgresql/14/data/PG_VERSION ]; then
            # 初始化14版本空数据目录
            su postgres -c "/usr/lib/postgresql/14/bin/initdb -D /var/lib/postgresql/14/data $POSTGRES_INITDB_ARGS"
            # 执行升级预检查
            su postgres -c "/usr/lib/postgresql/14/bin/pg_upgrade \
              -b /var/lib/postgresql/bin/9.6 \
              -B /var/lib/postgresql/bin/14 \
              -d /var/lib/postgresql/9.6/data \
              -D /var/lib/postgresql/14/data \
              --check"
            if [ $? -ne 0 ]; then
              echo "PostgreSQL升级预检查失败,请校验旧数据完整性"
              exit 1
            fi
            # 执行正式升级
            su postgres -c "/usr/lib/postgresql/14/bin/pg_upgrade \
              -b /var/lib/postgresql/bin/9.6 \
              -B /var/lib/postgresql/bin/14 \
              -d /var/lib/postgresql/9.6/data \
              -D /var/lib/postgresql/14/data"
          fi
          # 升级完成后按官方默认逻辑启动数据库
          exec docker-entrypoint.sh postgres
        volumeMounts:
        - mountPath: /var/lib/postgresql
          name: postgres-persistent-storage
      volumes:
      - name: postgres-persistent-storage
        persistentVolumeClaim:
          claimName: postgres-pv-claim
关键改动说明
  • 将已经废弃的extensions/v1beta1 API替换为稳定版apps/v1,兼容所有现行K8s版本
  • 新增Recreate发布策略,升级过程中会先销毁旧Pod再创建新Pod,避免多实例同时读写同一个PVC导致数据损坏
  • 新增初始化容器,新Pod启动前自动将14版本的二进制文件复制到PVC持久化留存,和旧版本bin、data目录统一存放,不会因为Pod重建丢失
  • 新增容器启动逻辑:第一次启动14版本时自动完成数据目录初始化、升级预检查、版本升级全流程,升级完成后后续重启会直接启动14版本数据库,不会重复执行升级操作
  • 所有旧版本9.6的bin、data文件都会完整保留在PVC中,后续需要回滚时只需要将镜像切回postgres:9.6,指定PGDATA为旧版本数据路径即可快速回滚
注意事项
  • 升级前建议对绑定的PV做快照备份,避免升级过程异常导致数据损坏
  • 升级完成后旧版本数据目录不会自动删除,确认业务运行正常不需要回滚后,可以手动进入容器删除/var/lib/postgresql/9.6目录释放存储空间
  • 如果你本地的postgres:14镜像自定义了数据目录或二进制路径,对应调整YAML里的路径值即可

内容的提问来源于stack exchange,提问作者hammer89

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 23:54:18