{{< details >}}

  • Tier: 基础版、专业版、旗舰版
  • Offering: 私有化部署

{{< /details >}}

极狐GitLab 备份保持数据一致性,并支持大型极狐GitLab 部署的灾难恢复。此过程:

  • 协调分布式存储组件的数据备份
  • 保存 PostgreSQL 数据库,大小可达多个 TB
  • 保护外部服务中的对象存储数据
  • 维护大型 Git 存储库集合的备份完整性
  • 创建可恢复的配置和密钥文件副本
  • 使系统数据的恢复能够最大限度地减少停机时间

请遵循这些程序,以支持 3,000+ 用户的参考架构运行极狐GitLab 环境,并特别考虑基于云的数据库和对象存储。

{{< alert type=”note” >}}

本文档面向使用以下环境:

{{< /alert >}}

配置每日备份

配置 PostgreSQL 数据备份

备份命令 使用 pg_dump,对于 超过 100 GB 的数据库不适用。您必须选择具有原生、强大备份功能的 PostgreSQL 解决方案。

  1. 配置 AWS 备份以备份 RDS(和 S3)数据。为了最大程度的保护,同时配置连续备份和快照备份。
  2. 配置 AWS 备份以将备份复制到单独的区域。当 AWS 进行备份时,备份只能在存储备份的区域恢复。
  3. 在 AWS 备份至少运行一次计划备份后,您可以根据需要创建按需备份。

配置对象存储数据备份

建议使用 对象存储,(而不是 NFS)来存储极狐GitLab 数据,包括 blobs容器注册表

配置 AWS 备份以备份 S3 数据。这可以在配置 PostgreSQL 数据备份时同时完成。

配置 Git 存储库备份

设置 cronjobs 以执行 Gitaly 服务器端备份:

{{< tabs >}}

{{< tab title=”Linux package (Omnibus)” >}}

  1. 按照配置服务器端备份在所有 Gitaly 节点上配置 Gitaly 服务器端备份目标。 此存储桶仅由 Gitaly 用于存储存储库数据。
  2. 虽然 Gitaly 在其指定的对象存储桶中备份所有 Git 存储库数据, 备份工具(gitlab-backup)将额外的备份数据上传到单独的存储桶。此数据包括一个 tar 文件,其中包含恢复所需的重要元数据。 按照将备份上传到远程(云)存储确保此备份数据正确上传到远程(云)存储,以设置上传存储桶。
  3. (可选)为了巩固此备份数据的持久性,请使用各自的对象存储提供商备份以上配置的两个存储桶,将它们添加到对象存储数据备份中。
  4. SSH 进入一个极狐GitLab Rails 节点,即运行 Puma 或 Sidekiq 的节点。
  5. 进行 Git 数据的完整备份。使用 REPOSITORIES_SERVER_SIDE 变量,并跳过 PostgreSQL 数据:

    sudo gitlab-backup create REPOSITORIES_SERVER_SIDE=true SKIP=db
    

    这会导致 Gitaly 节点将 Git 数据和一些元数据上传到远程存储。上传、产物和 LFS 等 blobs 不需要显式跳过,因为 gitlab-backup 命令默认情况下不备份对象存储。

  6. 记录备份的 备份 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
  7. 检查完整备份是否在 Gitaly 备份存储桶和常规备份存储桶中创建了数据。
  8. 再次运行备份命令,这次指定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

  9. 检查增量备份是否成功,并添加数据到对象存储。
  10. 配置 cron 进行每日备份。编辑 root 用户的 crontab:

    sudo su -
    crontab -e
    
  11. 在那里,添加以下行以安排每天每月凌晨 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
    

{{< /tab >}}

