极狐 GitLab

备份和恢复极狐GitLab 实例

Tier: 基础版,专业版,旗舰版

Offering: 私有化部署

GitLab Helm chart 提供了一个来自 Toolbox 子 chart 的实用工具 Pod,作为备份和恢复极狐GitLab 实例的接口。它配备了 backup-utility 可执行文件,该文件与此任务所需的其他 Pod 进行交互。 有关该实用工具工作原理的技术细节,请参阅架构文档

前提条件#

  • 此处描述的备份和恢复流程仅针对兼容 S3 的 API 进行了测试。对其他对象存储服务(如 Google Cloud Storage)的支持将在未来版本中进行测试。
  • 在恢复期间,备份压缩包需要解压到磁盘。这意味着 Toolbox Pod 应具有所需大小的磁盘空间
  • 此 chart 依赖对象存储来存储 artifactsuploadspackagesregistrylfs 对象,并且目前不会在恢复期间为您迁移这些对象。如果您要恢复从其他实例获取的备份,则必须在进行备份之前将现有实例迁移到使用对象存储。请参阅议题 646

备份和恢复流程#

备份到 S3#

默认情况下,Toolbox 使用 s3cmd 连接到对象存储,除非您指定使用其他 s3 工具。为了配置与外部对象存储的连接,应指定 gitlab.toolbox.backups.objectStorage.config.secret,它指向包含 .s3cfg 文件的 Kubernetes 密钥。如果与默认的 config 不同,则应指定 gitlab.toolbox.backups.objectStorage.config.key。这指向包含 .s3cfg 文件内容的键。

它应该如下所示:

shell
helm install gitlab gitlab/gitlab \ --set gitlab.toolbox.backups.objectStorage.config.secret=my-s3cfg \ --set gitlab.toolbox.backups.objectStorage.config.key=config .

此外,需要配置两个存储桶位置,一个用于存储备份,另一个临时存储桶用于恢复备份时使用。

shell
--set global.appConfig.backups.bucket=gitlab-backup-storage --set global.appConfig.backups.tmpBucket=gitlab-tmp-storage

备份到 Google Cloud Storage (GCS)#

要备份到 GCS,您必须首先将 gitlab.toolbox.backups.objectStorage.backend 设置为 gcs。这确保 Toolbox 在存储和检索对象时使用 gsutil CLI。

此外,需要配置两个存储桶位置,一个用于存储备份,另一个临时存储桶用于恢复备份时使用。

shell
--set global.appConfig.backups.bucket=gitlab-backup-storage --set global.appConfig.backups.tmpBucket=gitlab-tmp-storage

备份实用工具需要访问这些存储桶。有两种授予访问权限的方式:

GCS 凭据#

首先,将 gitlab.toolbox.backups.objectStorage.config.gcpProject 设置为包含您的存储桶的 GCP 项目的项目 ID。

您必须创建一个 Kubernetes 密钥,其中包含有效服务账号 JSON 密钥的内容,该服务账号对您将用于备份的存储桶具有 storage.admin 角色。以下是使用 gcloudkubectl 创建密钥的示例。

shell
export PROJECT_ID=$(gcloud config get-value project) gcloud iam service-accounts create gitlab-gcs --display-name "Gitlab Cloud Storage" gcloud projects add-iam-policy-binding --role roles/storage.admin ${PROJECT_ID} --member=serviceAccount:gitlab-gcs@${PROJECT_ID}.iam.gserviceaccount.com gcloud iam service-accounts keys create --iam-account gitlab-gcs@${PROJECT_ID}.iam.gserviceaccount.com storage.config kubectl create secret generic storage-config --from-file=config=storage.config

按如下方式配置您的 Helm chart,以使用服务账号密钥向 GCS 进行备份身份验证:

shell
helm install gitlab gitlab/gitlab \ --set gitlab.toolbox.backups.objectStorage.config.secret=storage-config \ --set gitlab.toolbox.backups.objectStorage.config.key=config \ --set gitlab.toolbox.backups.objectStorage.config.gcpProject=my-gcp-project-id \ --set gitlab.toolbox.backups.objectStorage.backend=gcs

为 GKE 配置工作负载身份联合#

请参阅使用 GitLab chart 为 GKE 配置工作负载身份联合的文档

