Help us learn about your current experience with the documentation. Take the survey.

Bundle URIs

  • Tier: Free, Premium, Ultimate
  • Offering: GitLab Self-Managed

Gitaly 支持 Git bundle URIs。Bundle URIs 是 Git 可以下载一个或多个包来引导对象数据库,然后再从远程获取剩余对象的位置。Bundle URIs 内置于 Git 协议中。

使用 Bundle URIs 可以:

  • 加速网络连接不佳的用户克隆和获取操作。包可以存储在 CDN 上,使其在全球范围内可用。
  • 减少运行 CI/CD 作业的服务器负载。如果 CI/CD 作业可以从其他地方预加载包,增量获取缺失对象和引用的剩余工作会大大减少服务器负载。

先决条件

使用 bundle URI 的先决条件取决于是在 CI/CD 作业中克隆还是在本地终端中克隆。

在 CI/CD 作业中克隆

为在 CI/CD 作业中使用 bundle URI 做准备:

  1. 选择 GitLab Runner 使用的 GitLab Runner helper image 版本,该版本需运行:

    • Git 版本 2.49.0 或更高版本。
    • GitLab Runner helper 版本 18.0 或更高版本。

    此步骤是必需的,因为 bundle URI 是一种旨在减少 git clone 期间 Git 服务器负载的机制。因此,当 CI/CD 管道运行时,发起 git clone 命令的 git 客户端就是 GitLab Runner。git 进程在 helper image 中运行。

    确保选择与您用于 GitLab runner 的操作系统发行版和架构相对应的镜像。

    您可以通过运行以下命令验证镜像是否满足要求:

    docker run -it <image:tag>
    $ git version
    $ gitlab-runner-helper -v

    我们依赖操作系统发行版的包管理器来管理 gitlab-runner-helper 镜像中的 Git 版本。因此,一些最新的可用镜像可能仍然无法运行 Git 2.49。

    如果找不到满足要求的镜像,请使用 gitlab-runner-helper 作为您自定义构建镜像的基础镜像。您可以使用 GitLab 容器注册表 托管您的自定义构建镜像。

  2. 通过更新您的 config.toml 文件,配置 GitLab Runner 实例使用所选镜像:

    [[runners]]
      (...)
      executor = "docker"
      [runners.docker]
        (...)
        helper_image = "image:tag" ## <-- 在此处放置镜像名称和标签

    有关更多详细信息,请参阅 helper image 信息

  3. 重启 runner 以使新配置生效。

  4. 在您的 .gitlab-ci.yml 文件中启用 FF_USE_GIT_NATIVE_CLONE GitLab Runner 功能标志, 将其设置为 true

    variables:
      FF_USE_GIT_NATIVE_CLONE: "true"

在本地终端中克隆

为在本地终端中使用 bundle URI 进行克隆做准备,在本地 Git 配置中启用 bundle-uri

git config --global transfer.bundleuri true

服务器配置

您必须配置包的存储位置。Gitaly 支持以下 存储服务:

  • Google Cloud Storage
  • AWS S3(或兼容)
  • Azure Blob Storage
  • 本地文件存储(不推荐)

配置 Azure Blob 存储

如何为 Bundle URI 配置 Azure Blob 存储取决于您的安装类型。对于自编译安装,您必须在 GitLab 外部设置 AZURE_STORAGE_ACCOUNTAZURE_STORAGE_KEY 环境变量。

编辑 /etc/gitlab/gitlab.rb 并配置 bundle_uri.go_cloud_url

gitaly['env'] = {
    'AZURE_STORAGE_ACCOUNT' => 'azure_storage_account',
    'AZURE_STORAGE_KEY' => 'azure_storage_key' # 或 'AZURE_STORAGE_SAS_TOKEN'
}
gitaly['configuration'] = {
    bundle_uri: {
        go_cloud_url: 'azblob://<bucket>'
    }
}

编辑 /home/git/gitaly/config.toml 并配置 go_cloud_url

[bundle_uri]
go_cloud_url = "azblob://<bucket>"

配置 Google Cloud 存储

Google Cloud 存储 (GCP) 使用 Application Default Credentials 进行身份验证。 使用以下任一方法在每个 Gitaly 服务器上设置 Application Default Credentials:

有关更多信息,请参阅 Application Default Credentials

目标存储桶使用 go_cloud_url 选项配置。

编辑 /etc/gitlab/gitlab.rb 并配置 go_cloud_url

gitaly['env'] = {
    'GOOGLE_APPLICATION_CREDENTIALS' => '/path/to/service.json'
}
gitaly['configuration'] = {
    bundle_uri: {
        go_cloud_url: 'gs://<bucket>'
    }
}

编辑 /home/git/gitaly/config.toml 并配置 go_cloud_url

[bundle_uri]
go_cloud_url = "gs://<bucket>"

配置 S3 存储

配置 S3 存储身份验证:

  • 如果您使用 AWS CLI 进行身份验证,可以使用默认的 AWS 会话。
  • 否则,您可以使用 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY 环境变量。对于自编译安装,在 GitLab 外部设置环境变量。

有关更多信息,请参阅 AWS 会话文档

目标存储桶和区域使用 go_cloud_url 选项配置。

编辑 /etc/gitlab/gitlab.rb 并配置 go_cloud_url

gitaly['env'] = {
    'AWS_ACCESS_KEY_ID' => 'aws_access_key_id',
    'AWS_SECRET_ACCESS_KEY' => 'aws_secret_access_key'
}
gitaly['configuration'] = {
    bundle_uri: {
        go_cloud_url: 's3://<bucket>?region=us-west-1'
    }
}

编辑 /home/git/gitaly/config.toml 并配置 go_cloud_url