{{< tab title=”Helm chart (Kubernetes)” >}}

  1. 按照配置服务器端备份在所有 Gitaly 节点上配置 Gitaly 服务器端备份目标。此存储桶仅由 Gitaly 用于存储存储库数据。
  2. 虽然 Gitaly 在其指定的对象存储桶中备份所有 Git 存储库数据, 备份工具(gitlab-backup)将额外的备份数据上传到单独的存储桶。此数据包括一个 tar 文件,其中包含恢复所需的重要元数据。 按照将备份上传到远程(云)存储确保此备份数据正确上传到远程(云)存储,以设置上传存储桶。
  3. (可选)为了巩固此备份数据的持久性,可以通过各自的对象存储提供商备份以上配置的两个存储桶,将它们添加到对象存储数据备份中。
  4. 按照配置对象存储数据备份确保备份两个存储桶。以上配置的两个存储桶也应由各自的对象存储提供商备份。
  5. SSH 进入一个极狐GitLab Rails 节点,即运行 Puma 或 Sidekiq 的节点。
  6. 进行 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 数据和一些元数据上传到远程存储。参见 Toolbox included tools

  7. 检查完整备份是否在 Gitaly 备份存储桶和常规备份存储桶中创建了数据。backup-utility 不支持服务器端存储库备份的增量存储库备份。
  8. 配置 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
    

{{< /tab >}}

{{< /tabs >}}

配置配置文件备份

如果您的配置和密钥文件定义在部署之外然后部署到其中,则备份策略的实施取决于您的具体设置和要求。作为示例,您可以使用 AWS Secret Manager 存储密钥,并复制到多个区域,并配置脚本自动备份密钥。

如果您的配置和密钥文件仅在部署内定义:

  1. 存储配置文件描述了如何提取配置和密钥文件。
  2. 这些文件应上传到单独的、更严格的对象存储帐户。

恢复备份

恢复极狐GitLab 实例的备份。

先决条件

在恢复备份之前:

  1. 选择一个正在工作的目标极狐GitLab 实例
  2. 确保目标极狐GitLab 实例位于存储 AWS 备份的区域。
  3. 检查目标极狐GitLab 实例使用与创建备份数据的极狐GitLab 完全相同版本和类型(CE 或 EE)。例如,CE 15.1.4。
  4. 将备份的密钥恢复到目标极狐GitLab 实例
  5. 确保目标极狐GitLab 实例配置了相同的存储库存储。额外的存储是可以的。
  6. 确保配置了对象存储
  7. 为使用新的密钥或配置,并避免在恢复期间处理任何意外的配置更改:

    • 所有节点上的 Linux 软件包安装:
      1. 重新配置目标极狐GitLab 实例。
      2. 重启目标极狐GitLab 实例。
    • Helm chart (Kubernetes) 安装:

      1. 在所有极狐GitLab Linux 软件包节点上运行:

        sudo gitlab-ctl reconfigure
        sudo gitlab-ctl start
        
      2. 确保您通过部署图表拥有正在运行的极狐GitLab 实例。 确保 Toolbox pod 启用并运行,执行以下命令:

        kubectl get pods -lrelease=RELEASE_NAME,app=toolbox
        
      3. Webservice、Sidekiq 和 Toolbox pod 必须重启。 重启这些 pod 的最安全方法是运行:

        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>
        
  8. 确认目标极狐GitLab 实例仍然有效。例如:

  9. 停止连接到 PostgreSQL 数据库的极狐GitLab 服务。

    • 所有运行 Puma 或 Sidekiq 的节点上的 Linux 软件包安装,运行:

      sudo gitlab-ctl stop
      
    • Helm chart (Kubernetes) 安装:

      1. 记录数据库客户端的当前副本数量,以便之后重启:

        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"}'
        
      2. 停止数据库客户端以防止锁干扰恢复过程:

        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
        

恢复对象存储数据

每个存储桶在 AWS 中存在为单独的备份,每个备份可以恢复到现有或新的存储桶。

  1. 要恢复存储桶,需要具有正确权限的 IAM 角色:

    • AWSBackupServiceRolePolicyForBackup
    • AWSBackupServiceRolePolicyForRestores
    • AWSBackupServiceRolePolicyForS3Restore
    • AWSBackupServiceRolePolicyForS3Backup
  2. 如果使用现有存储桶,则必须启用访问控制列表。
  3. 使用内置工具恢复 S3 存储桶。
  4. 您可以在恢复作业运行时继续恢复 PostgreSQL 数据

