为 Auto DevOps 升级 PostgreSQL

Auto DevOps 为您的应用程序提供集群内 PostgreSQL 数据库

用于配置 PostgreSQL 的 chart 版本:

  • 在 12.8 及更早版本中为 0.7.1。
  • 在 12.9 及更高版本中,可以设置为从 0.7.1 到 8.2.1。

建议用户将数据库迁移到更新的 PostgreSQL chart。

本指南提供有关如何迁移 PostgreSQL 数据库的说明,其中包括:

  1. 对您的数据进行数据库转储。
  2. 使用 chart 的较新版本 8.2.1 安装新的 PostgreSQL 数据库并删除旧的 PostgreSQL 安装。
  3. 将数据库转储恢复到新的 PostgreSQL。

先决条件

  1. 安装 kubectl
  2. 确保您可以使用 kubectl 访问您的 Kubernetes 集群,因 Kubernetes 提供商而异。
  3. 准备停机。以下步骤包括使应用程序离线,以便在创建数据库转储后不会修改集群内数据库。
  4. 确保您没有将 POSTGRES_ENABLED 设置为 false,因为此设置会删除任何现有的 channel 1 数据库。有关详细信息,请参阅检测到现有 PostgreSQL 数据库
note如果您已将 Auto DevOps 配置为 staging,请考虑先在 staging 尝试备份和恢复步骤,或在 review app 上尝试。

使您的应用程序离线

如果需要,使您的应用程序离线,防止在创建数据库转储后修改数据库。

  1. 获取环境的 Kubernetes 命名空间。它通常看起来像 <project-name>-<project-id>-<environment>。在示例中,命名空间为 minimal-ruby-app-4349298-production

     $ kubectl get ns
    
     NAME                                                  STATUS   AGE
     minimal-ruby-app-4349298-production                   Active   7d14h
    
  2. 为了方便使用,导出命名空间名称:

    export APP_NAMESPACE=minimal-ruby-app-4349298-production
    
  3. 使用以下命令获取应用程序的部署名称。在示例中,部署名称是 production

     $ kubectl get deployment --namespace "$APP_NAMESPACE"
     NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
     production            2/2     2            2           7d21h
     production-postgres   1/1     1            1           7d21h
    
  4. 为防止数据库被修改,请使用以下命令将部署的副本数设置为 0。使用上一步中的部署名称 (deployments/<DEPLOYMENT_NAME>)。

     $ kubectl scale --replicas=0 deployments/production --namespace "$APP_NAMESPACE"
     deployment.extensions/production scaled
    
  5. 如果您有任何 worker,您还必须将副本设置为零。

备份

  1. 获取 PostgreSQL 的服务名称。服务名称应以 -postgres 结尾。在示例中,服务名称是 production-postgres

     $ kubectl get svc --namespace "$APP_NAMESPACE"
     NAME                     TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
     production-auto-deploy   ClusterIP   10.30.13.90   <none>        5000/TCP   7d14h
     production-postgres      ClusterIP   10.30.4.57    <none>        5432/TCP   7d14h
    
  2. 使用以下命令获取 PostgreSQL 的 pod 名称。在示例中,pod 名称是 production-postgres-5db86568d7-qxlxv

     $ kubectl get pod --namespace "$APP_NAMESPACE" -l app=production-postgres
     NAME                                   READY   STATUS    RESTARTS   AGE
     production-postgres-5db86568d7-qxlxv   1/1     Running   0          7d14h
    
  3. 使用以下命令连接到 pod:

     kubectl exec -it production-postgres-5db86568d7-qxlxv --namespace "$APP_NAMESPACE" -- bash
    
  4. 连接后,使用以下命令创建转储文件。

    • SERVICE_NAME 是上一步获得的服务名称。
    • USERNAME 是您为 PostgreSQL 配置的用户名。默认为 user
    • DATABASE_NAME 通常是环境名称。

    • 当提示输入数据库密码时,默认为 testing-password
     ## Format is:
     # pg_dump -h SERVICE_NAME -U USERNAME DATABASE_NAME > /tmp/backup.sql
    
     pg_dump -h production-postgres -U user production > /tmp/backup.sql
    
  5. 备份转储完成后,使用 Control-Dexit 退出 Kubernetes exec 进程。

  6. 使用以下命令下载转储文件:

     kubectl cp --namespace "$APP_NAMESPACE" production-postgres-5db86568d7-qxlxv:/tmp/backup.sql backup.sql
    

保留持久卷

默认情况下,当删除使用该卷的 pod 和 pod 声明时,用于存储 PostgreSQL 基础数据的持久卷被标记为 Delete

当您选择使用较新的 8.2.1 PostgreSQL 时,旧的 0.7.1 PostgreSQL 将被删除,从而导致持久卷也被删除。

您可以使用以下命令验证这一点:

$ kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                                                     STORAGECLASS   REASON   AGE
pvc-0da80c08-5239-11ea-9c8d-42010a8e0096   8Gi        RWO            Delete           Bound    minimal-ruby-app-4349298-staging/staging-postgres         standard                7d22h
pvc-9085e3d3-5239-11ea-9c8d-42010a8e0096   8Gi        RWO            Delete           Bound    minimal-ruby-app-4349298-production/production-postgres   standard                7d22h

为了保留持久卷,即使旧的 0.7.1 PostgreSQL 被删除,我们也可以将保留策略更改为 Retain。在此示例中,我们通过查看声明名称来找到持久卷名称。由于我们有兴趣保留用于 minimal-ruby-app-4349298 应用程序的 staging 和生产环境的卷,因此这里的卷名称是 pvc-0da80c08-5239-11ea-9c8d-42010a8e0096pvc-9085e3d3- 5239-11ea-9c8d-42010a8e0096

$ kubectl patch pv  pvc-0da80c08-5239-11ea-9c8d-42010a8e0096 -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'
persistentvolume/pvc-0da80c08-5239-11ea-9c8d-42010a8e0096 patched
$ kubectl patch pv  pvc-9085e3d3-5239-11ea-9c8d-42010a8e0096 -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'
persistentvolume/pvc-9085e3d3-5239-11ea-9c8d-42010a8e0096 patched
$ kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                                                     STORAGECLASS   REASON   AGE
pvc-0da80c08-5239-11ea-9c8d-42010a8e0096   8Gi        RWO            Retain           Bound    minimal-ruby-app-4349298-staging/staging-postgres         standard                7d22h
pvc-9085e3d3-5239-11ea-9c8d-42010a8e0096   8Gi        RWO            Retain           Bound    minimal-ruby-app-4349298-production/production-postgres   standard                7d22h

安装新的 PostgreSQL

caution使用较新版本的 PostgreSQL 会删除较旧的 0.7.1 PostgreSQL。为了防止底层数据被删除,您可以选择保留持久卷
note您还可以将 AUTO_DEVOPS_POSTGRES_CHANNELAUTO_DEVOPS_POSTGRES_DELETE_V1POSTGRES_VERSION 变量限定到特定环境,例如,staging
  1. AUTO_DEVOPS_POSTGRES_CHANNEL 设置为 2。选择使用较新的基于 8.2.1 的 PostgreSQL,并删除旧的基于 0.7.1 的 PostgreSQL。
  2. AUTO_DEVOPS_POSTGRES_DELETE_V1 设置为非空值。此标志是防止意外删除数据库的保护措施。
  3. 如果您设置了 POSTGRES_VERSION,请确保将其设置为 9.6.16 或更高版本。这是 Auto DevOps 支持的最低 PostgreSQL 版本。另请参阅可用标签列表。
  4. PRODUCTION_REPLICAS 设置为 0。对于其它环境,使用带有环境范围REPLICAS
  5. 如果您设置了 DB_INITIALIZEDB_MIGRATE 变量,请删除这些变量,或将变量暂时重命名为 XDB_INITIALIZEXDB_MIGRATE 以有效禁用它们。
  6. 为分支运行一个新的 CI 流水线。在这种情况下,我们为 main 运行一个新的 CI 流水线。
  7. 流水线成功后,您的应用程序将升级并安装新的 PostgreSQL。此时存在零副本,因此不会为您的应用程序提供流量(以防止新数据进入)。

恢复

  1. 获取新 PostgreSQL 的 pod 名称,在我们的示例中,pod 名称为 production-postgresql-0

     $ kubectl get pod --namespace "$APP_NAMESPACE" -l app=postgresql
     NAME                      READY   STATUS    RESTARTS   AGE
     production-postgresql-0   1/1     Running   0          19m
    
  2. 将备份步骤中的转储文件复制到 pod:

    kubectl cp --namespace "$APP_NAMESPACE" backup.sql production-postgresql-0:/tmp/backup.sql
    
  3. 连接到 pod:

    kubectl exec -it production-postgresql-0 --namespace "$APP_NAMESPACE" -- bash
    
  4. 连接到 pod 后,运行以下命令来恢复数据库。

    • 当询问数据库密码时,默认为 testing-password
    • USERNAME 是您为 PostgreSQL 配置的用户名。默认为 user
    • DATABASE_NAME 通常是环境名称。
    ## Format is:
    # psql -U USERNAME -d DATABASE_NAME < /tmp/backup.sql
    
    psql -U user -d production < /tmp/backup.sql
    
  5. 您现在可以在还原完成后检查您的数据是否正确恢复。您可以使用 psql 对数据进行抽查。

恢复您的应用

一旦您对数据库已恢复感到满意,请运行以下步骤来恢复您的应用程序:

  1. 恢复 DB_INITIALIZEDB_MIGRATE 变量,如果之前已删除或禁用。
  2. PRODUCTION_REPLICASREPLICAS 变量恢复为其原始值。
  3. 为分支运行一个新的 CI 流水线。在这种情况下,我们为 main 运行一个新的 CI 流水线。流水线成功后,您的应用程序应该像以前一样提供服务。