备份极狐GitLab

备份极狐GitLab 的过程取决于许多因素。您对特定部署的使用和配置决定了存在的数据类型、数据位置和数据量。这些因素会影响您对如何执行备份、如何存储备份以及如何恢复备份的选择。

简单的备份过程

作为总体指南,如果您使用的 1k 参考架构数据少于 100 GB,请按照以下步骤操作:

  1. 运行备份命令
  2. 备份对象存储(如果适用)。
  3. 手动备份配置文件

扩展备份

随着极狐GitLab 数据量的增长,备份命令的执行时间会更长。备份选项例如并发备份 Git 仓库增量仓库备份可以减少执行时间。在某些时候,备份命令本身就不切实际。例如,可能需要 24 小时或更长时间。

在某些情况下,可能需要更改架构以允许扩展备份。如果您使用的是极狐GitLab 参考架构,请参阅备份和恢复大型参考架构

有关详细信息,请参阅替代备份策略

哪些数据需要备份?

PostgreSQL 数据库

在最简单的情况下,极狐GitLab 在 PostgreSQL 服务器中拥有一个 PostgreSQL 数据库,这台 PostgreSQL 服务器和其他极狐GitLab 服务都在同一台虚拟机上。但根据配置,极狐GitLab 可能会在多个 PostgreSQL 服务器中使用多个 PostgreSQL 数据库。

一般来说,此数据是 Web 界面中大多数用户生成的内容(例如议题和合并请求内容、评论、权限和凭据)的单一事实来源。

PostgreSQL 还保存一些缓存数据,例如 HTML 渲染的 Markdown,以及默认情况下的合并请求差异。 但是,合并请求差异也可以配置为卸载到文件系统或对象存储,请参阅 Blob

Gitaly Cluster 的 Praefect 服务使用 PostgreSQL 数据库作为单一事实来源来管理其 Gitaly 节点。

一个常见的 PostgreSQL 实用程序 pg_dump会生成一个可用于恢复 PostgreSQL 数据库的备份文件。备份命令在底层使用此实用程序。

不幸的是,数据库越大,pg_dump 执行所需的时间就越长。根据您的情况,持续时间有时会变得不切实际(例如几天)。如果您的数据库超过 100 GB,pg_dump 以及扩展的备份命令可能无法使用。有关详细信息,请参阅替代备份策略

Git 仓库

极狐GitLab 实例可以有一个或多个仓库分片。每个分片都是一个 Gitaly 实例或 Gitaly 集群,负责允许对本地存储的 Git 仓库进行访问和操作。Gitaly 可以在机器上运行:

  • 使用单个磁盘。
  • 将多个磁盘挂载为单个挂载点(如 RAID 阵列)。
  • 使用 LVM。

每个项目最多可以有 3 个不同的仓库:

  • 项目仓库:存储源代码。
  • Wiki 仓库:存储 Wiki 内容。
  • 设计仓库,索引设计产物进行索引(资产实际上位于 LFS 中)。

它们都位于同一个分片中,并共享相同的基本名称,并带有 -wiki-design 后缀,用于 Wiki 和设计仓库案例。

个人和项目代码片段以及群组 Wiki 内容存储在 Git 仓库中。

使用池仓库在实时极狐GitLab 站点中对项目派生进行去重。

备份命令为每个仓库生成一个 Git 包并将它们全部打包。这会将池仓库数据复制到每个派生中。在我们的测试中,100 GB 的 Git 仓库需要 2 个多小时才能备份并上传到 S3。对于大约 400 GB 的 Git 数据,备份命令可能不适用于常规备份。有关详细信息,请参阅替代备份策略

Blob

极狐GitLab 将议题附件或 LFS 对象等 Blob(或文件)存储到以下任一位置:

  • 特定位置的文件系统。
  • 对象存储解决方案。对象存储解决方案可以:
    • 基于云,例如 Amazon S3 和 Google Cloud Storage。
    • 由您托管(例如 MinIO)。
    • 公开对象存储兼容 API 的存储设备。

对象存储

备份命令不会备份未存储在文件系统上的 Blob。如果您使用对象存储,请务必启用对象存储提供者的备份。例如,请参见:

容器镜像库

极狐GitLab 容器镜像库存储可以配置为:

  • 特定位置的文件系统。
  • 对象存储 解决方案。对象存储解决方案可以是:
    • 基于云,例如 Amazon S3 和 Google Cloud Storage。
    • 由您托管(如 MinIO)。
    • 公开对象存储兼容 API 的存储设备。

当容器镜像库数据存储在对象存储上时,备份命令不会对其进行备份。

存储配置文件

caution 极狐GitLab 提供的备份 Rake 任务存储您的配置文件。主要原因是您的数据库包含的项目包括用于双因素身份验证和 CI/CD 安全变量 的加密信息。将加密信息存储在与其密钥相同的位置,从一开始就违背了使用加密的目的。例如,secret 文件包含您的数据库加密密钥。如果丢失,极狐GitLab 应用程序将无法解密数据库中的任何加密值。
caution 升级后私密文件可能会更改。

您应该备份配置目录。您至少必须备份:

::Tabs

:::TabTitle Linux 软件包

  • /etc/gitlab/gitlab-secrets.json
  • /etc/gitlab/gitlab.rb

有关更多信息,请参见备份和恢复 Linux 软件包(Omnibus)配置

:::TabTitle 自编译

  • /home/git/gitlab/config/secrets.yml
  • /home/git/gitlab/config/gitlab.yml

:::TabTitle Docker

  • 备份存储备份文件的卷。如果您按照文档创建极狐GitLab 容器,其应该在 /srv/gitlab/config 目录中。

:::TabTitle 极狐GitLab Helm chart

::EndTabs

您可能还需要备份任何 TLS 密钥和证书(/etc/gitlab/ssl/etc/gitlab/trusted-certs),以及您的 SSH 主机密钥以避免在必须执行完整机器恢复时出现中间人攻击警告。

万一 secret 文件丢失,请参阅故障排除部分

其他数据

极狐GitLab 使用 Redis 作为缓存存储并为我们的后台作业系统 Sidekiq 保存持久数据。提供的备份命令备份 Redis 数据。这意味着为了使用备份命令进行一致的备份,必须没有挂起或正在运行的后台作业。可以手动备份 Redis

