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 做准备:
-
选择 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 容器注册表 托管您的自定义构建镜像。 -
通过更新您的
config.toml文件,配置 GitLab Runner 实例使用所选镜像:[[runners]] (...) executor = "docker" [runners.docker] (...) helper_image = "image:tag" ## <-- 在此处放置镜像名称和标签有关更多详细信息,请参阅 helper image 信息。
-
重启 runner 以使新配置生效。
-
在您的
.gitlab-ci.yml文件中启用FF_USE_GIT_NATIVE_CLONEGitLab 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_ACCOUNT 和 AZURE_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:
gcloud auth application-default login命令。GOOGLE_APPLICATION_CREDENTIALS环境变量。对于自编译安装,在 GitLab 外部设置环境变量。
有关更多信息,请参阅 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_ID和AWS_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 还会跟踪它上次为仓库生成包的时间。当应该根据 threshold 和 interval 重新生成新包时,
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,请参阅您的存储服务文档。