GitLab 的备份与恢复
文档用途
介绍如何备份与恢复 GitLab, 以及如何将备份流程周期型自动执行.
参考官方文档 Back up and restore GitLab - GitLab Docs.
备份
备份数据
# 进入 gitlab 容器实例的交互式命令行
docker exec -it gitlab bash
# 最简单的备份命令
gitlab-backup create
# 备份时忽略一些类型的数据
gitlab-backup create SKIP=builds,artifactsINFO
备份过程中, 在备份 repositories 的阶段, 可能会看到很多警告, 但可以无视.
GitLab 为每个工程都自动提供了 wiki.git 和 design.git 这两个伴生的 git 工程,
但如果没有在某些工程中使用 wiki 和 design 功能, 在备份的时候会找不到相关文件,
然后就发出警告, 说 xxx.wiki.git 和 xxx.design.git 的备份被跳过了.
备份文件位置 /var/opt/gitlab/backups (容器内的路径).
备份成功后, 可以在最后一行看到 Backup task is done.

备份配置文件
前面只备份了数据, 但配置文件并没有包括在内, 需要单独备份.
使用以下命令, 备份整个 /etc/gitlab 文件夹.
备份文件的位置是: /etc/gitlab/config_backup
gitlab-ctl backup-etc自动删除
在 /etc/gitlab/gitlab.rb 中可以配置备份数据的寿命.
每当新创建一个备份时, 就会自动删除那些已经超过所设定的寿命的备份.
## The duration in seconds to keep backups.
## 604800 is meant to be 30 days.
gitlab_rails['backup_keep_time'] = 2592000建议使用 Docker 的环境变量 来设置, 不要直接修改 gitlab.rb.
自动备份
我们需要使用 cron 来周期性地执行备份命令 (参考 通过 cron 管理定时任务).
然而 gitlab/gitlab-ee 镜像中并未包含 cron, 但可以使用功能类似的 go-crond.
不论是 cron 还是 go-crond, 其配置文件语法都是一样的, 例如:
# 每月 1 日和 16 日的凌晨 3 点自动开始备份 gitlab 数据
0 3 1,16 * * root gitlab-backup create CRON=1 SKIP=builds,artifacts
# 每月 1 日和 16 日的凌晨 2 点自动开始备份 gitlab 配置文件
0 2 1,16 * * root backup-etc --delete-old-backups我们可以在配置文件工程根目录创建 backup-cron 文件, 写入上述内容.
然后在 compose.yaml 中通过 volumes 字段将 backup-cron 文件映射到容器内的:
/etc/cron.d/backup-cron
并使用名为 GITLAB_POST_RECONFIGURE_SCRIPT 的环境变量,
其所代表的脚本将会在 GitLab 启动后自动执行, 参考 StackOverflow 的问答.
services:
gitlab:
image: gitlab/gitlab-ee:latest
volumes:
# Cron file used to backup gitlab periodically
- ./backup-cron:/etc/cron.d/backup-cron:ro
environment:
# The script in GITLAB_POST_RECONFIGURE_SCRIPT
# is automatically executed on startup
GITLAB_POST_RECONFIGURE_SCRIPT: |
go-crond "/etc/cron.d/backup-cron" & # [!code hl]对象存储 OSS
备份文件需要存储在云端, 例如 AWS S3 - Glacier Deep Archive 每月 $0.99 / TB.
为了避免 OSS Bucket 中的备份文件数量过多, 我们可以设置文件的生命周期.

上传 1 天后, 转换为 Glacier Deep Archive 存储类型. 180 天后, 从 Bucket 中移除.

自动上传
如果能在备份完成后自动上 OSS 就更好了.
GitLab 提供了这个功能, 在 /etc/gitlab/gitlab.rb 中可以做相关配置.
建议把这些配置写在 compose.yaml 的环境变量 GITLAB_OMNIBUS_CONFIG 下.
## Consider using multipart uploads when file size reaches 100MB.
## Enter a number in bytes.
gitlab_rails['backup_multipart_chunk_size'] = 104857600
## Skip parts of the backup. Comma separated.
gitlab_rails['env'] = {
# 这里列出的类型, 将不会被备份
'SKIP' => 'builds,artifacts,registry,pages'
}
## 设置 bucket 名称
gitlab_rails['backup_upload_remote_directory'] = 'xxx' # 记得修改
## 设置 bucket 的其他元数据
gitlab_rails['backup_upload_connection'] = {
'provider' => 'AWS',
'region' => 'xxx', # 记得修改
'aws_access_key_id' => 'xxx', # 记得修改
'aws_secret_access_key' => 'xxx' # 记得修改
}如果 gitlab 备份文件所在 OSS bucket 的加密方式选择 AES256,
就需要在 gitlab.rb 中做相应的配置:
gitlab_rails['backup_upload_storage_options'] = {
'server_side_encryption' => 'AES256',
}调用以下命令, 测试是否能够成功上传备份:
docker exec -it gitlab bash
gitlab-backup create
恢复
准备工作
安装好 相同版本 的 GitLab 并确保处于运行状态.
# 通过以下命令查看 gitlab 版本
cat /opt/gitlab/embedded/service/gitlab-rails/VERSION将备份文件 (压缩包) 放在 /var/opt/gitlab/backups/ 文件夹内,
并确保该文件夹中只有这一个文件, 然后关闭两个可能会访问数据库的进程:
docker exec -it gitlab bash
gitlab-ctl stop puma
gitlab-ctl stop sidekiq恢复数据
执行以下命令开始恢复:
注意 BACKUP= 后面的字符串省略了备份文件名称的后面一部分.1645345876_2022_02_20_14.6.1-ee_gitlab_backup.tar 后面的 _gitlab_backup.tar 被省略了
gitlab-backup restore BACKUP=1645345876_2022_02_20_14.6.1-ee恢复过程中会有报错, 但是可以忽略 postgresql 相关报错.
恢复配置
先将原本的的 gitlab.rb 和 gitlab-secrets.json 这两个配置文件改个名.
cd /etc/gitlab/
mv gitlab.rb gitlab.rb.old
mv gitlab-secrets.json gitlab-secrets.json.old然后将之前备份好的两个配置文件放入 /etc/gitlab/ 文件夹内.
输入命令, 使得新的配置文件生效:\
gitlab-ctl reconfigure
gitlab-ctl restart最后检验是否成功恢复:
gitlab-rake gitlab:check SANITIZE=true
gitlab-rake gitlab:doctor:secrets