备份和恢复大型参考架构

本文档描述了如何:

本文档适用于以下环境:

配置每日备份

配置 PostgreSQL 数据的备份

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

::Tabs

:::TabTitle AWS

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

::EndTabs

配置对象存储数据的备份

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

::Tabs

:::TabTitle AWS

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

::EndTabs

配置 Git 仓库的备份

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

::Tabs

:::TabTitle Linux 软件包(Omnibus)

  1. 在所有 Gitaly 节点中配置服务端备份目标
  2. 配置上传备份到远程(云)存储。尽管 Gitaly 将所有 Git 数据备份到其自己的对象存储桶中,但 gitlab-backup 命令还会创建一个包含备份元数据的 tar 文件。恢复命令需要此 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
  1. 在其中,添加以下行以安排每个月每天凌晨 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

:::TabTitle Helm chart(Kubernetes)

  1. 在所有 Gitaly 节点中配置服务端备份目标
  2. 为备份实用工具配置对象存储桶。尽管 Gitaly 将所有 Git 数据备份到其自己的对象存储桶中,但 backup-utility 命令还会创建一个包含备份元数据的 tar 文件。恢复命令需要此 tar 文件。
  3. 确保将两个存储桶都添加到对象存储数据的备份中。
  4. 对 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 数据和一些元数据上传到远程存储。

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

::EndTabs

配置配置文件的备份

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

如果配置和密钥仅在部署内定义:

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

恢复备份

恢复极狐GitLab 实例的备份。

先决条件

在恢复备份之前:

  1. 选择一个正在工作的目标极狐GitLab 实例
  2. 确保目标极狐GitLab 实例位于存储 AWS 备份的区域。
  3. 检查目标极狐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 pods 必须重新启动。重新启动这些 pods 的最安全方法是运行:

        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
        

恢复对象存储数据

::Tabs

:::TabTitle AWS

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

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

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

::EndTabs

恢复 PostgreSQL 数据

::Tabs

:::TabTitle AWS

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

  3. 在继续之前,等待新的 RDS 实例创建完成并准备好使用。

::EndTabs

恢复 Git 仓库

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

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

::Tabs

:::TabTitle Linux 软件包(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 实例上运行相同的检查,以确定完整性检查结果是预先存在的还是与备份和恢复过程相关。

:::TabTitle 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 实例上运行相同的检查,以确定完整性检查结果是预先存在的还是与备份和恢复过程相关。

::EndTabs

恢复应该完成。