Elasticsearch 是用于高级搜索的可选数据库。它可以改善源代码级别以及用户在议题、合并请求和讨论中生成的内容中的搜索。备份命令备份 Elasticsearch 数据。恢复后可以从 PostgreSQL 数据重新生成 Elasticsearch 数据。可以手动备份 Elasticsearch

命令行界面

极狐GitLab 提供了一个命令行界面来备份您的整个实例,包括:

  • 数据库
  • 附件
  • Git 仓库数据
  • CI/CD 作业输出日志
  • CI/CD 作业产物
  • LFS 对象
  • Terraform 状态(引入于 14.7 版本)
  • 容器镜像库镜像
  • 极狐GitLab Pages 内容
  • 软件包(引入于 14.7 版本)
  • 代码片段
  • 群组 Wiki
  • 项目级安全文件(引入于 16.1 版本)
  • 外部的合并请求差异(引入于 17.1 版本)

备份不包括:

caution 极狐GitLab 不备份任何配置文件(/etc/gitlab)、TLS 密钥和证书或系统文件。强烈建议您阅读存储配置文件

要求

为了能够进行备份和恢复,请确保您的系统上安装了 Rsync。如果您安装了极狐GitLab:

  • 使用 Linux 软件包,已安装 Rsync。
  • 使用自编译,检查是否安装了 rsync。如果未安装 Rsync,请安装。例如:

    # Debian/Ubuntu
    sudo apt-get install rsync
    
    # RHEL/CentOS
    sudo yum install rsync
    

备份命令

caution 备份命令不备份对象存储中的项目。
caution 当您的安装使用 PgBouncer 时,出于性能原因或与 Patroni 集群一起使用时,备份命令需要附加参数
caution 在 15.5.0 版本之前,备份命令不验证是否有其他备份正在运行。我们强烈建议您在完成所有备份后再开始新的备份。
note 您只能将备份恢复到与创建备份的极狐GitLab 完全相同的版本和类型

::Tabs

:::TabTitle Linux 软件包(Omnibus)

sudo gitlab-backup create

:::TabTitle Helm chart(Kubernetes)

使用 kubectl 运行备份任务以在极狐GitLab toolbox pod 上运行 backup-utility 脚本。有关更多信息,请参阅 Chart 备份文档

:::TabTitle Docker

从主机运行备份。

  • 13.10 及更高版本:
docker exec -t <container name> gitlab-backup create

:::TabTitle 自编译

sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production

::EndTabs

如果您的极狐GitLab 部署有多个节点,您需要选择一个节点来运行备份命令。您必须确保指定节点:

  • 是持久的,并且不受弹性伸缩的影响。
  • 已安装极狐GitLab Rails 应用程序。如果 Puma 或 Sidekiq 正在运行,则 Rails 已安装。
  • 有足够的存储空间和内存来生成备份文件。

输出示例:

Dumping database tables:
- Dumping table events... [DONE]
- Dumping table issues... [DONE]
- Dumping table keys... [DONE]
- Dumping table merge_requests... [DONE]
- Dumping table milestones... [DONE]
- Dumping table namespaces... [DONE]
- Dumping table notes... [DONE]
- Dumping table projects... [DONE]
- Dumping table protected_branches... [DONE]
- Dumping table schema_migrations... [DONE]
- Dumping table services... [DONE]
- Dumping table snippets... [DONE]
- Dumping table taggings... [DONE]
- Dumping table tags... [DONE]
- Dumping table users... [DONE]
- Dumping table users_projects... [DONE]
- Dumping table web_hooks... [DONE]
- Dumping table wikis... [DONE]
Dumping repositories:
- Dumping repository abcd... [DONE]
Creating backup archive: $TIMESTAMP_gitlab_backup.tar [DONE]
Deleting tmp directories...[DONE]
Deleting old backups... [SKIPPING]

关于备份进程的更多详情,可以查看备份归档进程

备份选项

极狐GitLab 提供的用于备份实例的命令行工具可以接受更多选项。

备份策略选项

默认备份策略本质上是使用 Linux 命令 targzip 将数据从相应的数据位置流式传输到备份。在大多数情况下没有问题,但当数据快速变化时可能会导致问题。

tar 读取数据时数据发生更改,可能会出现 file changed as we read it 错误,并导致备份过程失败。在这种情况下,您可以使用称为 copy 的备份策略。该策略在调用 targzip 之前将数据文件复制到临时位置,从而避免了错误。

副作用是备份过程会额外占用 1X 的磁盘空间。该过程会尽力清理每个阶段的临时文件,因此问题不会变得复杂,但对于大型安装来说,这可能是一个相当大的变化。

要使用 copy 策略而不是默认的流策略,请在 Rake 任务命令中指定 STRATEGY=copy。例如:

sudo gitlab-backup create STRATEGY=copy

备份文件名称

caution 如果您使用自定义备份文件名,则无法限制备份的生命周期

默认情况下,备份文件是根据前面的备份时间戳部分中的规范创建的。但是,您可以通过设置 BACKUP 环境变量来覆盖文件名的 [TIMESTAMP]。例如:

sudo gitlab-backup create BACKUP=dump

生成的文件名为 dump_gitlab_backup.tar。这对于使用 rsync 和增量备份的系统非常有用,并且可以显著提高传输速度。

备份压缩

默认情况下,在备份以下内容期间应用 Gzip 快速压缩:

默认命令是 gzip -c -1。您可以使用 COMPRESS_CMD 覆盖此命令。

注意事项:

  • 压缩命令在流水线中使用,因此您的自定义命令必须输出到 stdout。
  • 如果您指定的命令未与极狐GitLab 一起打包,则您必须自行安装。
  • 结果文件名仍将以 .gz 结尾。
  • 恢复期间使用的默认解压缩命令是 gzip -cd。因此,如果您覆盖压缩命令以使用无法通过 gzip -cd 解压缩的格式,则必须在恢复期间覆盖解压缩命令。
  • 不要在备份命令后面放环境变量。比如,gitlab-backup create COMPRESS_CMD="pigz -c --best" 就无法如期工作。

