Help us learn about your current experience with the documentation. Take the survey.

为 Auto DevOps 升级 PostgreSQL

  • Tier: Free, Premium, Ultimate
  • Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated

POSTGRES_ENABLEDtrue 时,Auto DevOps 会为您的应用提供一个 集群内 PostgreSQL 数据库

用于部署 PostgreSQL 的 chart 版本:

  • 可以设置为 0.7.1 到 8.2.1 之间。

GitLab 鼓励用户将数据库迁移到较新的 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 数据库

如果您已配置 Auto DevOps 包含 staging 环境, 建议先在 staging 环境中尝试备份和恢复步骤, 或者在 review app 上进行测试。

将您的应用下线

如果需要,将您的应用下线,以防止在创建数据库转储后数据库被修改。

  1. 获取环境的 Kubernetes 命名空间。它通常看起来像 <项目名>-<项目ID>-<环境>。 在我们的示例中,命名空间名为 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,也必须将其副本数设置为 0。

备份

  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

      ## 格式为:
      # 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

保留持久卷

默认情况下,用于存储 PostgreSQL 底层数据的 持久卷 在使用该卷的 pod 和 pod 声明被删除时会被标记为 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 和 production 环境的卷, 这里的卷名称是 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

使用较新版本的 PostgreSQL 会删除 旧的 0.7.1 PostgreSQL。为防止底层数据被删除, 您可以选择保留 持久卷

您还可以 限定 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 通常是环境名称。
    ## 格式为:
    # 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 管道。管道成功后,您的 应用应该像以前一样接收流量。