为 Auto DevOps 升级 PostgreSQL
- Tier: Free, Premium, Ultimate
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
当 POSTGRES_ENABLED 为 true 时,Auto DevOps 会为您的应用提供一个
集群内 PostgreSQL 数据库。
用于部署 PostgreSQL 的 chart 版本:
- 可以设置为 0.7.1 到 8.2.1 之间。
GitLab 鼓励用户将数据库迁移到较新的 PostgreSQL chart。
本指南提供了如何迁移 PostgreSQL 数据库的说明,包括:
- 对数据进行数据库转储。
- 使用 chart 的新版本 8.2.1 安装新的 PostgreSQL 数据库,并移除旧的 PostgreSQL 安装。
- 将数据库转储恢复到新的 PostgreSQL 中。
前置条件
- 安装
kubectl。 - 确保您可以使用
kubectl访问您的 Kubernetes 集群。 这取决于 Kubernetes 提供商。 - 准备停机时间。以下步骤包括将应用下线, 以确保在创建数据库转储后,集群内数据库不会被修改。
- 确保您没有将
POSTGRES_ENABLED设置为false,因为此设置会删除 任何现有的 channel 1 数据库。更多信息,请参见 检测到现有的 PostgreSQL 数据库。
如果您已配置 Auto DevOps 包含 staging 环境, 建议先在 staging 环境中尝试备份和恢复步骤, 或者在 review app 上进行测试。
将您的应用下线
如果需要,将您的应用下线,以防止在创建数据库转储后数据库被修改。
-
获取环境的 Kubernetes 命名空间。它通常看起来像
<项目名>-<项目ID>-<环境>。 在我们的示例中,命名空间名为minimal-ruby-app-4349298-production。$ kubectl get ns NAME STATUS AGE minimal-ruby-app-4349298-production Active 7d14h -
为方便使用,导出命名空间名称:
export APP_NAMESPACE=minimal-ruby-app-4349298-production -
使用以下命令获取您应用的部署名称。在我们的示例中,部署名称为
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 -
为防止数据库被修改,使用以下命令将部署的副本数设置为 0。 我们使用上一步中的部署名称(
deployments/<DEPLOYMENT_NAME>)。$ kubectl scale --replicas=0 deployments/production --namespace "$APP_NAMESPACE" deployment.extensions/production scaled -
如果您有任何 worker,也必须将其副本数设置为 0。
备份
-
获取 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 -
使用以下命令获取 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 -
连接到 pod:
kubectl exec -it production-postgres-5db86568d7-qxlxv --namespace "$APP_NAMESPACE" -- bash -
连接后,使用以下命令创建转储文件。
-
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
-
-
备份转储完成后,使用
Control-D或exit退出 Kubernetes exec 进程。 -
使用以下命令下载转储文件:
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-42010a8e0096 和 pvc-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_CHANNEL、AUTO_DEVOPS_POSTGRES_DELETE_V1 和
POSTGRES_VERSION 变量的作用域到特定环境,例如 staging。
- 将
AUTO_DEVOPS_POSTGRES_CHANNEL设置为2。这表示使用 基于 8.2.1 的较新 PostgreSQL,并移除基于 0.7.1 的 旧 PostgreSQL。 - 将
AUTO_DEVOPS_POSTGRES_DELETE_V1设置为非空值。此标志是一个 安全措施,防止意外删除数据库。 - 如果您设置了
POSTGRES_VERSION,请确保它设置为9.6.16或更高版本。这是 Auto DevOps 支持的最低 PostgreSQL 版本。另请参阅 可用标签列表。 - 将
PRODUCTION_REPLICAS设置为0。对于其他环境,使用 带有 环境作用域 的REPLICAS。 - 如果您设置了
DB_INITIALIZE或DB_MIGRATE变量,请 删除这些变量,或者临时将变量重命名为XDB_INITIALIZE或XDB_MIGRATE以禁用它们。 - 为分支运行新的 CI 管道。在这种情况下,我们为
main运行新的 CI 管道。 - 管道成功后,您的应用将升级为使用新安装的 PostgreSQL。 此时副本数为零,因此您的应用不会接收流量(以防止 新数据进入)。
恢复
-
获取新 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 -
将备份步骤中的转储文件复制到 pod:
kubectl cp --namespace "$APP_NAMESPACE" backup.sql production-postgresql-0:/tmp/backup.sql -
连接到 pod:
kubectl exec -it production-postgresql-0 --namespace "$APP_NAMESPACE" -- bash -
连接到 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 - 当提示输入数据库密码时,默认为
-
恢复完成后,您现在可以检查数据是否已正确恢复。 您可以使用
psql对数据进行抽查。
恢复您的应用
当您确认数据库已恢复后,运行以下步骤来恢复您的应用:
- 如果之前已删除或禁用,请恢复
DB_INITIALIZE和DB_MIGRATE变量。 - 将
PRODUCTION_REPLICAS或REPLICAS变量恢复为原始值。 - 为分支运行新的 CI 管道。在这种情况下,我们为
main运行新的 CI 管道。管道成功后,您的 应用应该像以前一样接收流量。