默认压缩:最快方法的 Gzip

gitlab-backup create

最慢方法的 Gzip

gitlab-backup create COMPRESS_CMD="gzip -c --best"

如果使用 gzip 进行备份,那么恢复不需要任何选项:

gitlab-backup restore

无压缩

如果您的备份目标具有内置自动压缩功能,那么您可能希望跳过压缩。

tee 命令将 stdin 传输到 stdout

gitlab-backup create COMPRESS_CMD=tee

恢复时:

gitlab-backup restore DECOMPRESS_CMD=tee
pigz 并行压缩
caution 尽管我们支持使用 COMPRESS_CMDDECOMPRESS_CMD 来覆盖默认的 Gzip 压缩库,但是我们仅在常规情况下使用默认选项测试了默认的 Gzip 库。您负责测试并验证备份的可行性。我们强烈建议将此作为通用备份的最佳实践,而不管您是否在覆盖压缩命令。如果您在使用其他压缩库时遇到了问题,您应该撤回至默认压缩。对于极狐GitLab 来讲,对其他压缩仓库进行故障排查和错误修复是优先级较低的事情。
note pigz 没有包含在极狐GitLab Linux 软件包中。您必须自行安装。

pigz 并用 4 个进程进行压缩的示例如下:

COMPRESS_CMD="pigz --compress --stdout --fast --processes=4" sudo gitlab-backup create

因为 pigz 会压缩成 gzip 格式,所以不要求使用 pigz 来解压缩那些使用 pigz 压缩的备份。不过,与 gzip 相比,它在性能上仍有优势。以下是一个使用 pigz 解压缩备份文件的示例。

DECOMPRESS_CMD="pigz --decompress --stdout" sudo gitlab-backup restore
使用 zstd 并行压缩
caution 尽管我们支持使用 COMPRESS_CMDDECOMPRESS_CMD 来覆盖默认的 Gzip 压缩库,但是我们仅在常规情况下使用默认选项测试了默认的 Gzip 库。您负责测试并验证备份的可行性。我们强烈建议将此作为通用备份的最佳实践,而不管您是否在覆盖压缩命令。如果您在使用其他压缩库时遇到了问题,您应该撤回至默认压缩。对于极狐GitLab 来讲,对其他压缩仓库进行故障排查和错误修复是优先级较低的事情。
note zstd 没有包含在极狐GitLab Linux 软件包中。您必须自行安装。

zstd 并用 4 个线程进行压缩的示例如下:

COMPRESS_CMD="zstd --compress --stdout --fast --threads=4" sudo gitlab-backup create

使用 zstd 解压缩备份文件的示例如下:

DECOMPRESS_CMD="zstd --decompress --stdout" sudo gitlab-backup restore

确认可以传输存档

为了确保生成的存档可以通过 rsync 传输,您可以设置 GZIP_RSYNCABLE=yes 选项。这会将 --rsyncable 选项设置为 gzip,该选项仅与设置备份文件名选项结合使用才有用。

不保证 gzip 中的 --rsyncable 选项在所有发行版上都可用。要验证它在您的发行版中是否可用,请运行 gzip --help 或查阅手册。

sudo gitlab-backup create BACKUP=dump GZIP_RSYNCABLE=yes

从备份排除特定目录

取决于您的安装方式,在创建备份时,可以跳过的组建也略有不同。

:Tabs

:::TabTitle Linux package (Omnibus) / Docker / Self-compiled

  • db (数据库)
  • repositories (Git 仓库数据,包括 wiki)
  • uploads (附件)
  • builds (CI 作业输出日志)
  • artifacts (CI 作业产物)
  • pages (Pages 内容)
  • lfs (LFS 对象)
  • terraform_state (Terraform 状态)
  • registry (容器镜像仓库镜像)
  • packages (软件包)
  • ci_secure_files (项目级别的安全文件)
  • external_diffs (外部合并请求差异)

:::TabTitle Helm chart (Kubernetes)

  • db (数据库)
  • repositories (Git 仓库数据,包括 wiki)
  • uploads (附件)
  • artifacts (CI 作业产物和输出日志)
  • pages (Pages 内容)
  • lfs (LFS 对象)
  • terraform_state (Terraform 状态)
  • registry (容器镜像仓库镜像)
  • packages (软件包仓库)
  • ci_secure_files 项目级别的安全文件)
  • external_diffs (外部合并请求差异)

::EndTabs

::Tabs

:::TabTitle Linux package (Omnibus)

sudo gitlab-backup create SKIP=db,uploads

:::TabTitle Helm chart (Kubernetes)

See Skipping components in charts backup documentation.

:::TabTitle Self-compiled

sudo -u git -H bundle exec rake gitlab:backup:create SKIP=db,uploads RAILS_ENV=production

::EndTabs

SKIP= 也用于:

跳过 tar 创建

note 使用对象存储进行备份时,无法跳过 tar 创建。

创建备份的最后一部分是生成包含所有部分的 .tar 文件。在某些情况下,创建 .tar 文件可能会浪费精力,甚至有害,因此您可以通过将 tar 添加到 SKIP 环境变量来跳过此步骤。用例示例:

  • 当其他备份软件拾取备份时。
  • 通过避免每次都提取备份来加速增量备份。(在这种情况下,不能指定 PREVIOUS_BACKUPBACKUP,否则提取指定的备份,但最终不会生成 .tar 文件。)

tar 添加到 SKIP 变量会将目录中包含备份的文件和目录用于中间文件。创建新备份时,这些文件将被覆盖,因此您应该将其复制到其他位置,因为您在系统上只能有一个备份。

::Tabs

:::TabTitle Linux 软件包(Omnibus)

sudo gitlab-backup create SKIP=tar

:::TabTitle 自编译

sudo -u git -H bundle exec rake gitlab:backup:create SKIP=tar RAILS_ENV=production

::EndTabs

创建服务器端的仓库备份

  • gitlab-backup 中引入于极狐GitLab 16.3。
  • 恢复指定备份而不是最新备份时,在 gitlab-backup 中对于服务器端的支持引入于极狐GitLab 16.6。
  • 创建增量备份时,中对于服务器端的支持引入于极狐GitLab 16.6。
  • backup-utility 中对于服务器端的支持引入于极狐GitLab 17.0。

