备份和还原极狐GitLab 实例

极狐GitLab Helm chart 通过 Task Runner 子 chart 提供公用 pod,用作备份和还原实例的接口。该 pod 配备一个 backup-utility 可执行文件,可与其它必要使用的 pod 进行交互。有关技术细节,请查看 架构文档

前提条件

  • 本文描述的备份和还原过程仅使用 S3 兼容 API 测试过。对其它对象存储服务的支持,例如 Google Cloud Storage,将在未来的修订版中进行测试。

  • 在还原期间,备份的原始数据需要解压到磁盘。这意味着 Task Runner pod 应有必要可用大小的磁盘。

  • chart 依赖于利用对象存储,保存 artifactsuploadspackagesregistrylfs 对象,在还原期间不会迁移。如果您正在还原一个其它实例的备份,您必须在备份之前使用对象存储,迁移现有实例。

对象存储

使用 chart 时,我们提供了开箱即用的 MinIO 实例,除非指定了外部对象存储。Task Runner 默认连接到 MinIO,除非进行特别设置。Task Runner 也可以配置为备份到 Amazon S3 或 Google Cloud Storage (GCS)。

备份到 S3

Task Runner 使用 s3cmd 连接到对象存储。为了配置与外部对象存储的连接,应指定 gitlab.task-runner.backups.objectStorage.config.secret,指向包含 .s3cfg 文件的 Kubernetes Secret。当和 config 的默认值不同时,应当指定 gitlab.task-runner.backups.objectStorage.config.key,指向包含 .s3cfg 文件内容的键。

举例如下:

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

获取关于 s3cmd .s3cfg 文件的信息,请查看文档

此外,需要配置两个 bucket location,一个用于存储备份,另一个在还原备份时作为临时 bucket。

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

备份到 Google Cloud Storage (GCS)

要备份到 GCS,您必须设置 gitlab.task-runner.backups.objectStorage.backendgcs。这样确保 Task Runner 在存储和检索对象时使用 gsutil CLI。此外您必须将 gitlab.task-runner.backups.objectStorage.config.gcpProject 设置为 GCP 项目的 project ID,GCP 项目应包含您的存储桶。 您必须使用有效 service account JSON 密钥的内容创建 Kubernetes secret,service account 对用于备份的存储桶,应具有 storage.admin 角色。下面时使用 gcloudkubectl 创建 secret 的示例。

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,使用 service account 密钥对用于备份的 GCS 进行认证。

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

此外,需要配置两个 bucket location,一个用于存储备份,另一个在还原备份时作为临时 bucket。

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

备份和还原过程

故障排查

Pod 驱逐问题

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

--set gitlab.task-runner.persistence.enabled=true

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

--set gitlab.task-runner.backups.cron.persistence.enabled=true

对于其它云提供商,您可能需要创建持久卷。查看 存储文档,参考可能适用的案例。

“Bucket not found” 错误

如果在备份时发现 Bucket not found 错误,检查为您的存储桶配置的凭证。

使用的命令取决于云服务提供商:

  • 对于 AWS S3, 凭证存储在 task runner pod 的 ~/.s3cfg 中。执行以下命令:

    s3cmd ls
    
  • 对于 GCP GCS,执行以下命令:

    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 帐户可以访问(list、read 和 write)所有存储桶:

  1. 找到您的 task-runner pod:

    kubectl get pods -lrelease=RELEASE_NAME,app=task-runner
    
  2. 获取 pod 环境中的所有存储桶Get all buckets in the pod’s environment. 将 <task-runner-pod-name> 替换为实际的 task-runner pod 名称,但不要替换 "BUCKET_NAME",将其原地保留:

    kubectl describe pod <task-runner-pod-name> | grep "BUCKET_NAME"
    
  3. 确认您具有访问环境中的每个存储桶的权限:

    # List
    gsutil ls gs://<bucket-to-validate>/
    
    # Read
    gsutil cp gs://<bucket-to-validate>/<object-to-get> <save-to-location>
    
    # Write
    gsutil cp -n <local-file> gs://<bucket-to-validate>/