2. GitLab备份机制总览

GitLab 的备份能力并不是简单地把 /var/opt/gitlab 目录打包,而是由 gitlab-backup(旧版本中为 gitlab-rake gitlab:backup:create)这一内置命令驱动的一套“分组件导出 + 归档”机制。理解它的工作原理,是后续做恢复、迁移和灾难恢复设计的基础。本节围绕四个问题展开:命令怎么跑、备份了哪些东西、备份文件长什么样、文件最终落在哪里以及由哪些配置项控制。

一、命令入口与工作原理

在 Omnibus 安装方式下,备份命令通常以如下形式执行:

# 创建备份(默认备份编号为时间戳)
sudo gitlab-backup create

# 指定备份编号,便于识别
sudo gitlab-backup create BACKUP=20240615_prod

# 跳过某些组件(例如跳过仓库,仅备份数据库)
sudo gitlab-backup create SKIP=repositories,uploads

这条命令实际是一个封装脚本,它按顺序调用 GitLab 各组件自带的备份工具,把不同数据分别导出成独立文件,最后统一打包成一个 tar 归档。其核心流程可以概括为:

  1. 读取配置:从 /etc/gitlab/gitlab.rb 中读取 gitlab_rails['backup_path']、backup_keep_time 等参数,确定输出目录与保留策略。
  2. 锁定与准备:对部分组件做短暂协调,避免备份过程中数据被写入导致不一致。
  3. 分组件导出:依次导出 PostgreSQL 数据库、Git 仓库、上传附件、CI 构建产物、容器镜像仓库、LFS 对象等。
  4. 生成元数据:写入 backup_information.yml,记录 GitLab 版本、备份时间、组件清单等。
  5. 打包归档:将上述所有内容合并为一个 .tar 文件,并按需压缩。

需要特别注意的是,备份命令本身不备份配置文件。像 /etc/gitlab/gitlab.rb、/etc/gitlab/gitlab-secrets.json 这类关键文件必须单独保存,否则恢复时即使数据完整,也可能因为密钥不匹配而无法解密数据库中的敏感字段。

gitlab-backup create 工作原理与备份范围 gitlab-backup create 读取 gitlab.rb 配置 分组件导出 PostgreSQL 数据库 db/database.sql.gz Git 仓库 repositories/ 上传附件 uploads/ CI 构建产物 builds/ artifacts/ 容器镜像仓库 registry/ LFS 对象 lfs/ 元数据 backup_information.yml 版本 / 时间 / 组件清单 tar 归档文件 时间戳_gitlab_backup.tar db/ repositories/ uploads/ builds/ registry/ backup_information.yml (可选压缩 .tar.gz) 默认存储路径 /var/opt/gitlab/backups/ 由 backup_path 配置项控制 关键配置项(/etc/gitlab/gitlab.rb) gitlab_rails['backup_path'] = "/var/opt/gitlab/backups" gitlab_rails['backup_keep_time'] = 604800 # 保留 7 天(秒) ⚠ 备份命令不包含配置文件,必须单独保存: /etc/gitlab/gitlab.rb  /etc/gitlab/gitlab-secrets.json  (否则恢复时密钥不匹配,敏感数据无法解密)

二、备份范围:哪些数据被包含

默认情况下,gitlab-backup create 会备份以下核心数据:

  • PostgreSQL 数据库:包含用户、项目、Issue、Merge Request、权限、CI 流水线记录等几乎所有结构化数据,导出为 db/database.sql.gz。
  • Git 仓库:所有项目的裸仓库数据,位于 repositories/ 目录下,按项目命名空间组织。
  • 上传附件:Issue 附件、头像、评论中的图片等,位于 uploads/。
  • CI 构建产物与日志:builds/ 与 artifacts/ 目录,包含 Job 日志和产物文件。
  • 容器镜像仓库:如果启用了 GitLab Container Registry,会包含 registry/ 目录。
  • LFS 对象:Git Large File Storage 的大文件对象,位于 lfs/。

可以通过 SKIP 参数跳过某些组件,例如只备份数据库和仓库:

sudo gitlab-backup create SKIP=builds,artifacts,registry,lfs

反过来,如果某些数据量极大且可以重建(如 CI 产物),跳过它们能显著缩短备份时间并减小归档体积。但要注意:跳过组件后,恢复时这些数据将缺失,需要评估业务影响。

三、备份文件结构

生成的归档文件命名格式为 <时间戳>_gitlab_backup.tar,例如 1718438400_2024_06_15_14.0.0_gitlab_backup.tar。解包后可以看到清晰的目录结构:

20240615_prod_gitlab_backup.tar
├── backup_information.yml      # 元数据:版本、时间、组件清单
├── db/
│   └── database.sql.gz         # PostgreSQL 逻辑导出
├── repositories/               # Git 裸仓库
│   └── @hashed/...
├── uploads/                    # 上传附件
├── builds/                     # CI 构建目录
├── artifacts/                  # CI 产物
├── registry/                   # 容器镜像仓库
└── lfs/                        # LFS 对象

backup_information.yml 是恢复时的关键依据,它记录了备份时的 GitLab 版本、备份时间戳、以及本次备份包含的组件列表。恢复命令会读取该文件来判断如何还原各组件。

四、存储路径与配置项

备份文件默认写入 /var/opt/gitlab/backups/。这个路径由 /etc/gitlab/gitlab.rb 中的 gitlab_rails['backup_path'] 控制。生产环境中通常建议将其指向独立的大容量磁盘或网络存储,避免与 GitLab 数据盘争抢空间:

gitlab_rails['backup_path'] = "/data/gitlab-backups"
gitlab_rails['backup_keep_time'] = 604800   # 单位秒,此处为 7 天

修改配置后需要执行 sudo gitlab-ctl reconfigure 使其生效。backup_keep_time 控制自动清理策略:超过该时长的备份文件会在下次执行备份时被删除。若设为 0,则表示不自动清理,需要自行管理磁盘空间。

实践建议:备份目录应设置合理的权限(通常为 git 用户可读写),并确保磁盘剩余空间至少为预估备份体积的 1.5 倍。对于大型实例,建议将备份路径挂载到独立卷,并配合监控告警,防止备份因空间不足而静默失败。
常见误区:很多管理员认为“有备份文件就万事大吉”,却忽略了 /etc/gitlab/gitlab-secrets.json 的单独保存。该文件包含数据库加密密钥、CI 变量密钥等,一旦丢失,恢复后的实例将无法解密原有敏感数据,导致 CI 变量、Runner 令牌等全部失效。请务必将配置文件与备份归档分开存放,并纳入同一恢复演练流程。

总结来说,gitlab-backup create 是一条“分组件导出、统一归档”的命令,它覆盖数据库、仓库、附件、CI 产物、镜像仓库和 LFS 等核心数据,输出为带时间戳的 tar 文件,默认存放在 /var/opt/gitlab/backups/,并由 backup_path 与 backup_keep_time 两个配置项控制位置与保留周期。掌握这些机制,才能在后续的恢复与灾难恢复设计中做出正确决策。