在创建引用 Kubernetes ServiceAccount 的 IAM 允许策略时,授予 roles/storage.objectAdmin 角色。

对于备份,请确保未设置 gitlab.toolbox.backups.objectStorage.config.secretgitlab.toolbox.backups.objectStorage.config.keygitlab.toolbox.backups.objectStorage.config.gcpProject,以确保使用 Google 的应用默认凭据。

备份到 Azure blob 存储#

可以通过将 gitlab.toolbox.backups.objectStorage.backend 设置为 azure 来使用 Azure blob 存储保存备份。这使 Toolbox 能够使用附带的 azcopy 副本将备份文件传输到 Azure blob 存储以及从中检索。

要使用 Azure blob 存储,需要在现有资源组中创建存储账户。使用您的存储账户名称、访问密钥和 blob 主机创建一个配置密钥。

创建一个包含以下参数的配置文件:

yaml
# azure-backup-conf.yaml azure_storage_account_name: <storage account> azure_storage_access_key: <access key value> azure_storage_domain: blob.core.windows.net # optional

以下 kubectl 命令可用于创建 Kubernetes 密钥:

shell
kubectl create secret generic backup-azure-creds \ --from-file=config=azure-backup-conf.yaml

创建密钥后,可以通过将备份设置添加到已部署的 values 中或在 Helm 命令行上提供设置来配置 GitLab Helm chart。例如:

shell
helm install gitlab gitlab/gitlab \ --set gitlab.toolbox.backups.objectStorage.config.secret=backup-azure-creds \ --set gitlab.toolbox.backups.objectStorage.config.key=config \ --set gitlab.toolbox.backups.objectStorage.backend=azure

密钥中的访问密钥用于生成和刷新较短期的共享访问签名 (SAS) 令牌,以访问存储账户。

此外,需要预先创建两个存储桶/容器,一个用于存储备份,另一个临时存储桶用于恢复备份时使用。将存储桶名称添加到您的 values 或设置中。例如:

shell
--set global.appConfig.backups.bucket=gitlab-backup-storage --set global.appConfig.backups.tmpBucket=gitlab-tmp-storage

镜像仓库元数据数据库#

如果您已启用容器镜像仓库元数据数据库,则可以配置 Toolbox 在备份和恢复操作期间访问镜像仓库数据库。这需要在 Toolbox chart values 中设置镜像仓库数据库凭据。有关配置详细信息,请参阅 Toolbox chart 文档中的镜像仓库元数据数据库凭据部分。

故障排查#

Pod 驱逐问题#

由于备份在对象存储目标之外本地组装,因此需要临时磁盘空间。所需空间可能超过实际备份存档的大小。默认配置将使用 Toolbox Pod 的文件系统来存储临时数据。如果您发现 Pod 因资源不足而被驱逐,则应为 Pod 附加一个持久卷来保存临时数据。 在 GKE 上,将以下设置添加到您的 Helm 命令中:

shell
--set gitlab.toolbox.persistence.enabled=true

如果您的备份作为附带的备份 cron 作业的一部分运行,那么您还需要为 cron 作业启用持久性:

shell
--set gitlab.toolbox.backups.cron.persistence.enabled=true

对于其他提供商,您可能需要创建持久卷。有关如何执行此操作的示例,请参阅我们的存储文档

“Bucket not found”错误#

如果在备份期间看到 Bucket not found 错误,请检查是否为您的存储桶配置了凭据。

该命令取决于云服务提供商:

  • 对于 AWS S3,凭据存储在 toolbox Pod 的 ~/.s3cfg 中。运行:

    shell
    s3cmd ls
  • 对于 GCP GCS,运行:

    shell
    gsutil ls

您应该会看到可用存储桶的列表。

GCP 中的 “AccessDeniedException: 403” 错误#

类似 [Error] AccessDeniedException: 403 <GCP Account> does not have storage.objects.list access to the Google Cloud Storage bucket. 的错误通常会在备份或恢复极狐GitLab 实例期间发生,原因是权限缺失。