与其在备份归档中恢复大型项目备份,对于仓库备份,可以进行相应配置,让托管每个仓库的 Gitaly 节点负责创建备份,并将其传输到对象存储中。这有助于减少创建和恢复备份所需的网络资源。

  1. 在 Gitaly 中配置服务器端备份目标
  2. 使用仓库服务器端选项创建备份。请参阅以下示例。

::Tabs

:::TabTitle Linux 软件包(Omnibus)

sudo gitlab-backup create REPOSITORIES_SERVER_SIDE=true

:::TabTitle 自编译

sudo -u git -H bundle exec rake gitlab:backup:create REPOSITORIES_SERVER_SIDE=true

:::TabTitle Helm chart (Kubernetes)

kubectl exec <Toolbox pod name> -it -- backup-utility --repositories-server-side

当您在使用基于定时的备份时,请添加 --repositories-server-side 参数。

::EndTabs

并发备份 Git 仓库

  • 引入于极狐GitLab 13.3。
  • 并发恢复引入于极狐GitLab 14.3。

使用多个仓库存储时,可以同时备份或恢复仓库以帮助充分利用 CPU 时间。以下变量可用于修改 Rake 任务的默认行为:

  • GITLAB_BACKUP_MAX_CONCURRENCY:同时备份的最大项目数。默认为逻辑 CPU 的数量。
  • GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY:每个存储上同时备份的最大项目数。允许仓库备份分布在存储中。默认为 2

例如,有 4 个仓库存储:

::Tabs

:::TabTitle Linux 软件包(Omnibus)

sudo gitlab-backup create GITLAB_BACKUP_MAX_CONCURRENCY=4 GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY=1

:::TabTitle 自编译

sudo -u git -H bundle exec rake gitlab:backup:create GITLAB_BACKUP_MAX_CONCURRENCY=4 GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY=1

::EndTabs

增量仓库备份

  • PREVIOUS_BACKUP 选项引入于极狐GitLab 15.0。
  • 创建增量备份的服务器端的支持引入于极狐GitLab 16.6。
在私有化部署的极狐GitLab 上,默认情况下此功能可用。要隐藏该功能,管理员可以隐藏名为 incremental_repository_backup功能标志。 在 JihuLab.com,此功能不可用。
note 只有仓库支持增量备份。因此,如果您使用 INCREMENTAL=yes,该任务将创建一个独立的备份 tar 存档。这是因为除仓库之外的所有子任务仍在创建完整备份(覆盖现有完整备份)。

增量仓库备份可能比完整仓库备份更快,因为它们仅将自上次备份以来的更改打包到每个仓库的备份包中。增量备份存档不相互链接:每个存档都是实例的独立备份。必须有现有备份才能从中创建增量备份。

使用 PREVIOUS_BACKUP=<backup-id> 选项来选择要使用的备份。默认情况下,按照备份 ID 部分中的说明创建备份文件。您可以通过设置 BACKUP 环境变量来覆盖备份文件中的 <backup-id> 部分。

要创建增量备份,请运行:

  • 在 15.0 及更高版本中:
sudo gitlab-backup create INCREMENTAL=yes PREVIOUS_BACKUP=<backup-id>

要从 tarred 备份创建 untarred 增量备份,请使用 SKIP=tar

sudo gitlab-backup create INCREMENTAL=yes SKIP=tar

备份特定仓库存储

  • 引入于极狐GitLab 15.0。

当使用多个仓库存储时,可以使用 REPOSITORIES_STORAGES 选项单独备份特定仓库存储中的仓库。该选项接受以逗号分隔的存储名称列表。

示例:

::Tabs

:::TabTitle Linux 软件包(Omnibus)

sudo gitlab-backup create REPOSITORIES_STORAGES=storage1,storage2

:::TabTitle 自编译

sudo -u git -H bundle exec rake gitlab:backup:create REPOSITORIES_STORAGES=storage1,storage2

::EndTabs

备份特定仓库

  • 引入于极狐GitLab 15.1。
  • 跳过指定仓库引入于极狐GitLab 16.1。

您可以使用 REPOSITORIES_PATHS 选项备份特定仓库。同样,您可以使用 SKIP_REPOSITORIES_PATHS 来跳过某些仓库。这两个选项都接受以逗号分隔的项目或群组路径列表。如果指定群组路径,则包含或跳过该群组和子组中所有项目中的所有仓库,具体取决于您使用的选项。

例如,要备份 A 组 (group-a) 中所有项目的所有仓库,请备份 B 组项目 C 的仓库 (group-b/project- c),并跳过 A 组 中的 项目 D (group-a/project-d):

::Tabs

:::TabTitle Linux 软件包(Omnibus)

  sudo gitlab-backup create REPOSITORIES_PATHS=group-a,group-b/project-c SKIP_REPOSITORIES_PATHS=group-a/project-d

:::TabTitle 自编译

  sudo -u git -H bundle exec rake gitlab:backup:create REPOSITORIES_PATHS=group-a,group-b/project-c SKIP_REPOSITORIES_PATHS=group-a/project-d

::EndTabs

将备份上传到远端(云)存储

note 使用对象存储进行备份时,无法跳过 tar 创建

您可以让备份脚本上传(使用 Fog 库)它创建的 .tar 文件。在以下示例中,我们使用 Amazon S3 进行存储,但 Fog 还允许您使用其他存储提供者。 极狐GitLab 还为 AWS、Google 和阿里云导入云驱动程序。本地驱动程序也可用

阅读有关在极狐GitLab 中使用对象存储的更多信息

使用 Amazon S3

对于 Linux 软件包(Omnibus):

  1. 将以下内容添加到 /etc/gitlab/gitlab.rb

    gitlab_rails['backup_upload_connection'] = {
      'provider' => 'AWS',
      'region' => 'eu-west-1',
      'aws_access_key_id' => 'AKIAKIAKI',
      'aws_secret_access_key' => 'secret123'
      # If using an IAM Profile, don't configure aws_access_key_id & aws_secret_access_key
      # 'use_iam_profile' => true
    }
    gitlab_rails['backup_upload_remote_directory'] = 'my.s3.bucket'
    # Consider using multipart uploads when file size reaches 100MB. Enter a number in bytes.
    # gitlab_rails['backup_multipart_chunk_size'] = 104857600
    
  2. 重新配置极狐GitLab 以使更改生效。

