备份和恢复大型参考架构
本文档描述了如何:
本文档适用于以下环境:
- Linux 软件包(Omnibus)和云原生混合参考架构 60 RPS / 3,000 用户及以上
- Amazon RDS 用于 PostgreSQL 数据
- Amazon S3 用于对象存储
- 对象存储 用于存储所有可能的内容,包括 blobs 和 容器注册表
配置每日备份
配置 PostgreSQL 数据的备份
备份命令 使用 pg_dump
,对于 超过 100 GB 的数据库不合适。必须选择具有原生、强大备份功能的 PostgreSQL 解决方案。
::Tabs
:::TabTitle AWS
- 配置 AWS Backup 备份 RDS(和 S3)数据。为了最大保护,配置连续备份和快照备份。
- 配置 AWS Backup 将备份复制到一个单独的区域。当 AWS 进行备份时,备份只能在存储备份的区域恢复。
- 在 AWS Backup 至少运行一次计划备份之后,可以根据需要创建按需备份。
::EndTabs
配置对象存储数据的备份
建议使用 对象存储(不是 NFS)存储极狐GitLab 数据,包括 blobs 和 容器注册表。
::Tabs
:::TabTitle AWS
配置 AWS Backup 以备份 S3 数据。这可以在配置 PostgreSQL 数据备份时同时完成。
::EndTabs
配置 Git 仓库的备份
设置 cronjobs 执行 Gitaly 服务端备份:
::Tabs
:::TabTitle Linux 软件包(Omnibus)
- 在所有 Gitaly 节点中配置服务端备份目标。
- 配置上传备份到远程(云)存储。尽管 Gitaly 将所有 Git 数据备份到其自己的对象存储桶中,但
gitlab-backup
命令还会创建一个包含备份元数据的tar
文件。恢复命令需要此tar
文件。 - 确保将两个存储桶都添加到对象存储数据的备份中。
- 通过 SSH 登录到一个极狐GitLab Rails 节点,该节点运行 Puma 或 Sidekiq。
-
对 Git 数据进行完整备份。使用
REPOSITORIES_SERVER_SIDE
变量,并跳过 PostgreSQL 数据:sudo gitlab-backup create REPOSITORIES_SERVER_SIDE=true SKIP=db
这会导致 Gitaly 节点将 Git 数据和一些元数据上传到远程存储。诸如上传、工件和 LFS 的 blobs 不需要明确跳过,因为
gitlab-backup
命令默认不备份对象存储。 - 注意备份的 备份 ID,恢复时需要。例如,如果备份命令输出
2024-02-22 02:17:47 UTC -- Backup 1708568263_2024_02_22_16.9.0-ce is done.
,则备份 ID 为1708568263_2024_02_22_16.9.0-ce
。 - 检查完整备份是否在 Gitaly 备份存储桶和常规备份存储桶中创建了数据。
-
再次运行 备份命令,这次指定 Git 仓库的增量备份,并提供一个备份 ID。使用上一步中的示例 ID,命令为:
sudo gitlab-backup create REPOSITORIES_SERVER_SIDE=true SKIP=db INCREMENTAL=yes PREVIOUS_BACKUP=1708568263_2024_02_22_16.9.0-ce
此命令不使用
PREVIOUS_BACKUP
的值,但命令需要它。有关删除此不必要要求的问题,请参阅 issue 429141。 - 检查增量备份是否成功,并将数据添加到对象存储中。
-
配置 cron 执行每日备份。编辑
root
用户的 crontab:
sudo su -
crontab -e
- 在其中,添加以下行以安排每个月每天凌晨 2 点的备份。为了限制恢复备份所需的增量数量,每月的第一天将进行 Git 仓库的完整备份,其余的天数将进行增量备份:
0 2 1 * * /opt/gitlab/bin/gitlab-backup create REPOSITORIES_SERVER_SIDE=true SKIP=db CRON=1
0 2 2-31 * * /opt/gitlab/bin/gitlab-backup create REPOSITORIES_SERVER_SIDE=true SKIP=db INCREMENTAL=yes PREVIOUS_BACKUP=1708568263_2024_02_22_16.9.0-ce CRON=1
:::TabTitle Helm chart(Kubernetes)
- 在所有 Gitaly 节点中配置服务端备份目标。
-
为备份实用工具配置对象存储桶。尽管 Gitaly 将所有 Git 数据备份到其自己的对象存储桶中,但
backup-utility
命令还会创建一个包含备份元数据的tar
文件。恢复命令需要此tar
文件。 - 确保将两个存储桶都添加到对象存储数据的备份中。
-
对 Git 数据进行完整备份。使用
--repositories-server-side
选项,并跳过所有其他数据:kubectl exec <Toolbox pod name> -it -- backup-utility --repositories-server-side --skip db,builds,pages,registry,uploads,artifacts,lfs,packages,external_diffs,terraform_state,pages,ci_secure_files
这会导致 Gitaly 节点将 Git 数据和一些元数据上传到远程存储。
- 检查完整备份是否在 Gitaly 备份存储桶和常规备份存储桶中创建了数据。
backup-utility
不支持使用服务端仓库备份的增量仓库备份。 -
配置 cron 执行每日备份。具体来说,设置
gitlab.toolbox.backups.cron.extraArgs
以包含:--repositories-server-side --skip db --skip repositories --skip uploads --skip builds --skip artifacts --skip pages --skip lfs --skip terraform_state --skip registry --skip packages --skip ci_secure_files
::EndTabs
配置配置文件的备份
如果配置和密钥在部署之外定义然后部署到其中,则备份策略的实施取决于具体设置和要求。作为示例,可以将密钥存储在 AWS Secret Manager 中,并复制到多个区域,并配置脚本以自动备份密钥。
如果配置和密钥仅在部署内定义:
- 存储配置文件 描述了如何提取配置和密钥文件。
- 这些文件应上传到一个单独的、更严格的对象存储帐户中。
恢复备份
恢复极狐GitLab 实例的备份。
先决条件
在恢复备份之前:
- 选择一个正在工作的目标极狐GitLab 实例。
- 确保目标极狐GitLab 实例位于存储 AWS 备份的区域。
- 检查目标极狐GitLab 实例使用与备份数据创建时完全相同的版本和类型(CE 或 EE)。例如,CE 15.1.4。
- 将备份的密钥恢复到目标极狐GitLab 实例。
- 确保目标极狐GitLab 实例配置了相同的仓库存储。其他存储是可以的。
- 确保配置了对象存储。
-
要使用新的密钥或配置,并避免在恢复过程中遇到任何意外的配置更改:
- 在所有节点上的 Linux 软件包安装:
-
Helm chart(Kubernetes)安装:
-
在所有极狐GitLab Linux 软件包节点上,运行:
sudo gitlab-ctl reconfigure sudo gitlab-ctl start
-
通过部署图表确保有一个正在运行的极狐GitLab 实例。通过执行以下命令确保 Toolbox pod 已启用并运行:
kubectl get pods -lrelease=RELEASE_NAME,app=toolbox
-
Webservice、Sidekiq 和 Toolbox pods 必须重新启动。重新启动这些 pods 的最安全方法是运行:
kubectl delete pods -lapp=sidekiq,release=<helm release name> kubectl delete pods -lapp=webservice,release=<helm release name> kubectl delete pods -lapp=toolbox,release=<helm release name>
-
-
确认目标极狐GitLab 实例仍然有效。例如:
- 向健康检查端点发出请求。
- 运行极狐GitLab 检查 Rake 任务。
-
停止连接到 PostgreSQL 数据库的极狐GitLab 服务。
-
在所有运行 Puma 或 Sidekiq 的节点上的 Linux 软件包安装,运行:
sudo gitlab-ctl stop
-
Helm chart(Kubernetes)安装:
-
注意数据库客户端的当前副本数量以便后续重启:
kubectl get deploy -n <namespace> -lapp=sidekiq,release=<helm release name> -o jsonpath='{.items[].spec.replicas}{"\n"}' kubectl get deploy -n <namespace> -lapp=webservice,release=<helm release name> -o jsonpath='{.items[].spec.replicas}{"\n"}' kubectl get deploy -n <namespace> -lapp=prometheus,release=<helm release name> -o jsonpath='{.items[].spec.replicas}{"\n"}'
-
停止数据库的客户端以防止锁定干扰恢复过程:
kubectl scale deploy -lapp=sidekiq,release=<helm release name> -n <namespace> --replicas=0 kubectl scale deploy -lapp=webservice,release=<helm release name> -n <namespace> --replicas=0 kubectl scale deploy -lapp=prometheus,release=<helm release name> -n <namespace> --replicas=0
-
-
恢复对象存储数据
::Tabs
:::TabTitle AWS
每个存储桶在 AWS 中作为单独的备份存在,每个备份可以恢复到现有或新的存储桶。
-
要恢复存储桶,需要具有正确权限的 IAM 角色:
AWSBackupServiceRolePolicyForBackup
AWSBackupServiceRolePolicyForRestores
AWSBackupServiceRolePolicyForS3Restore
AWSBackupServiceRolePolicyForS3Backup
- 如果使用现有存储桶,它们必须启用访问控制列表。
- 使用内置工具恢复 S3 存储桶。
- 在恢复作业运行时,可以继续恢复 PostgreSQL 数据。
::EndTabs
恢复 PostgreSQL 数据
::Tabs
:::TabTitle AWS
- 使用内置工具恢复 AWS RDS 数据库,这会创建一个新的 RDS 实例。
-
由于新的 RDS 实例具有不同的端点,必须重新配置目标极狐GitLab 实例以指向新数据库:
-
对于 Linux 软件包安装,参阅使用非打包的 PostgreSQL 数据库管理服务器。
-
对于 Helm chart(Kubernetes)安装,参阅使用外部数据库配置极狐GitLab 图表。
-
- 在继续之前,等待新的 RDS 实例创建完成并准备好使用。
::EndTabs
恢复 Git 仓库
首先,作为恢复对象存储数据的一部分,您应该已经:
- 恢复了一个包含 Gitaly 服务端备份的 Git 仓库的存储桶。
- 恢复了一个包含
*_gitlab_backup.tar
文件的存储桶。
::Tabs
:::TabTitle Linux 软件包(Omnibus)
- 通过 SSH 登录到一个极狐GitLab Rails 节点,该节点运行 Puma 或 Sidekiq。
- 在备份存储桶中,根据其时间戳选择一个
*_gitlab_backup.tar
文件,与恢复的 PostgreSQL 和对象存储数据对齐。 - 将
tar
文件下载到/var/opt/gitlab/backups/
中。 -
恢复备份,指定要恢复的备份 ID,省略
_gitlab_backup.tar
:# 此命令将覆盖极狐GitLab 数据库的内容! sudo gitlab-backup restore BACKUP=11493107454_2018_04_25_10.6.4-ce SKIP=db
如果备份 tar 文件与安装的极狐GitLab 版本之间存在不匹配,恢复命令将中止并显示错误消息。安装正确的极狐GitLab 版本,然后重试。
-
重启并检查极狐GitLab:
-
在所有 Puma 或 Sidekiq 节点上,运行:
sudo gitlab-ctl restart
-
在一个 Puma 或 Sidekiq 节点上,运行:
sudo gitlab-rake gitlab:check SANITIZE=true
-
-
检查数据库值是否可以解密,特别是如果
/etc/gitlab/gitlab-secrets.json
已恢复,或者如果不同的服务器是恢复的目标:在一个 Puma 或 Sidekiq 节点上,运行:
sudo gitlab-rake gitlab:doctor:secrets
-
为了增加保证,可以对上传的文件执行完整性检查:
在一个 Puma 或 Sidekiq 节点上,运行:
sudo gitlab-rake gitlab:artifacts:check sudo gitlab-rake gitlab:lfs:check sudo gitlab-rake gitlab:uploads:check
如果发现缺失或损坏的文件,并不总是意味着备份和恢复过程失败。例如,文件可能在源极狐GitLab 实例上丢失或损坏。可能需要交叉引用先前的备份。如果您正在将极狐GitLab 迁移到新环境,可以在源极狐GitLab 实例上运行相同的检查,以确定完整性检查结果是预先存在的还是与备份和恢复过程相关。
:::TabTitle Helm chart(Kubernetes)
- SSH 进入 Toolbox pod。
- 在备份存储桶中,根据其时间戳选择一个
*_gitlab_backup.tar
文件,与恢复的 PostgreSQL 和对象存储数据对齐。 - 将
tar
文件下载到/var/opt/gitlab/backups/
中。 -
恢复备份,指定要恢复的备份 ID,省略
_gitlab_backup.tar
:# 此命令将覆盖 Gitaly 的内容! kubectl exec <Toolbox pod name> -it -- backup-utility --restore -t 11493107454_2018_04_25_10.6.4-ce --skip db,builds,pages,registry,uploads,artifacts,lfs,packages,external_diffs,terraform_state,pages,ci_secure_files
如果备份 tar 文件与安装的极狐GitLab 版本之间存在不匹配,恢复命令将中止并显示错误消息。安装正确的极狐GitLab 版本,然后重试。
-
重启并检查极狐GitLab:
-
启动停止的部署,使用先决条件中记下的副本数:
kubectl scale deploy -lapp=sidekiq,release=<helm release name> -n <namespace> --replicas=<original value> kubectl scale deploy -lapp=webservice,release=<helm release name> -n <namespace> --replicas=<original value> kubectl scale deploy -lapp=prometheus,release=<helm release name> -n <namespace> --replicas=<original value>
-
在 Toolbox pod 中,运行:
sudo gitlab-rake gitlab:check SANITIZE=true
-
-
检查数据库值是否可以解密,特别是如果
/etc/gitlab/gitlab-secrets.json
已恢复,或者如果不同的服务器是恢复的目标:在 Toolbox pod 中,运行:
sudo gitlab-rake gitlab:doctor:secrets
-
为了增加保证,可以对上传的文件执行完整性检查:
由于这些命令可能需要很长时间,因为它们遍历所有行,请在极狐GitLab Rails 节点上而不是 Toolbox pod 中运行以下命令:
sudo gitlab-rake gitlab:artifacts:check sudo gitlab-rake gitlab:lfs:check sudo gitlab-rake gitlab:uploads:check
如果发现缺失或损坏的文件,并不总是意味着备份和恢复过程失败。例如,文件可能在源极狐GitLab 实例上丢失或损坏。可能需要交叉引用先前的备份。如果您正在将极狐GitLab 迁移到新环境,可以在源极狐GitLab 实例上运行相同的检查,以确定完整性检查结果是预先存在的还是与备份和恢复过程相关。
::EndTabs
恢复应该完成。