备份和恢复操作使用环境中的所有存储桶,因此请确认环境中的所有存储桶都已创建,并且 GCP 账户可以访问(列出、读取和写入)所有存储桶:

  1. 找到您的 toolbox Pod:

    shell
    kubectl get pods -lrelease=RELEASE_NAME,app=toolbox
  2. 获取 Pod 环境中的所有存储桶。将 <toolbox-pod-name> 替换为您的实际 toolbox Pod 名称,但保持 "BUCKET_NAME" 不变:

    shell
    kubectl describe pod <toolbox-pod-name> | grep "BUCKET_NAME"
  3. 确认您可以访问环境中的每个存储桶:

    shell
    1# List 2gsutil ls gs://<bucket-to-validate>/ 3 4# Read 5gsutil cp gs://<bucket-to-validate>/<object-to-get> <save-to-location> 6 7# Write 8gsutil cp -n <local-file> gs://<bucket-to-validate>/

使用 --backend s3 运行 backup-utility 时出现 “ERROR: /home/git/.s3cfg: None” 错误#

当未通过 gitlab.toolbox.backups.objectStorage.config.secret 值指定包含 .s3cfg 文件的 Kubernetes 密钥时,会发生此错误。

要解决此问题,请按照备份到 S3 中的说明进行操作。

如果您使用 ServiceAccount 的 IAM 角色 (IRSA) 进行身份验证,并且不使用静态 AWS 凭据,则无需创建 .s3cfg 文件。通过向 backup-utility 传递 --s3tool awscli 来使用 awscli 而不是默认的 s3cmd。有关更多信息,请参阅为服务账户使用 IAM 角色 (IRSA)

使用 S3 时出现 “PermissionError: File not writable” 错误#

如果 toolbox 用户没有权限写入与存储桶中对象所存储的权限匹配的文件,则会发生类似 [Error] WARNING: <file> not writable: Operation not permitted 的错误。

为防止这种情况,请配置 s3cmd 不保留文件所有者、模式和时间戳,方法是将以下标志添加到您的 .s3cfg 文件中(通过 gitlab.toolbox.backups.objectStorage.config.secret 引用)。

toml
preserve_attrs = False

恢复时跳过代码仓库#

从极狐GitLab 16.6/Chart 7.6 开始,如果备份存档已重命名,则恢复时可能会跳过代码仓库。为避免这种情况,请不要重命名备份存档,并将备份重命名为其原始名称 ({backup_id}_gitlab_backup.tar)。

可以从代码仓库备份目录结构中提取原始备份 ID:repositories/@hashed/*/*/*/{backup_id}/LATEST

错误:cannot drop view pg_stat_statements because extension pg_stat_statements requires it#

在 Helm chart 实例上恢复备份时,您可能会遇到此错误。请使用以下步骤作为变通方法:

  1. 在您的 toolbox Pod 内打开数据库控制台:

    shell
    /srv/gitlab/bin/rails dbconsole -p
  2. 删除扩展:

    shell
    DROP EXTENSION pg_stat_statements;
  3. 执行恢复过程。

  4. 恢复完成后,在数据库控制台中重新创建扩展:

    shell
    CREATE EXTENSION pg_stat_statements;

如果您遇到 pg_buffercache 扩展的相同问题,请按照上述相同步骤删除并重新创建它。

您可以在议题 #2469 中找到有关此错误的更多详细信息。

Toolbox 备份上传失败#

尝试上传到对象存储时,备份可能会失败,并出现类似错误:

plaintext
An error occurred (XAmzContentSHA256Mismatch) when calling the UploadPart operation: The Content-SHA256 you specified did not match what we received

这可能是由 awscli 工具与您的对象存储服务不兼容引起的。使用 Dell ECS S3 存储时已报告此问题。

为避免此问题,您可以禁用数据完整性保护

错误:无法识别的配置参数 “transaction_timeout”#

GitLab chart 部署了一个用于备份和恢复等任务的 toolbox,它目前附带 PostgreSQL 17 客户端库。

客户端库向后兼容,因此如果您运行的是 PostgreSQL 16,备份和恢复仍然可以工作,但您可能会看到此错误:

plaintext
ERROR: unrecognized configuration parameter "transaction_timeout"

发生这种情况是因为 pg_dump 向后兼容,但不保证恢复在不同服务器版本之间无缝工作。

有关更多详细信息,请参阅 pg_dump 文档

备份工具会询问您是否要忽略此错误,在这种情况下忽略是安全的。