恢复 PostgreSQL 数据

  1. 使用内置工具恢复 AWS RDS 数据库,这会创建一个新的 RDS 实例。
  2. 由于新的 RDS 实例具有不同的端点,您必须重新配置目标极狐GitLab 实例以指向新的数据库:

  3. 在继续之前,等待新的 RDS 实例创建并可使用。

恢复 Git 存储库

首先,作为恢复对象存储数据的一部分,您应该已经:

  • 恢复了包含 Git 存储库的 Gitaly 服务器端备份的存储桶。
  • 恢复了包含 *_gitlab_backup.tar 文件的存储桶。

{{< tabs >}}

{{< tab title=”Linux package (Omnibus)” >}}

  1. SSH 进入一个极狐GitLab Rails 节点,即运行 Puma 或 Sidekiq 的节点。
  2. 在您的备份存储桶中,选择一个 *_gitlab_backup.tar 文件,根据其时间戳,与您恢复的 PostgreSQL 和对象存储数据保持一致。
  3. 下载 tar 文件到 /var/opt/gitlab/backups/
  4. 恢复备份,指定您希望恢复的备份 ID,省略 *_gitlab_backup.tar 中的名称:

    # 此命令将覆盖您的极狐GitLab 数据库内容!
    sudo gitlab-backup restore BACKUP=11493107454_2018_04_25_10.6.4-ce SKIP=db
    

    如果备份 tar 文件与安装的极狐GitLab 版本不匹配, 恢复命令将中止并显示错误消息。 安装正确的极狐GitLab 版本,然后重试。

  5. 重启并检查极狐GitLab:

    1. 在所有 Puma 或 Sidekiq 节点上运行:

      sudo gitlab-ctl restart
      
    2. 在一个 Puma 或 Sidekiq 节点上运行:

      sudo gitlab-rake gitlab:check SANITIZE=true
      
  6. 检查数据库值是否可以被解密,尤其是当 /etc/gitlab/gitlab-secrets.json 已恢复或目标为其他服务器时:

    在 Puma 或 Sidekiq 节点上运行:

    sudo gitlab-rake gitlab:doctor:secrets
    
  7. 为了增加保证,您可以对上传的文件执行完整性检查

    在 Puma 或 Sidekiq 节点上运行:

    sudo gitlab-rake gitlab:artifacts:check
    sudo gitlab-rake gitlab:lfs:check
    sudo gitlab-rake gitlab:uploads:check
    

    如果发现丢失或损坏的文件,并不总是表示备份和恢复过程失败。 例如,文件可能在源极狐GitLab 实例上丢失或损坏。您可能需要交叉引用以前的备份。 如果您正在将极狐GitLab 迁移到新环境,可以在源极狐GitLab 实例上运行相同检查,以确定完整性检查结果是预先存在的还是与备份和恢复过程相关。

{{< /tab >}}

{{< tab title=”Helm chart (Kubernetes)” >}}

  1. SSH 进入 toolbox pod。
  2. 在您的备份存储桶中,选择一个 *_gitlab_backup.tar 文件,根据其时间戳,与您恢复的 PostgreSQL 和对象存储数据保持一致。
  3. 下载 tar 文件到 /var/opt/gitlab/backups/
  4. 恢复备份,指定您希望恢复的备份 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 版本,然后重试。

  5. 重启并检查极狐GitLab:

    1. 启动已停止的部署,使用在先决条件中记录的副本数量:

      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>
      
    2. 在 Toolbox pod 中运行:

      sudo gitlab-rake gitlab:check SANITIZE=true
      
  6. 检查数据库值是否可以被解密,尤其是当 /etc/gitlab/gitlab-secrets.json 已恢复或目标为其他服务器时:

    在 Toolbox pod 中运行:

    sudo gitlab-rake gitlab:doctor:secrets
    
  7. 为了增加保证,您可以对上传的文件执行完整性检查

    这些命令可能需要很长时间,因为它们遍历所有行。因此,请在极狐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 实例上运行相同检查,以确定完整性检查结果是预先存在的还是与备份和恢复过程相关。

{{< /tab >}}

{{< /tabs >}}

恢复应已完成。