S3 加密存储桶

AWS 支持这些服务器端加密模式

  • Amazon S3-Managed 密钥 (SSE-S3)
  • 存储在 AWS Key Management Service (SSE-KMS) 中的客户主密钥 (CMK)
  • 客户提供的密钥 (SSE-C)

使用您选择的极狐GitLab 模式。每种模式都有类似但略有不同的配置方法。

SSE-S3

要启用 SSE-S3,请在备份存储选项中将 server_side_encryption 字段设置为 AES256。例如,在 Linux 软件包(Omnibus)中:

gitlab_rails['backup_upload_storage_options'] = {
  'server_side_encryption' => 'AES256'
}
SSE-KMS

要启用 SSE-KMS,您需要 arn:aws:kms:region:acct-id:key/key-id 格式的通过其 Amazon 资源名称 (ARN) 的 KMS 密钥。 在 backup_upload_storage_options 配置设置下,将:

  • server_side_encryption 设置为 aws:kms
  • server_side_encryption_kms_key_id 设置为密钥的 ARN。

例如,在 Linux 软件包中(Omnibus):

gitlab_rails['backup_upload_storage_options'] = {
  'server_side_encryption' => 'aws:kms',
  'server_side_encryption_kms_key_id' => 'arn:aws:<YOUR KMS KEY ID>:'
}
SSE-C

SSE-C 要求您设置以下加密选项:

  • backup_encryption:AES256
  • backup_encryption_key:未编码的 32 字节(256 位)密钥。如果不是 32 字节,则上传失败

例如,在 Linux 软件包中(Omnibus):

gitlab_rails['backup_encryption'] = 'AES256'
gitlab_rails['backup_encryption_key'] = '<YOUR 32-BYTE KEY HERE>'

如果密钥包含二进制字符且无法以 UTF-8 编码,请使用 GITLAB_BACKUP_ENCRYPTION_KEY 环境变量指定密钥。 例如:

gitlab_rails['env'] = { 'GITLAB_BACKUP_ENCRYPTION_KEY' => "\xDE\xAD\xBE\xEF" * 8 }
Digital Ocean Spaces

此示例可用于 Amsterdam (AMS3) 中的存储桶:

  1. 将以下内容添加到 /etc/gitlab/gitlab.rb

    gitlab_rails['backup_upload_connection'] = {
      'provider' => 'AWS',
      'region' => 'ams3',
      'aws_access_key_id' => 'AKIAKIAKI',
      'aws_secret_access_key' => 'secret123',
      'endpoint'              => 'https://ams3.digitaloceanspaces.com'
    }
    gitlab_rails['backup_upload_remote_directory'] = 'my.s3.bucket'
    
  2. 重新配置极狐GitLab 以使更改生效。

如果您在使用 Digital Ocean Spaces 时看到 400 Bad Request 错误消息,原因可能是使用了备份加密。由于 Digital Ocean Spaces 不支持加密,因此请移除或评价包含 gitlab_rails['backup_encryption'] 的行。

其他 S3 提供者

并非所有 S3 提供者都与 Fog 库完全兼容。例如,如果您在尝试上传后看到 411 Length Required 错误消息,您可能需要将 aws_signature_version 值从默认值降级为 2

对于自编译安装:

  1. 编辑 home/git/gitlab/config/gitlab.yml

      backup:
        # snip
        upload:
          # Fog storage connection settings, see https://fog.io/storage/ .
          connection:
            provider: AWS
            region: eu-west-1
            aws_access_key_id: AKIAKIAKI
            aws_secret_access_key: 'secret123'
            # If using an IAM Profile, leave aws_access_key_id & aws_secret_access_key empty
            # ie. aws_access_key_id: ''
            # use_iam_profile: 'true'
          # The remote 'directory' to store your backups. For S3, this would be the bucket name.
          remote_directory: 'my.s3.bucket'
          # Specifies Amazon S3 storage class to use for backups, this is optional
          # storage_class: 'STANDARD'
          #
          # Turns on AWS Server-Side Encryption with Amazon Customer-Provided Encryption Keys for backups, this is optional
          #   'encryption' must be set in order for this to have any effect.
          #   'encryption_key' should be set to the 256-bit encryption key for Amazon S3 to use to encrypt or decrypt.
          #   To avoid storing the key on disk, the key can also be specified via the `GITLAB_BACKUP_ENCRYPTION_KEY`  your data.
          # encryption: 'AES256'
          # encryption_key: '<key>'
          #
          #
          # Turns on AWS Server-Side Encryption with Amazon S3-Managed keys (optional)
          # https://docs.aws.amazon.com/AmazonS3/latest/userguide/serv-side-encryption.html
          # For SSE-S3, set 'server_side_encryption' to 'AES256'.
          # For SS3-KMS, set 'server_side_encryption' to 'aws:kms'. Set
          # 'server_side_encryption_kms_key_id' to the ARN of customer master key.
          # storage_options:
          #   server_side_encryption: 'aws:kms'
          #   server_side_encryption_kms_key_id: 'arn:aws:kms:YOUR-KEY-ID-HERE'
    
  2. 重启极狐GitLab 以使更改生效。

如果您要将备份上传到 S3,您应该创建一个具有受限访问权限的新 IAM 用户。要授予上传用户仅上传备份的访问权限,请创建以下 IAM 配置文件,并将 my.s3.bucket 替换为您的存储桶名称:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1412062044000",
      "Effect": "Allow",
      "Action": [
        "s3:AbortMultipartUpload",
        "s3:GetBucketAcl",
        "s3:GetBucketLocation",
        "s3:GetObject",
        "s3:GetObjectAcl",
        "s3:ListBucketMultipartUploads",
        "s3:PutObject",
        "s3:PutObjectAcl"
      ],
      "Resource": [
        "arn:aws:s3:::my.s3.bucket/*"
      ]
    },
    {
      "Sid": "Stmt1412062097000",
      "Effect": "Allow",
      "Action": [
        "s3:GetBucketLocation",
        "s3:ListAllMyBuckets"
      ],
      "Resource": [
        "*"
      ]
    },
    {
      "Sid": "Stmt1412062128000",
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::my.s3.bucket"
      ]
    }
  ]
}
使用 Google Cloud Storage