[bundle_uri]
go_cloud_url = "s3://<bucket>?region=us-west-1"

配置 S3 兼容服务器

MinIO 等 S3 兼容服务器的配置与 S3 类似,只是增加了 endpoint 参数。

支持以下参数:

  • region: AWS 区域。
  • endpoint: 端点 URL。
  • disableSSL: 设置为 true 以禁用 SSL。适用于 GitLab 17.4.0 及更早版本。对于 17.4.0 之后的 GitLab 版本,使用 disable_https
  • disable_https: 设置为 true 以在端点选项中禁用 HTTPS。
  • s3ForcePathStyle: 设置为 true 以强制使用路径样式的 S3 对象 URL。在 GitLab 17.4.0 到 17.4.3 版本中不可用。在这些版本中,使用 use_path_style 代替。
  • use_path_style: 设置为 true 以启用路径样式的 S3 URL(https://<host>/<bucket> 而不是 https://<bucket>.<host>)。
  • awssdk: 强制使用特定版本的 AWS SDK。设置为 v1 强制使用 AWS SDK v1,或设置为 v2 强制使用 AWS SDK v2。如果:
    • 设置为 v1,必须使用 disableSSL 而不是 disable_https
    • 未设置,默认为 v2

use_path_style 是在 Go Cloud Development Kit 依赖从 v0.38.0 更新到 v0.39.0 时引入的,这从 AWS SDK v1 切换到了 v2。然而,在 gocloud.dev 维护者添加向后兼容支持后,s3ForcePathStyle 参数在 GitLab 17.4.4 中被恢复。有关更多信息,请参阅 issue 6489

disable_https 在 Go Cloud Development Kit v0.40.0(AWS SDK v2)中引入。

awssdk 在 Go Cloud Development Kit v0.24.0 中引入。

编辑 /etc/gitlab/gitlab.rb 并配置 go_cloud_url

gitaly['env'] = {
    'AWS_ACCESS_KEY_ID' => 'minio_access_key_id',
    'AWS_SECRET_ACCESS_KEY' => 'minio_secret_access_key'
}
gitaly['configuration'] = {
    bundle_uri: {
        go_cloud_url: 's3://<bucket>?region=minio&endpoint=my.minio.local:8080&disable_https=true&use_path_style=true'
    }
}

编辑 /home/git/gitaly/config.toml 并配置 go_cloud_url

[bundle_uri]
go_cloud_url = "s3://<bucket>?region=minio&endpoint=my.minio.local:8080&disable_https=true&use_path_style=true"

生成包

配置 Gitaly 后,Gitaly 可以手动或自动生成包。

手动生成

此命令生成包并将其存储在配置的存储服务中。

sudo -u git -- /opt/gitlab/embedded/bin/gitaly bundle-uri \
                                               --config=<config-file> \
                                               --storage=<storage-name> \
                                               --repository=<relative-path>

Gitaly 不会自动刷新生成的包。当您想要生成更新的包版本时,必须再次运行该命令。

您可以使用 cron(8) 等工具来安排此命令。

自动生成

此功能的可用性由功能标志控制。 有关更多信息,请参阅历史记录。

Gitaly 可以通过确定是否正在为同一仓库处理频繁的克隆来自动生成包。 当前启发式算法跟踪每个仓库发出 git fetch 请求的次数。如果 请求数量在给定时间间隔内达到某个阈值,Gitaly 会自动生成一个包。

Gitaly 还会跟踪它上次为仓库生成包的时间。当应该根据 thresholdinterval 重新生成新包时, Gitaly 会查看上次为给定仓库生成包的时间。只有当现有包比 maxBundleAge 配置更旧时, Gitaly 才会生成新包,在这种情况下,旧包会被覆盖。云存储中每个仓库只能有一个包。

Bundle URI 示例

在以下示例中,我们演示了使用和不使用 bundle URI 克隆 gitlab.com/gitlab-org/gitlab.git 的区别。

$ git -c transfer.bundleURI=false clone https://gitlab.com/gitlab-org/gitlab.git
Cloning into 'gitlab'...
remote: Enumerating objects: 5271177, done.
remote: Total 5271177 (delta 0), reused 0 (delta 0), pack-reused 5271177
Receiving objects: 100% (5271177/5271177), 1.93 GiB | 32.93 MiB/s, done.
Resolving deltas: 100% (4140349/4140349), done.
Updating files: 100% (71304/71304), done.

$ git -c transfer.bundleURI=true clone https://gitlab.com/gitlab-org/gitlab.git
Cloning into 'gitlab'...
remote: Enumerating objects: 1322255, done.
remote: Counting objects: 100% (611708/611708), done.
remote: Total 1322255 (delta 611708), reused 611708 (delta 611708), pack-reused 710547
Receiving objects: 100% (1322255/1322255), 539.66 MiB | 22.98 MiB/s, done.
Resolving deltas: 100% (1026890/1026890), completed with 223946 local objects.
Checking objects: 100% (8388608/8388608), done.
Checking connectivity: 1381139, done.
Updating files: 100% (71304/71304), done.

在上述示例中:

  • 不使用 Bundle URI 时,从 GitLab 服务器接收了 5,271,177 个对象。
  • 使用 Bundle URI 时,从 GitLab 服务器接收了 1,322,255 个对象。

这种减少意味着 GitLab 需要打包更少的对象(在上述示例中,大约是对象数量的四分之一),因为客户端首先从存储服务器下载了包。

保护包

包使用签名 URL 对客户端可用。签名 URL 是一个提供有限权限和时间来发出请求的 URL。要查看您的存储服务是否支持签名 URL,请参阅您的存储服务文档。