备份极狐GitLab
Tier: 基础版,专业版,旗舰版
Offering: 私有化部署
极狐GitLab 备份保护您的数据,有助于灾难恢复。
最佳备份策略取决于您的极狐GitLab 部署配置、数据量和存储位置。这些因素决定了使用哪些备份方法、备份存储在哪里以及如何组织备份计划。
对于较大的极狐GitLab 实例,替代备份策略包括:
- 增量备份。
- 特定仓库的备份。
- 跨多个存储位置的备份。
备份包含的数据
版本历史
- 安全文件在极狐GitLab 16.1 中引入。
- 外部合并请求差异在极狐GitLab 17.1 中引入。
极狐GitLab 提供了一个命令行界面来备份您的整个实例。默认情况下,备份会创建一个归档,打包成一个压缩的 tar 文件。该文件包括:
- 数据库数据和配置
- 账号和群组设置
- CI/CD 产物和作业日志
- Git 仓库和 LFS 对象
- 外部合并请求差异
- 软件包仓库数据和容器镜像仓库镜像
- 项目和群组 Wiki
- 项目级附件和上传
- 安全文件
- 极狐GitLab Pages 内容
- Terraform 状态
- 代码片段
备份不包含的数据
强烈建议您阅读 存储配置文件,以单独备份这些文件。
- Mattermost 数据
- Redis(以及 Sidekiq 作业)
- Linux 软件包 (Omnibus) / Docker / 自编译安装中的 对象存储
- 全局服务器钩子
- 文件钩子
- 极狐GitLab 配置文件 (/etc/gitlab)
- TLS 和 SSH 相关密钥和证书
- 其他系统文件
简单备份过程
作为一个粗略的指南,如果您使用的是 1k 参考架构且数据量少于 100 GB,请按照以下步骤操作:
- 运行备份命令。
- 如果适用,备份对象存储。
- 手动备份系统配置文件。
另请参阅:
扩展备份
随着极狐GitLab 数据量的增长,备份命令执行时间会变长。诸如并发备份 Git 仓库和增量仓库备份等选项有助于缩短执行时间。在某个时候,备份命令本身会变得不切实际。例如,它可能需要 24 小时或更长时间。
从极狐GitLab 18.0 开始,对于拥有大量引用(分支、标签)的仓库,仓库备份性能得到了显著提升。对于受影响的仓库,此改进可以将备份时间从数小时缩短至几分钟。无需更改任何配置即可从此增强中受益。
在某些情况下,可能需要进行架构更改以使备份能够扩展。
延伸阅读:
哪些数据需要备份?
以下数据需要备份。
PostgreSQL 数据库
在最简单的情况下,极狐GitLab 有一个 PostgreSQL 数据库,位于一个 PostgreSQL 服务器上,与所有其他极狐GitLab 服务在同一台虚拟机上。但根据配置,极狐GitLab 可能会在多个 PostgreSQL 服务器上使用多个 PostgreSQL 数据库。
一般来说,这些数据是 Web 界面中大多数用户生成内容的唯一真实来源,例如议题和合并请求内容、评论、权限和凭证。
PostgreSQL 还保存了一些缓存数据,如 HTML 渲染的 Markdown,以及默认情况下的合并请求差异。但是,合并请求差异也可以配置为 卸载 到文件系统或对象存储。
Gitaly 集群 (Praefect) 使用 PostgreSQL 数据库作为管理其 Gitaly 节点的唯一真实来源。
常见的 PostgreSQL 实用程序 pg_dump 会生成可用于恢复 PostgreSQL 数据库的备份文件。备份命令 底层使用了此实用程序。
不幸的是,数据库越大,pg_dump 执行所需的时间就越长。根据您的情况,持续时间在某个点会变得不切实际(例如数天)。如果您的数据库超过 100 GB,pg_dump,进而 备份命令 很可能无法使用。有关更多信息,请参阅 替代备份策略。
Git 仓库
极狐GitLab 实例可以有一个或多个仓库分片。每个分片是一个 Gitaly 实例或 Gitaly 集群 (Praefect),负责允许对本地存储的 Git 仓库进行访问和操作。Gitaly 可以运行在以下机器上:
- 具有单个磁盘。
- 具有挂载为单个挂载点的多个磁盘(如 RAID 阵列)。
- 使用 LVM。
每个项目最多可以有 3 个不同的仓库:
- 项目仓库,存储源代码。
- Wiki 仓库,存储 Wiki 内容。
- 设计仓库,对设计资产进行索引(资产实际存储在 LFS 中)。
它们都位于同一个分片中,并共享相同的基础名称,对于 Wiki 和设计仓库,分别带有 -wiki 和 -design 后缀。
个人和项目代码片段以及群组 Wiki 内容都存储在 Git 仓库中。
项目派生在极狐GitLab 站点中通过池仓库进行去重。
备份命令为每个仓库生成一个 Git 包并打包成 tar。这会将池仓库数据复制到每个派生中。在我们的测试中,100 GB 的 Git 仓库备份并上传到 S3 用了两个多小时。在 Git 数据量达到约 400 GB 时,备份命令可能不再适合定期备份。有关更多信息,请参阅 替代备份策略。
Blob 数据
极狐GitLab 将 blob(或文件)如议题附件或 LFS 对象存储在以下位置之一:
- 特定位置的文件系统中。
- 对象存储 解决方案。对象存储解决方案可以是:
- 基于云的,如 Amazon S3 和 Google Cloud Storage。
- 自托管的与 S3 兼容的对象存储。
- 暴露对象存储兼容 API 的存储设备。
对象存储
备份命令不会备份未存储在文件系统上的 blob。如果您正在使用对象存储,请确保使用您的对象存储提供商启用备份。
提供商专用的备份指南:
另请参阅:
容器镜像仓库
极狐GitLab 容器镜像仓库存储可以配置在以下位置之一:
- 特定位置的文件系统中。
- 对象存储解决方案。对象存储解决方案可以是:
- 基于云的,如 Amazon S3 和 Google Cloud Storage。
- 自托管的与 S3 兼容的对象存储。
- 暴露对象存储兼容 API 的存储设备。
当容器镜像仓库数据存储在对象存储中时,备份命令不会备份这些数据。
元数据数据库
如果您已启用 容器镜像仓库元数据数据库,则必须在备份期间配置对镜像仓库数据库的访问。按照您的极狐GitLab 安装说明配置所需的凭证:
另请参阅:
存储配置文件
极狐GitLab 提供的备份 Rake 任务不存储您的配置文件。主要原因是您的数据库包含诸如双因素身份验证和 CI/CD 安全变量等加密信息。将加密信息与其密钥存储在同一位置,首先就违背了使用加密的目的。例如,secrets 文件包含您的数据库加密密钥。如果丢失此文件,极狐GitLab 应用程序将无法解密数据库中的任何加密值。 此外,secrets 文件在升级后可能会发生变化。
您应该备份配置目录。至少,您必须备份:
- /etc/gitlab/gitlab-secrets.json
- /etc/gitlab/gitlab.rb
有关更多信息,请参阅 备份和恢复 Linux 软件包 (Omnibus) 配置。
您可能还想备份任何 TLS 密钥和证书 (/etc/gitlab/ssl, /etc/gitlab/trusted-certs),以及您的 SSH 主机密钥,以避免在必须执行完整机器恢复时出现中间人攻击警告。
如果不幸丢失了 secrets 文件,请参阅 当 secrets 文件丢失时。
其他数据
极狐GitLab 使用 Redis 作为缓存存储并保存后台作业系统 Sidekiq 的持久数据。提供的备份命令不备份 Redis 数据。这意味着,为了使用备份命令进行一致的备份,必须没有待处理或正在运行的后台作业。
Elasticsearch 是用于高级搜索的可选数据库。它可以改进源代码级别的搜索以及议题、合并请求和讨论中的用户生成内容。备份命令不备份 Elasticsearch 数据。Elasticsearch 数据可以在恢复后从 PostgreSQL 数据重新生成。
手动备份选项:
另请参阅:备份命令详情。
要求
为了能够备份和恢复,请确保系统上安装了 Rsync。如果您安装极狐GitLab 时:
- 使用了 Linux 软件包,Rsync 已安装。
- 使用了自编译安装,请检查 rsync 是否已安装,如果未安装请安装。
备份命令
- 备份命令不会备份 Linux 软件包 (Omnibus) / Docker / 自编译安装中对象存储上的项目。
- 当您的安装使用 PgBouncer 时,无论是出于性能原因还是与 Patroni 集群一起使用时,备份命令需要额外的参数。
- 您只能将备份恢复到创建备份时完全相同的极狐GitLab 版本和类型(CE/EE)。
重要注意事项:
要创建备份:
shellsudo gitlab-backup create
如果您的极狐GitLab 部署有多个节点,您需要选择一个节点来运行备份命令。您必须确保指定的节点:
- 是持久的,并且不会受到自动伸缩的影响。
- 已经安装了极狐GitLab Rails 应用程序。如果 Puma 或 Sidekiq 正在运行,则 Rails 已安装。
- 有足够的存储和内存来生成备份文件。
输出示例:
plaintext1Dumping database tables: 2- Dumping table events... [DONE] 3- Dumping table issues... [DONE] 4- Dumping table keys... [DONE] 5- Dumping table merge_requests... [DONE] 6- Dumping table milestones... [DONE] 7- Dumping table namespaces... [DONE] 8- Dumping table notes... [DONE] 9- Dumping table projects... [DONE] 10- Dumping table protected_branches... [DONE] 11- Dumping table schema_migrations... [DONE] 12- Dumping table services... [DONE] 13- Dumping table snippets... [DONE] 14- Dumping table taggings... [DONE] 15- Dumping table tags... [DONE] 16- Dumping table users... [DONE] 17- Dumping table users_projects... [DONE] 18- Dumping table web_hooks... [DONE] 19- Dumping table wikis... [DONE] 20Dumping repositories: 21- Dumping repository abcd... [DONE] 22Creating backup archive: <backup-id>_gitlab_backup.tar [DONE] 23Deleting tmp directories...[DONE] 24Deleting old backups... [SKIPPING]
有关备份过程的详细信息,请参阅 备份归档过程。
备份选项
极狐GitLab 提供用于备份实例的命令行工具可以接受更多选项。
备份策略选项
默认的备份策略是本质上是使用 Linux 命令 tar 和 gzip 将数据从各自的数据位置流式传输到备份。这在大多数情况下工作良好,但当数据快速变化时可能会导致问题。
当 tar 读取数据时数据发生变化,可能会出现 file changed as we read it 错误,并导致备份过程失败。在这种情况下,您可以使用称为 copy 的备份策略。该策略在调用 tar 和 gzip 之前将数据文件复制到临时位置,从而避免错误。
副作用是备份过程最多会额外占用 1 倍的磁盘空间。该过程会尽力在每个阶段清理临时文件,因此问题不会加剧,但对于大型安装来说,这可能是一个相当大的变化。
要使用 copy 策略而不是默认的流式传输策略,请在 Rake 任务命令中指定 STRATEGY=copy。例如:
shellsudo gitlab-backup create STRATEGY=copy
备份文件名
如果您使用自定义备份文件名,则无法 限制本地文件的备份生命周期(修剪旧备份)。
备份文件根据 特定默认值 以文件名创建。但是,您可以通过设置 BACKUP 环境变量来覆盖文件名的 <backup-id> 部分。例如:
shellsudo gitlab-backup create BACKUP=dump
生成的文件名为 dump_gitlab_backup.tar。这对于使用 rsync 和增量备份的系统非常有用,并且可以显著提高传输速度。
备份压缩
默认情况下,在备份以下内容时应用 Gzip 快速压缩:
- PostgreSQL 数据库转储。
- Blob 数据,例如上传、作业产物、外部合并请求差异。
另请参阅:
默认命令是 gzip -c -1。您可以使用 COMPRESS_CMD 覆盖此命令。类似地,您可以使用 DECOMPRESS_CMD 覆盖解压缩命令。
注意事项:
- 压缩命令在管道中使用,因此您的自定义命令必须输出到 stdout。
- 如果您指定的命令未与极狐GitLab 打包在一起,则必须自行安装。
- 生成的文件名仍将以 .gz 结尾。
- 恢复时使用的默认解压缩命令是 gzip -cd。因此,如果您覆盖压缩命令以使用无法被 gzip -cd 解压缩的格式,则必须在恢复时覆盖解压缩命令。
- 不要在备份命令之后放置环境变量。例如,gitlab-backup create COMPRESS_CMD="pigz -c --best" 不会按预期工作。
默认压缩:使用最快方法的 Gzip
shellgitlab-backup create
使用最慢方法的 Gzip
shellCOMPRESS_CMD="gzip -c --best" gitlab-backup create
如果备份使用了 gzip,则恢复不需要任何选项:
shellgitlab-backup restore
无压缩
如果您的备份目标具有内置的自动压缩功能,则您可能希望跳过压缩。
tee 命令将 stdin 管道到 stdout。
shellCOMPRESS_CMD=tee gitlab-backup create
恢复时:
shellDECOMPRESS_CMD=tee gitlab-backup restore
使用 pigz 进行并行压缩
虽然我们支持使用 COMPRESS_CMD 和 DECOMPRESS_CMD 覆盖默认的 Gzip 压缩库,但我们仅在例行基础上使用默认选项测试默认的 Gzip 库。您有责任测试和验证备份的可行性。我们强烈建议将此作为备份的最佳实践,无论是否覆盖压缩命令。如果您在使用其他压缩库时遇到问题,应该回退到默认库。对于替代库的问题排查和修复,在极狐GitLab 中的优先级较低。
一个使用 4 个进程通过 pigz 压缩备份的示例:
shellsudo COMPRESS_CMD="pigz --stdout --fast --processes 4" gitlab-backup create
由于 pigz 压缩为 gzip 格式,因此不需要使用 pigz 来解压缩由 pigz 压缩的备份。但是,相对于 gzip 它仍然可以提供性能优势。使用 pigz 解压缩备份的示例:
shellsudo DECOMPRESS_CMD="pigz --decompress --stdout" gitlab-backup restore
pigz 不包含在极狐GitLab Linux 软件包中。您必须自行安装。
使用 zstd 进行并行压缩
虽然我们支持使用 COMPRESS_CMD 和 DECOMPRESS_CMD 覆盖默认的 Gzip 压缩库,但我们仅在例行基础上使用默认选项测试默认的 Gzip 库。您有责任测试和验证备份的可行性。我们强烈建议将此作为备份的最佳实践,无论是否覆盖压缩命令。如果您在使用其他压缩库时遇到问题,应该回退到默认库。对于替代库的问题排查和修复,在极狐GitLab 中的优先级较低。
一个使用 4 个线程通过 zstd 压缩备份的示例:
shellsudo COMPRESS_CMD="zstd --compress --stdout --fast --threads=4" gitlab-backup create
使用 zstd 解压缩备份的示例:
shellsudo DECOMPRESS_CMD="zstd --decompress --stdout" gitlab-backup restore
zstd 不包含在极狐GitLab Linux 软件包中。您必须自行安装。
确认归档可以传输
为确保生成的归档可以被 rsync 传输,您可以设置 GZIP_RSYNCABLE=yes 选项。这会为 gzip 设置 --rsyncable 选项,该选项仅在结合 备份文件名选项 设置时有用。
gzip 中的 --rsyncable 选项并不能保证在所有发行版上都可用。要验证它在您的发行版中是否可用,请运行 gzip --help 或查阅 man 手册。
shellsudo gitlab-backup create BACKUP=dump GZIP_RSYNCABLE=yes
从备份中排除特定数据
根据您的安装类型,可以在创建备份时跳过略有不同的组件。
- db (数据库)
- repositories (Git 仓库数据,包括 Wikis)
- uploads (附件)
- builds (CI 作业输出日志)
- artifacts (CI 作业产物)
- pages (Pages 内容)
- lfs (LFS 对象)
- terraform_state (Terraform 状态)
- registry (容器镜像仓库镜像)
- packages (软件包)
- ci_secure_files (项目级安全文件)
- external_diffs (外部合并请求差异)
shellsudo gitlab-backup create SKIP=db,uploads
SKIP= 也用于:
- 跳过创建 tar 文件 (SKIP=tar)。
- 跳过将备份上传到远程存储 (SKIP=remote)。
跳过创建 tar 文件
当使用 对象存储 进行备份时,无法跳过创建 tar 文件。
创建备份的最后一部分是生成包含所有部分的 .tar 文件。在某些情况下,创建 .tar 文件可能是浪费精力甚至直接有害的,因此您可以通过将 tar 添加到 SKIP 环境变量来跳过此步骤。示例用例:
- 当备份由其他备份软件拾取时。
- 通过避免每次都必须提取备份来加速增量备份。(在这种情况下,不得指定 PREVIOUS_BACKUP 和 BACKUP,否则会提取指定的备份,但最后不会生成 .tar 文件。)
将 tar 添加到 SKIP 变量会将包含备份的文件和目录留在用于中间文件的目录中。创建新备份时这些文件会被覆盖,因此您应确保将它们复制到其他地方,因为系统上只能有一个备份。
shellsudo gitlab-backup create SKIP=tar
创建服务器端仓库备份
版本历史
与其在备份归档中存储大型仓库备份,不如配置仓库备份,让托管每个仓库的 Gitaly 节点负责创建备份并将其流式传输到对象存储。这有助于减少创建和恢复备份所需的网络资源。
- 在 Gitaly 中配置服务端备份目标。
- 使用仓库服务端选项创建备份。请参见以下示例。
shellsudo gitlab-backup create REPOSITORIES_SERVER_SIDE=true
并发备份 Git 仓库
当使用多个仓库存储时,可以并发备份或恢复仓库,以帮助充分利用 CPU 时间。以下变量可用于修改 Rake 任务的默认行为:
- GITLAB_BACKUP_MAX_CONCURRENCY:同时备份的最大项目数。默认为逻辑 CPU 的数量。
- GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY:在每个存储上同时备份的最大项目数。这允许将仓库备份分布到不同的存储上。默认为 2。
例如,有 4 个仓库存储时:
shellsudo gitlab-backup create GITLAB_BACKUP_MAX_CONCURRENCY=4 GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY=1
增量仓库备份
版本历史
- 创建增量备份的服务端支持引入于极狐GitLab 16.6。
只有仓库支持增量备份。因此,如果你使用 INCREMENTAL=yes,该任务会创建一个自包含的备份 tar 归档。这是因为除仓库外的所有子任务仍会创建完整备份(它们会覆盖现有的完整备份)。 请参见 issue 19256 以了解支持所有子任务增量备份的功能请求。
增量仓库备份比完整仓库备份更快,因为它们只将自上次备份以来的更改打包到每个仓库的备份包中。 gitlab-backup 生成的备份归档是可移植且自包含的,因为它们包含了从原始完整备份开始恢复每个仓库所需的所有步骤。
要将增量备份恢复到新的极狐GitLab 实例(无预先存在的数据),你必须从完整备份创建增量备份。 创建基础备份时,不要跳过任何备份组件。
使用服务端仓库备份时,增量仓库备份文件会单独存储在对象存储中。每个增量都依赖于回溯到原始完整备份的所有先前步骤。
不要从对象存储中删除增量备份文件。如果中间文件被删除(例如,通过对象存储生命周期策略),备份链将中断,备份将无法恢复。
更多详细信息,请参见恢复增量仓库备份。
使用 PREVIOUS_BACKUP=<backup-id> 选项来选择要使用的备份。默认情况下,备份文件按照备份 ID 部分所述创建。你可以通过设置 BACKUP 环境变量来覆盖文件名的 <backup-id> 部分。
要创建增量备份,请运行:
shellsudo gitlab-backup create INCREMENTAL=yes PREVIOUS_BACKUP=<backup-id>
要从已 tar 的备份创建未 tar 的增量备份,请使用 SKIP=tar:
shellsudo gitlab-backup create INCREMENTAL=yes SKIP=tar
备份特定仓库存储
版本历史
- 引入于极狐GitLab 15.0。
当使用多个仓库存储时,可以使用 REPOSITORIES_STORAGES 选项单独备份特定仓库存储中的仓库。该选项接受以逗号分隔的存储名称列表。
例如:
shellsudo gitlab-backup create REPOSITORIES_STORAGES=storage1,storage2
备份特定仓库
版本历史
- 引入于极狐GitLab 15.1。
- 跳过特定仓库的功能添加于极狐GitLab 16.1。
你可以使用 REPOSITORIES_PATHS 选项备份特定仓库。同样,你可以使用 SKIP_REPOSITORIES_PATHS 跳过某些仓库。这两个选项都接受以逗号分隔的项目或群组路径列表。如果你指定了一个群组路径,则该群组及其后代群组中所有项目的所有仓库都会被包含或跳过,具体取决于你使用的选项。
例如,备份群组 A (group-a) 中所有项目的所有仓库、群组 B (group-b/project-c) 中项目 C 的仓库,并跳过群组 A (group-a/project-d) 中的项目 D:
shellsudo gitlab-backup create REPOSITORIES_PATHS=group-a,group-b/project-c SKIP_REPOSITORIES_PATHS=group-a/project-d
将备份上传到远程(云)存储
当使用对象存储进行备份时,无法跳过 tar 创建。
你可以让备份脚本将其创建的 .tar 文件上传到远程存储。 在以下示例中,我们使用 Amazon S3 进行存储,但你也可以使用其他云提供商,如 Google Cloud Storage 和 Azure,或本地挂载共享。
另请参见:
使用 Amazon S3
对于 Linux 软件包 (Omnibus):
-
将以下内容添加到 /etc/gitlab/gitlab.rb:
ruby1gitlab_rails['backup_upload_connection'] = { 2 'provider' => 'AWS', 3 'region' => 'eu-west-1', 4 # 选择一种身份验证方法 5 # IAM 配置文件 6 'use_iam_profile' => true 7 # 或者 AWS 访问密钥和私有密钥 8 'aws_access_key_id' => 'AKIAKIAKI', 9 'aws_secret_access_key' => 'secret123' 10} 11gitlab_rails['backup_upload_remote_directory'] = 'my.s3.bucket' 12# 当文件大小达到 100 MB 时,考虑使用分段上传。输入一个以字节为单位的数字。 13# gitlab_rails['backup_multipart_chunk_size'] = 104857600 -
如果你使用 IAM 配置文件身份验证方法,请确保运行 backup-utility 的实例设置了以下策略(将 <backups-bucket> 替换为正确的存储桶名称):
json1{ 2 "Version": "2012-10-17", 3 "Statement": [ 4 { 5 "Effect": "Allow", 6 "Action": [ 7 "s3:PutObject", 8 "s3:GetObject", 9 "s3:DeleteObject" 10 ], 11 "Resource": "arn:aws:s3:::<backups-bucket>/*" 12 } 13 ] 14} -
重新配置极狐GitLab 以使更改生效
S3 加密存储桶
AWS 支持这些服务端加密模式:
- Amazon S3 托管密钥 (SSE-S3)
- 存储在 AWS Key Management Service (SSE-KMS) 中的客户主密钥 (CMKs)
- 客户提供的密钥 (SSE-C)
在极狐GitLab 中使用你选择的模式。每种模式的配置方法相似但略有不同。
SSE-S3
要启用 SSE-S3,请在备份存储选项中将 server_side_encryption 字段设置为 AES256。例如,在 Linux 软件包 (Omnibus) 中:
rubygitlab_rails['backup_upload_storage_options'] = { 'server_side_encryption' => 'AES256' }
SSE-KMS
要启用 SSE-KMS,你需要通过其 Amazon 资源名称 (ARN)(格式为 arn:aws:kms:region:acct-id:key/key-id)获取 KMS 密钥。 在 backup_upload_storage_options 配置设置下,设置:
- server_side_encryption 为 aws:kms。
- server_side_encryption_kms_key_id 为密钥的 ARN。
例如,在 Linux 软件包 (Omnibus) 中:
rubygitlab_rails['backup_upload_storage_options'] = { 'server_side_encryption' => 'aws:kms', 'server_side_encryption_kms_key_id' => 'arn:aws:<你的 KMS 密钥 ID>:' }
SSE-C
SSE-C 要求你设置这些加密选项:
- backup_encryption:AES256。
- backup_encryption_key:未编码的 32 字节(256 位)密钥。如果密钥不是正好 32 字节,上传将失败。
例如,在 Linux 软件包 (Omnibus) 中:
rubygitlab_rails['backup_encryption'] = 'AES256' gitlab_rails['backup_encryption_key'] = '<你的 32 字节密钥>'
如果密钥包含二进制字符且无法以 UTF-8 编码,请改用 GITLAB_BACKUP_ENCRYPTION_KEY 环境变量指定密钥。 例如:
rubygitlab_rails['env'] = { 'GITLAB_BACKUP_ENCRYPTION_KEY' => "\xDE\xAD\xBE\xEF" * 8 }
Digital Ocean Spaces
此示例可用于阿姆斯特丹 (AMS3) 的存储桶:
-
将以下内容添加到 /etc/gitlab/gitlab.rb:
ruby1gitlab_rails['backup_upload_connection'] = { 2 'provider' => 'AWS', 3 'region' => 'ams3', 4 'aws_access_key_id' => 'AKIAKIAKI', 5 'aws_secret_access_key' => 'secret123', 6 'endpoint' => 'https://ams3.digitaloceanspaces.com' 7} 8gitlab_rails['backup_upload_remote_directory'] = 'my.s3.bucket' -
重新配置极狐GitLab 以使更改生效
如果在使用 Digital Ocean Spaces 时看到 400 Bad Request 错误消息,原因可能是使用了备份加密。因为 Digital Ocean Spaces 不支持加密,请移除或注释包含 gitlab_rails['backup_encryption'] 的行。
其他 S3 提供商
并非所有 S3 提供商都与 Fog 库完全兼容。例如,如果你在尝试上传后看到 411 Length Required 错误消息,你可能需要由于此问题将 aws_signature_version 值从默认值降级为 2。
对于自行编译的安装:
-
编辑 home/git/gitlab/config/gitlab.yml:
yaml1 backup: 2 # snip 3 upload: 4 # Fog 存储连接设置,请参见 https://fog.github.io/storage/ 。 5 connection: 6 provider: AWS 7 region: eu-west-1 8 aws_access_key_id: AKIAKIAKI 9 aws_secret_access_key: 'secret123' 10 # 如果使用 IAM 配置文件,请将 aws_access_key_id 和 aws_secret_access_key 留空 11 # 即 aws_access_key_id: '' 12 # use_iam_profile: 'true' 13 # 用于存储备份的远程“目录”。对于 S3,这将是存储桶名称。 14 remote_directory: 'my.s3.bucket' 15 # 指定用于备份的 Amazon S3 存储类,这是可选的 16 # storage_class: 'STANDARD' 17 # 18 # 为备份开启使用 Amazon 客户提供的加密密钥的 AWS 服务端加密,这是可选的 19 # 必须设置 'encryption' 才能使其生效。 20 # 'encryption_key' 应设置为 Amazon S3 用于加密或解密的 256 位加密密钥。 21 # 为避免将密钥存储在磁盘上,也可以通过 `GITLAB_BACKUP_ENCRYPTION_KEY` 环境变量指定密钥。 22 # encryption: 'AES256' 23 # encryption_key: '<key>' 24 # 25 # 26 # 为备份开启使用 Amazon S3 托管密钥的 AWS 服务端加密(可选) 27 # https://docs.aws.amazon.com/AmazonS3/latest/userguide/serv-side-encryption.html 28 # 对于 SSE-S3,将 'server_side_encryption' 设置为 'AES256'。 29 # 对于 SS3-KMS,将 'server_side_encryption' 设置为 'aws:kms'。将 30 # 'server_side_encryption_kms_key_id' 设置为主客户密钥的 ARN。 31 # storage_options: 32 # server_side_encryption: 'aws:kms' 33 # server_side_encryption_kms_key_id: 'arn:aws:kms:你的密钥 ID' -
重启极狐GitLab 以使更改生效
使用 Google Cloud Storage
要使用 Google Cloud Storage 保存备份,你必须首先从 Google 控制台创建一个访问密钥:
- 前往 Google 存储设置页面。
- 选择互操作性,然后创建一个访问密钥。
- 记下访问密钥和私有密钥,并在以下配置中替换它们。
- 在存储桶的高级设置中,确保选择了访问控制选项设置对象级和存储桶级权限。
- 确保你已经创建了一个存储桶。
对于 Linux 软件包 (Omnibus):
-
编辑 /etc/gitlab/gitlab.rb:
ruby1gitlab_rails['backup_upload_connection'] = { 2 'provider' => 'Google', 3 'google_storage_access_key_id' => '访问密钥', 4 'google_storage_secret_access_key' => '私有密钥', 5 6 ## 如果你有 CNAME 存储桶 (foo.example.com),上传备份时可能会遇到 SSL 问题 7 ## ("hostname foo.example.com.storage.googleapis.com 8 ## 与服务器证书不匹配")。在这种情况下,请取消注释以下 9 ## 设置。请参见:https://github.com/fog/fog/issues/2834 10 #'path_style' => true 11} 12gitlab_rails['backup_upload_remote_directory'] = 'my.google.bucket' -
重新配置极狐GitLab 以使更改生效
对于自行编译的安装:
-
编辑 home/git/gitlab/config/gitlab.yml:
yaml1 backup: 2 upload: 3 connection: 4 provider: 'Google' 5 google_storage_access_key_id: '访问密钥' 6 google_storage_secret_access_key: '私有密钥' 7 remote_directory: 'my.google.bucket' -
重启极狐GitLab 以使更改生效
使用 Azure Blob 存储
-
编辑 /etc/gitlab/gitlab.rb:
ruby1gitlab_rails['backup_upload_connection'] = { 2 'provider' => 'AzureRM', 3 'azure_storage_account_name' => '<AZURE 存储账户名称>', 4 'azure_storage_access_key' => '<AZURE 存储访问密钥>', 5 'azure_storage_domain' => 'blob.core.windows.net', # 可选 6} 7gitlab_rails['backup_upload_remote_directory'] = '<AZURE BLOB 容器>'如果你正在使用托管标识,请省略 azure_storage_access_key:
ruby1gitlab_rails['backup_upload_connection'] = { 2 'provider' => 'AzureRM', 3 'azure_storage_account_name' => '<AZURE 存储账户名称>', 4 'azure_storage_domain' => '<AZURE 存储域>' # 可选 5} 6gitlab_rails['backup_upload_remote_directory'] = '<AZURE BLOB 容器>' -
重新配置极狐GitLab 以使更改生效
更多详细信息,请参见 Azure 参数表。
为备份指定自定义目录
此选项仅适用于远程存储。如果你想对备份进行分组,可以传入 DIRECTORY 环境变量:
shellsudo gitlab-backup create DIRECTORY=daily sudo gitlab-backup create DIRECTORY=weekly
跳过将备份上传到远程存储
如果你已配置极狐GitLab 将备份上传到远程存储,可以使用 SKIP=remote 选项跳过将备份上传到远程存储。
shellsudo gitlab-backup create SKIP=remote
上传到本地挂载共享
你可以使用 Fog Local 存储提供商将备份发送到本地挂载的共享(例如 NFS、CIFS 或 SMB)。
为此,你必须设置以下配置键:
- backup_upload_connection.local_root:备份复制到的已挂载目录。
- backup_upload_remote_directory:backup_upload_connection.local_root 目录的子目录。如果不存在则创建。 如果你想将 tarball 复制到挂载目录的根目录,请使用 .。
挂载后,local_root 键中设置的目录必须由以下任一用户拥有:
- git 用户。因此,对于 CIFS 和 SMB,使用 git 用户的 uid= 进行挂载。
- 执行备份任务的用户。对于 Linux 软件包 (Omnibus),这是 git 用户。
由于文件系统性能可能影响极狐GitLab 的整体性能,我们不建议将基于云的文件系统用于存储。
避免配置冲突
不要将以下配置键设置为相同的路径:
- gitlab_rails['backup_path'](对于自行编译的安装是 backup.path)。
- gitlab_rails['backup_upload_connection'].local_root(对于自行编译的安装是 backup.upload.connection.local_root)。
backup_path 配置键设置备份文件的本地位置。upload 配置键旨在用于将备份文件上传到单独的服务器,可能是为了存档目的。
如果这些配置键设置为相同的位置,上传功能会因为上传位置已存在备份而失败。此失败会导致上传功能删除备份,因为它假定这是上次上传尝试失败后残留的文件。
配置上传到本地挂载共享
-
编辑 /etc/gitlab/gitlab.rb:
ruby1gitlab_rails['backup_upload_connection'] = { 2 :provider => 'Local', 3 :local_root => '/mnt/backups' 4} 5 6# 挂载文件夹内用于复制备份的目录 7# 使用 '.' 将它们存储在根目录中 8gitlab_rails['backup_upload_remote_directory'] = 'gitlab_backups' -
重新配置极狐GitLab 以使更改生效。
备份归档权限
极狐GitLab 创建的备份归档(1393513186_2014_02_27_gitlab_backup.tar)默认拥有所有者/群组 git/git 和 0600 权限。这是为了避免其他系统用户读取极狐GitLab 数据。如果你需要备份归档具有不同的权限,可以使用 archive_permissions 设置。
-
编辑 /etc/gitlab/gitlab.rb:
rubygitlab_rails['backup_archive_permissions'] = 0644 # 使备份归档全局可读 -
重新配置极狐GitLab 以使更改生效。
配置 cron 进行每日备份
以下 cron 作业不会备份你的极狐GitLab 配置文件或 SSH 主机密钥。
重要提示: 请记住同时备份:
你可以安排一个 cron 作业来备份你的仓库和极狐GitLab 元数据。
-
编辑 root 用户的 crontab:
shellsudo su - crontab -e -
在其中添加以下行以安排每天凌晨 2 点进行备份:
plaintext0 2 * * * /opt/gitlab/bin/gitlab-backup create CRON=1
CRON=1 环境设置指示备份脚本在没有错误时隐藏所有进度输出。建议这样做以减少 cron 垃圾信息。但是,在排查备份问题时,请将 CRON=1 替换为 --trace 以进行详细日志记录。
限制本地文件的备份生命周期(清理旧备份)
如果你为备份使用了自定义文件名,本节描述的过程将不起作用。
此配置选项仅管理本地文件。极狐GitLab 不会清理存储在第三方对象存储中的旧文件,因为用户可能没有权限列出和删除文件。建议你为你的对象存储配置适当的保留策略。
参见:
-
编辑 /etc/gitlab/gitlab.rb:
ruby## Limit backup lifetime to 7 days - 604800 seconds gitlab_rails['backup_keep_time'] = 604800 -
重新配置极狐GitLab 以使更改生效。
在使用 PgBouncer 的安装中进行备份和恢复
请勿通过 PgBouncer 连接备份或恢复极狐GitLab。这些任务必须绕过 PgBouncer 并直接连接到 PostgreSQL 主数据库节点,否则会导致极狐GitLab 服务中断。
当极狐GitLab 的备份或恢复任务与 PgBouncer 一起使用时,将显示以下错误消息:
rubyActiveRecord::StatementInvalid: PG::UndefinedTable
每次极狐GitLab 备份运行时,极狐GitLab 开始生成 500 错误,关于缺失表的错误将被 PostgreSQL 记录:
plaintext错误:关系 "tablename" 在字符 123 处不存在
这是因为该任务使用了 pg_dump,它设置了一个空的搜索路径,并在每个 SQL 查询中显式包含模式,以解决 CVE-2018-1058。
由于在事务池模式下重用与 PgBouncer 的连接,PostgreSQL 无法搜索默认的 public 模式。因此,清除搜索路径导致表和列似乎缺失。
技术参考:
- Schema 处理实现
- CVE-2018-1058 详情
绕过 PgBouncer
有两种方法可以解决此问题:
- 为备份任务使用环境变量覆盖数据库设置。
- 重新配置节点以直接连接到 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:
shellsudo GITLAB_BACKUP_PGHOST=192.168.1.10 GITLAB_BACKUP_PGPORT=5432 /opt/gitlab/bin/gitlab-backup create
如果你在多个数据库上运行 极狐GitLab,可以通过在环境变量中包含数据库名称来覆盖数据库设置。例如,如果你的 main 和 ci 数据库托管在不同的数据库服务器上,你可以在 GITLAB_BACKUP_ 前缀之后附加它们的名称,而保持 PG* 名称不变:
shellsudo 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
gitaly-backup 二进制文件被备份 Rake 任务用于创建和恢复来自 Gitaly 的仓库备份。 gitaly-backup 替换了之前从 极狐GitLab 直接调用 Gitaly 上的 RPC 的备份方法。
备份 Rake 任务必须能够找到该可执行文件。在大多数情况下,你无需更改该二进制文件的路径,因为默认路径 /opt/gitlab/embedded/bin/gitaly-backup 应该可以正常工作。 如果你有特定的理由需要更改路径,可以在 Linux 软件包 (Omnibus) 中进行配置:
-
在 /etc/gitlab/gitlab.rb 中添加以下内容:
rubygitlab_rails['backup_gitaly_backup_path'] = '/path/to/gitaly-backup' -
重新配置极狐GitLab 以使更改生效。
替代备份策略
由于每个部署可能具有不同的能力,你应该首先检查需要备份哪些数据,以便更好地了解是否以及如何利用它们。
例如,如果你使用 Amazon RDS,你可能选择使用其内置的备份和恢复功能来处理你的极狐GitLab PostgreSQL 数据,并在使用备份命令时排除 PostgreSQL 数据。
参见:
在以下情况下,考虑将文件系统数据传输或快照作为备份策略的一部分:
- 你的极狐GitLab 实例包含大量 Git 仓库数据,而极狐GitLab 备份脚本太慢。
- 你的极狐GitLab 实例有很多派生项目,常规备份任务会为所有这些项目复制 Git 数据。
- 你的极狐GitLab 实例出现问题,无法使用常规备份和导入 Rake 任务。
Gitaly 集群 (Praefect) 不支持快照备份。
在考虑使用文件系统数据传输或快照时:
- 请勿使用这些方法从一个操作系统迁移到另一个操作系统。源操作系统和目标操作系统应尽可能相似。例如,请勿使用这些方法从 Ubuntu 迁移到 RHEL。
- 数据一致性至关重要。在进行文件系统传输(例如使用 rsync)或创建快照之前,你应该停止 极狐GitLab(sudo gitlab-ctl stop),以确保内存中的所有数据都刷新到磁盘。极狐GitLab 由多个子系统(Gitaly、数据库、文件存储)组成,这些子系统有自己的缓冲区、队列和存储层。极狐GitLab 事务可能跨越这些子系统,导致事务的部分以不同路径写入磁盘。在实时系统上,文件系统传输和快照运行无法捕获仍保留在内存中的事务部分。
示例:Amazon Elastic Block Store (EBS)
- 一个托管在 Amazon AWS 上并使用 Linux 软件包 (Omnibus) 的 极狐GitLab 服务器。
- 一个包含 ext4 文件系统的 EBS 驱动器挂载在 /var/opt/gitlab。
- 在这种情况下,你可以通过创建 EBS 快照来制作应用程序备份。
- 该备份包括所有仓库、上传文件和 PostgreSQL 数据。
示例:逻辑卷管理器 (LVM) 快照 + rsync
- 一个使用 Linux 软件包 (Omnibus) 的 极狐GitLab 服务器,其 LVM 逻辑卷挂载在 /var/opt/gitlab。
- 使用 rsync 复制 /var/opt/gitlab 目录并不靠谱,因为在 rsync 运行时会有太多文件发生变化。
- 我们不直接 rsync /var/opt/gitlab,而是创建一个临时 LVM 快照,并将其作为只读文件系统挂载到 /mnt/gitlab_backup。
- 现在我们可以运行一个较长时间的 rsync 作业,在远程服务器上创建一个一致性的副本。
- 该副本包括所有仓库、上传文件和 PostgreSQL 数据。
如果你在虚拟化服务器上运行 极狐GitLab,你也可以创建整个 极狐GitLab 服务器的 VM 快照。然而,VM 快照通常要求你关闭服务器电源,这限制了该解决方案的实际用途。
单独备份仓库数据
首先,确保在跳过仓库的情况下备份现有极狐GitLab 数据:
shellsudo gitlab-backup create SKIP=repositories
对于手动备份磁盘上的 Git 仓库数据,有多种可能的策略:
- 使用快照,例如前面的 Amazon EBS 驱动器快照示例,或 LVM 快照 + rsync。
- 使用 极狐GitLab Geo 并依赖 Geo 辅助站点上的仓库数据。
- 阻止写入并复制 Git 仓库数据。
- 通过将仓库标记为只读来创建在线备份(实验性)。
阻止写入并复制 Git 仓库数据
必须以一致的方式复制 Git 仓库。如果在并发写操作期间复制仓库,可能会发生不一致或损坏问题。这可能导致仓库损坏、丢失提交或备份数据不完整。
有两种可能的方法来阻止对 Git 仓库数据的写入:
-
使用维护模式将 极狐GitLab 置于只读状态。
-
在备份仓库之前停止所有 Gitaly 服务,以创建明确的停机时间:
shellsudo gitlab-ctl stop gitaly # 执行 git 数据复制步骤 sudo gitlab-ctl start gitaly
你可以使用任何方法复制 Git 仓库数据,只要在复制数据时阻止写入(以防止不一致和损坏问题)。按偏好和安全性排序,推荐的方法有:
-
使用带有归档模式、删除和校验和选项的 rsync,例如:
shellrsync -aR --delete --checksum source destination # 注意顺序以防意外删除现有数据 -
使用 sftp、scp、cp 或任何其他复制方法。
通过将仓库标记为只读进行在线备份(实验性)
一种无需整个实例停机即可备份仓库的方法是,在复制底层数据时以编程方式将项目标记为只读。
这存在一些可能的缺点:
- 仓库在备份期间将处于只读状态,时间长短与仓库大小成正比。
- 由于需要将每个项目标记为只读,备份可能需要更长时间才能完成,这可能导致不一致。例如,第一个被备份的项目与最后一个被备份的项目之间,最后可用的数据可能存在日期差异。
- 为避免对池存储库的潜在更改,派生网络在内部项目备份期间应完全处于只读状态。
在 Geo 团队 Runbooks 项目中有一个实验性脚本,尝试自动化此过程。