要使用 Google Cloud Storage 保存备份,您必须首先从 Google 控制台创建访问密钥:

  1. 进入 Google 存储设置页面
  2. 选择 Interoperability,然后创建访问密钥。
  3. 记下 Access KeySecret 并将其替换为以下配置。
  4. 在存储桶高级设置中,确保选择访问控制选项 Set object-level and bucket-level permissions
  5. 确保您已经创建了存储桶。

对于 Linux 软件包(Omnibus):

  1. 编辑 /etc/gitlab/gitlab.rb

    gitlab_rails['backup_upload_connection'] = {
      'provider' => 'Google',
      'google_storage_access_key_id' => 'Access Key',
      'google_storage_secret_access_key' => 'Secret',
    
      ## If you have CNAME buckets (foo.example.com), you might run into SSL issues
      ## when uploading backups ("hostname foo.example.com.storage.googleapis.com
      ## does not match the server certificate"). In that case, uncomment the following
      ## setting. See: https://github.com/fog/fog/issues/2834
      #'path_style' => true
    }
    gitlab_rails['backup_upload_remote_directory'] = 'my.google.bucket'
    
  2. 重新配置极狐GitLab 以使更改生效。

对于自编译安装:

  1. 编辑 home/git/gitlab/config/gitlab.yml

      backup:
        upload:
          connection:
            provider: 'Google'
            google_storage_access_key_id: 'Access Key'
            google_storage_secret_access_key: 'Secret'
          remote_directory: 'my.google.bucket'
    
  2. 重启极狐GitLab 以使更改生效。

使用 Azure Blob storage

::Tabs

:::TabTitle Linux 软件包(Omnibus)

  1. 编辑 /etc/gitlab/gitlab.rb

    gitlab_rails['backup_upload_connection'] = {
     'provider' => 'AzureRM',
     'azure_storage_account_name' => '<AZURE STORAGE ACCOUNT NAME>',
     'azure_storage_access_key' => '<AZURE STORAGE ACCESS KEY>',
     'azure_storage_domain' => 'blob.core.windows.net', # Optional
    }
    gitlab_rails['backup_upload_remote_directory'] = '<AZURE BLOB CONTAINER>'
    
  2. 重新配置极狐GitLab 以使更改生效。

:::TabTitle 自编译

  1. 编辑 home/git/gitlab/config/gitlab.yml

      backup:
        upload:
          connection:
            provider: 'AzureRM'
            azure_storage_account_name: '<AZURE STORAGE ACCOUNT NAME>'
            azure_storage_access_key: '<AZURE STORAGE ACCESS KEY>'
          remote_directory: '<AZURE BLOB CONTAINER>'
    
  2. 重启极狐GitLab 以使更改生效。

::EndTabs

更多信息请参见 Azure 参数表格

为备份指定自定义目录

此选项仅适用于远程存储。如果要对备份进行分组,可以传递 DIRECTORY 环境变量:

sudo gitlab-backup create DIRECTORY=daily
sudo gitlab-backup create DIRECTORY=weekly

跳过向远端存储上传备份

如果您已将极狐GitLab 配置为向远端存储上传备份,您可以使用 SKIP=remote 选项跳过将备份上传到远端存储。

::Tabs

:::TabTitle Linux 软件包(Omnibus)

sudo gitlab-backup create SKIP=remote

:::TabTitle 自编译

sudo -u git -H bundle exec rake gitlab:backup:create SKIP=remote RAILS_ENV=production

::EndTabs

上传到本地挂载的共享

您可以使用 Fog Local 存储提供者将备份发送到本地挂载的共享(例如,NFSCIFSSMB)。

为此,您必须设置以下配置 key:

  • backup_upload_connection.local_root:备份复制到的挂载目录。
  • backup_upload_remote_directorybackup_upload_connection.local_root 目录的子目录。如果不存在则需要创建。 如果要将 tarball 复制到已安装目录的根目录,请使用 .

挂载时,local_root key 中设置的目录必须由以下任一者拥有:

  • git 用户。因此,使用 git 用户的 uid= 来安装 CIFSSMB
  • 您执行备份任务的用户。对于 Linux 软件包 (Omnibus),这是 git 用户。

由于文件系统性能可能会影响极狐GitLab 的整体性能,我们不建议使用基于云的文件系统进行存储。

避免冲突配置

不要将以下配置 key 设置为同一路径:

  • gitlab_rails['backup_path'](用于自编译安装的 backup.path)。
  • gitlab_rails['backup_upload_connection'].local_rootbackup.upload.connection.local_root 用于自编译安装)。

backup_path 配置 key 设置备份文件的本地位置。upload 配置 key 用于将备份文件上传到单独的服务器,也可能用于存档。

如果这些配置 key 设置为同一位置,则上传功能会失败,因为上传位置已存在备份。此失败会导致上传功能删除备份,因为它假定这是上传尝试失败后剩余的残留文件。

将上传配置到本地挂载的共享

::Tabs

:::TabTitle Linux 软件包(Omnibus)

  1. 编辑 /etc/gitlab/gitlab.rb

    gitlab_rails['backup_upload_connection'] = {
      :provider => 'Local',
      :local_root => '/mnt/backups'
    }
    
    # The directory inside the mounted folder to copy backups to
    # Use '.' to store them in the root directory
    gitlab_rails['backup_upload_remote_directory'] = 'gitlab_backups'
    
  2. 重新配置极狐GitLab 以使更改生效。

:::TabTitle 自编译

  1. 编辑 home/git/gitlab/config/gitlab.yml

    backup:
      upload:
        # Fog storage connection settings, see https://fog.io/storage/ .
        connection:
          provider: Local
          local_root: '/mnt/backups'
        # The directory inside the mounted folder to copy backups to
        # Use '.' to store them in the root directory
        remote_directory: 'gitlab_backups'
    
  2. 重启极狐GitLab 以使更改生效。

::EndTabs

备份存档权限

极狐GitLab 创建的备份存档 (1393513186_2014_02_27_gitlab_backup.tar) 默认拥有所有者/群组 git/git 和 0600 权限。这是为了避免其他系统用户读取极狐GitLab 数据。如果您需要备份存档具有不同的权限,可以使用 archive_permissions 设置。

::Tabs

:::TabTitle Linux 软件包(Omnibus)

  1. 编辑 /etc/gitlab/gitlab.rb

    gitlab_rails['backup_archive_permissions'] = 0644 # Makes the backup archives world-readable
    
  2. 重新配置极狐GitLab 以使更改生效。

:::TabTitle 自编译

  1. 编辑 /home/git/gitlab/config/gitlab.yml

    backup:
      archive_permissions: 0644 # Makes the backup archives world-readable
    
  2. 重启极狐GitLab 以使更改生效。

::EndTabs

配置 cron 进行每日备份

caution 以下 cron 作业不会备份您的极狐GitLab 配置文件SSH 主机密钥

您可以安排一个 cron 作业来备份您的仓库和极狐GitLab 元数据。

::Tabs

:::TabTitle Linux 软件包(Omnibus)

  1. root 用户配置 crontab:

    sudo su -
    crontab -e
    
  2. 添加以下内容,计划每天凌晨 2:00 进行备份:

    0 2 * * * /opt/gitlab/bin/gitlab-backup create CRON=1
    

:::TabTitle 自编译

  1. git 用户编辑 crontab:

    sudo -u git crontab -e
    
  2. 在底部添加以下内容:

    # Create a full backup of the GitLab repositories and SQL database every day at 2am
    0 2 * * * cd /home/git/gitlab && PATH=/usr/local/bin:/usr/bin:/bin bundle exec rake gitlab:backup:create RAILS_ENV=production CRON=1
    

::EndTabs

如果没有任何错误,CRON=1 环境设置会指示备份脚本隐藏所有进度输出。建议这样做以减少 cron spam。 但是,在解决备份故障时,请将 CRON=1 替换为 --trace 以详细记录。

限制本地文件的备份生命周期(修剪旧备份)

caution 如果您使用自定义文件名进行备份,本节中描述的过程将不起作用。

为了防止定期备份占用所有磁盘空间,您可能需要设置备份的有限生命周期。下次运行备份任务时,早于 backup_keep_time 的备份将被删除。

此配置选项仅管理本地文件。极狐GitLab 不会删除存储在第三方对象存储中的旧文件,因为用户可能没有列出和删除文件的权限。建议您为对象存储配置适当的保留策略(例如,AWS S3)。

::Tabs

:::TabTitle Linux 软件包(Omnibus)

  1. 编辑 /etc/gitlab/gitlab.rb

    ## Limit backup lifetime to 7 days - 604800 seconds
    gitlab_rails['backup_keep_time'] = 604800
    
  2. 重新配置极狐GitLab 以使更改生效。

:::TabTitle 自编译

  1. 编辑 /home/git/gitlab/config/gitlab.yml

    backup:
      ## Limit backup lifetime to 7 days - 604800 seconds
      keep_time: 604800
    
  2. 重启极狐GitLab 以使更改生效。

::EndTabs

使用 PgBouncer 备份和恢复安装

不要通过 PgBouncer 连接备份或恢复极狐GitLab。这些任务必须绕过 PgBouncer 并直接连接到 PostgreSQL 主数据库节点,否则会导致极狐GitLab 中断。

当极狐GitLab 备份或恢复任务与 PgBouncer 一起使用时,会显示以下错误消息:

ActiveRecord::StatementInvalid: PG::UndefinedTable

每次运行极狐GitLab 备份时,极狐GitLab 都会开始生成 500 个错误,并且有关丢失表的错误将由 PostgreSQL 记录

ERROR: relation "tablename" does not exist at character 123

发生这种情况是因为该任务使用 pg_dump,它设置一个空搜索路径并在每个 SQL 查询中显式包含架构来解决 CVE-2018-1058

由于连接在事务池模式下与 PgBouncer 重用,因此 PostgreSQL 无法搜索默认的 public 架构。因此,搜索路径的清除会出现表和列丢失。

绕过 PgBouncer

有两种方法绕过 PgBouncer:

  1. 使用环境变量覆盖数据库设置进行备份任务。
  2. 重新配置节点以直接连接到 PostgreSQL 主数据库节点

环境变量覆盖
  • 多个数据库支持引入于极狐GitLab 16.5。

默认情况下,极狐GitLab 使用存储在配置文件(database.yml)中的数据库配置。但是,您可以通过设置前缀为 GITLAB_BACKUP_ 的环境变量来覆盖备份和恢复任务的数据库设置:

  • GITLAB_BACKUP_PGHOST
  • GITLAB_BACKUP_PGUSER
  • GITLAB_BACKUP_PGPORT
  • GITLAB_BACKUP_PGPASSWORD
  • GITLAB_BACKUP_PGSSLMODE
  • GITLAB_BACKUP_PGSSLKEY
  • GITLAB_BACKUP_PGSSLCERT
  • GITLAB_BACKUP_PGSSLROOTCERT
  • GITLAB_BACKUP_PGSSLCRL
  • GITLAB_BACKUP_PGSSLCOMPRESSION

例如,要覆盖数据库主机和端口以通过 Linux 软件包 (Omnibus) 使用 192.168.1.10 和端口 5432:

sudo GITLAB_BACKUP_PGHOST=192.168.1.10 GITLAB_BACKUP_PGPORT=5432 /opt/gitlab/bin/gitlab-backup create

如果您在多个数据库上运行极狐GitLab,您可以通过在环境变量中包含数据库名称来覆盖数据库设置。例如,如果您的 mainci 数据库托管在不同的数据库服务器上,您可以将它们的名称附加在 GITLAB_BACKUP_ 前缀之后,而将 PG* 名称保留为原样:

sudo GITLAB_BACKUP_MAIN_PGHOST=192.168.1.10 GITLAB_BACKUP_CI_PGHOST=192.168.1.12 /opt/gitlab/bin/gitlab-backup create

有关这些参数的更多信息,请参见 PostgreSQL 文档

仓库备份和恢复的 gitaly-backup

  • 引入于极狐GitLab 14.2。
  • 部署在功能标志后,默认启用。
  • 普遍可用于极狐GitLab 14.10。移除功能标志 gitaly_backup

备份 Rake 任务使用 gitaly-backup 二进制文件从 Gitaly 创建和恢复仓库备份。gitaly-backup 取代了之前从极狐GitLab 直接调用 Gitaly 上的 RPC 的备份方法。

备份 Rake 任务必须能够找到此可执行文件。在大多数情况下,您不需要更改二进制文件的路径,因为它应该可以与默认路径 /opt/gitlab/embedded/bin/gitaly-backup 一起正常工作。 如果您有特定原因需要更改路径,可以在 Linux 软件包(Omnibus)中进行配置:

  1. 将以下内容添加到 /etc/gitlab/gitlab.rb

    gitlab_rails['backup_gitaly_backup_path'] = '/path/to/gitaly-backup'
    
  2. 重新配置极狐GitLab 以使更改生效。

替代备份策略

由于每个部署可能具有不同的功能,因此您应该首先查看需要备份哪些数据,以更好地了解是否以及如何使用这些功能。

例如,如果您使用 Amazon RDS,您可以选择使用其内置的备份和恢复功能来处理极狐GitLab PostgreSQL 数据并在使用备份命令排除 PostgreSQL 数据

在以下情况下,请考虑使用文件系统数据传输或快照作为备份策略的一部分:

  • 您的极狐GitLab 实例包含大量 Git 仓库数据,并且极狐GitLab 备份脚本太慢。
  • 您的极狐GitLab 实例有很多派生项目,定期备份任务会复制所有项目的 Git 数据。
  • 您的极狐GitLab 实例有问题,无法使用常规备份和导入 Rake 任务。
caution Gitaly Cluster 不支持快照备份

当考虑使用文件系统数据传输或快照时:

  • 不要使用这些方法从一种操作系统迁移到另一种操作系统。源和目标的操作系统应尽可能相似。例如,不要使用这些方法从 Ubuntu 迁移到 RHEL。
  • 数据一致性非常重要。在进行文件系统传输(例如使用 rsync)或拍摄快照之前,您应该使用 sudo gitlab-ctl stop 停止极狐GitLab。

示例:Amazon Elastic Block Store (EBS)

  • 使用托管在 Amazon AWS 上的 Linux 软件包 (Omnibus) 的极狐GitLab 服务器。
  • 包含 ext4 文件系统的 EBS 驱动器挂载在 /var/opt/gitlab
  • 在这种情况下,您可以通过拍摄 EBS 快照来进行应用程序备份。
  • 备份包括所有仓库、上传和 PostgreSQL 数据。

示例:Logical Volume Manager (LVM) 快照 + rsync

  • 使用 Linux 软件包 (Omnibus) 的极狐GitLab 服务器,LVM 逻辑卷挂载在 /var/opt/gitlab
  • 使用 rsync 复制 /var/opt/gitlab 目录并不可靠,因为 rsync 运行时会更改太多文件。
  • 我们创建一个临时 LVM 快照,而不是 rsync /var/opt/gitlab,并将其作为只读文件系统挂载在 /mnt/gitlab_backup 处。
  • 现在我们可以有一个运行时间更长的 rsync 作业,它在远程服务器上创建一致的副本。
  • 副本包括所有仓库、上传和 PostgreSQL 数据。

如果您在虚拟化服务器上运行极狐GitLab,您还可以创建整个极狐GitLab 服务器的 VM 快照。然而,虚拟机快照要求您关闭服务器电源的情况并不少见,这限制了该解决方案的实际使用。

分别备份仓库数据

首先确保您在跳过仓库时备份现有的极狐GitLab 数据:

::Tabs

:::TabTitle Linux 软件包(Omnibus)

sudo gitlab-backup create SKIP=repositories

:::TabTitle 自编译

sudo -u git -H bundle exec rake gitlab:backup:create SKIP=repositories RAILS_ENV=production

::EndTabs

要在磁盘上手动备份 Git 仓库数据,有多种可能的策略:

防止写入和复制 Git 仓库数据

Git 仓库必须以一致的方式复制。不应在并发写入操作期间进行复制,因为这可能会导致不一致或损坏问题。

为了防止写入 Git 仓库数据,有两种可能的方法:

  • 使用维护模式将极狐GitLab 置于只读状态。
  • 在备份仓库之前停止所有 Gitaly 服务,以创建明确的停机时间:

    sudo gitlab-ctl stop gitaly
    # execute git data copy step
    sudo gitlab-ctl start gitaly
    

您可以使用任何方法复制 Git 仓库数据,只要防止对正在复制的数据进行写入(以防止不一致和损坏问题)。按照优先级和安全性的顺序,推荐的方法是:

  1. 通过归档模式、删除和校验和选项使用 rsync,例如:

    rsync -aR --delete --checksum source destination # be extra safe with the order as it will delete existing data if inverted
    
  2. 使用 tar pipe 以将整个仓库的目录复制到另一个服务器或位置

  3. 使用 sftpscpcp 和任何其他方法。

通过将仓库标记为只读进行在线备份(实验性功能)

在不需要实例级范围停机的情况下备份仓库的一种方法是以编程方式将项目标记为只读,同时复制基础数据。

这样做有一些可能的缺点:

  • 仓库在一段时间内是只读的,该时间段随仓库的大小而变化。
  • 由于将每个项目标记为只读,备份需要更长的时间才能完成,这可能会导致不一致。例如,第一个备份项目的最新可用数据与最后一个备份项目的可用数据之间可能存在日期差异。
  • 派生网络应该是完全只读的,同时备份里面的项目以防止对池仓库的潜在更改。

技术支持

如果您在迁移过程中遇到任何问题,您可以在极狐GitLab 官方论坛上发帖求助,您也可以直接扫描下方二维码咨询专业人员:

jihu-gitlab-support