极狐GitLab 容器镜像仓库管理

  1. Tier: 基础版, 专业版, 旗舰版
  2. Offering: 私有化部署

现在,下一代容器镜像仓库已经在私有化部署上可用。升级的镜像仓库支持在线垃圾收集,而且有重大的性能和稳定性提升。

通过极狐GitLab 容器容器镜像仓库,每个项目都可以拥有自己的空间来存储 Docker 镜像。

有关分发容器镜像仓库的更多详细信息:

  1. Configuration
  2. Storage drivers
  3. Deploy a registry server

本文档是管理员指南。要了解如何使用极狐GitLab 容器容器镜像仓库,请参阅用户文档

启用容器容器镜像仓库#

启用容器容器镜像仓库的过程取决于您使用的安装类型。

Linux 软件包安装#

如果您使用 Linux 软件包安装了极狐GitLab ,则容器容器镜像仓库可能会默认可用或不可用。

如果您使用内置的 Let's Encrypt integration,容器容器镜像仓库会自动启用并在您的极狐GitLab 域名上端口 5050 可用。

否则,容器容器镜像仓库未启用。要启用它:

  1. 您可以为您的 极狐GitLab 域名 配置它,或者
  2. 您可以为 不同的域 配置它。

容器容器镜像仓库默认情况下在 HTTPS 下工作。您可以使用 HTTP,但不建议这样做,并且超出了本文档的范围。

Helm Charts 安装#

对于 Helm Charts 安装,请参阅 Helm Charts 文档中的使用容器容器镜像仓库

自编译安装#

如果您自行编译了极狐GitLab 安装:

  1. 您必须使用与您正在安装的极狐GitLab 版本对应的镜像部署容器镜像仓库 (例如:registry.gitlab.com/gitlab-org/build/cng/gitlab-container-registry:v3.15.0-gitlab
  2. 安装完成后,要启用它,您必须在 gitlab.yml 中配置容器镜像仓库的设置。
  3. 使用来自 lib/support/nginx/registry-ssl 的示例 NGINX 配置文件,并根据 主机端口 和 TLS 证书路径进行编辑。

gitlab.yml 的内容为:

yaml
1registry: 2 enabled: true 3 host: <registry.gitlab.example.com> 4 port: <5005> 5 api_url: <http://localhost:5000/> 6 key: <config/registry.key> 7 path: <shared/registry> 8 issuer: <gitlab-issuer>

其中:

参数描述
enabledtruefalse。启用极狐GitLab 中的容器镜像仓库。默认情况下这是 false
host容器镜像仓库运行的主机 URL,用户可以使用。
port外部容器镜像仓库域名监听的端口。
api_url容器镜像仓库公开的内部 API URL。默认为 http://localhost:5000。除非您设置了外部 Docker 容器镜像仓库,否则不要更改此项。
key是容器镜像仓库的 rootcertbundle 的一对的私钥位置。
path应该是容器镜像仓库的 rootdirectory 中指定的相同目录。此路径需要极狐GitLab 用户、web 服务器用户和容器镜像仓库用户可读。
issuer应该与容器镜像仓库中配置的 issuer 值相同。

如果您从源代码安装极狐GitLab,则不会随极狐GitLab 一起提供容器镜像仓库初始化文件。 因此,重新启动极狐GitLab 不会重新启动容器镜像仓库,应您修改其设置。 请阅读上游文档以了解如何实现。

至少确保您的容器镜像仓库配置 将 container_registry 设置为服务并将 https://gitlab.example.com/jwt/auth 设置为领域:

yaml
1auth: 2 token: 3 realm: <https://gitlab.example.com/jwt/auth> 4 service: container_registry 5 issuer: gitlab-issuer 6 rootcertbundle: /root/certs/certbundle

如果未设置 auth,用户可以在不进行身份验证的情况下拉取 Docker 镜像。

容器容器镜像仓库域配置#

您可以通过以下任意一种方式配置容器镜像仓库的外部域:

  1. 使用现有的极狐GitLab 域名。容器镜像仓库在端口上监听,并重用极狐GitLab 的 TLS 证书。
  2. 使用完全独立的域,为该域提供新的 TLS 证书。

由于容器容器镜像仓库需要 TLS 证书,成本可能是一个因素。

在首次配置容器容器镜像仓库之前请考虑这一点。

在现有极狐GitLab 域名下配置容器容器镜像仓库#

如果容器容器镜像仓库配置为使用现有极狐GitLab 域名,您可以通过端口公开容器容器镜像仓库。 这样您就可以重用现有的极狐GitLab TLS 证书。

如果极狐GitLab 域名是 https://gitlab.example.com 并且对外端口是 5050,要配置容器容器镜像仓库:

  1. 如果您使用的是 Linux 软件包安装,请编辑 gitlab.rb
  2. 如果您使用的是自编译安装,请编辑 gitlab.yml

确保选择与容器镜像仓库监听的端口(默认为 5000)不同的端口,否则会发生冲突。

主机和容器防火墙规则必须配置为允许流量通过 registry_external_url 行下列出的端口进入,而不是 gitlab_rails['registry_port'](默认为 5000)下列出的端口。

  1. 您的 /etc/gitlab/gitlab.rb 应包含容器镜像仓库 URL 以及极狐GitLab 使用的现有 TLS 证书和密钥路径:

    ruby
    registry_external_url '<https://gitlab.example.com:5050>'

    registry_external_url 在现有极狐GitLab URL 下监听 HTTPS,但在不同的端口上。

    如果您的 TLS 证书不在 /etc/gitlab/ssl/gitlab.example.com.crt 中,密钥不在 /etc/gitlab/ssl/gitlab.example.com.key 中,请取消注释以下行:

    ruby
    registry_nginx['ssl_certificate'] = "</path/to/certificate.pem>" registry_nginx['ssl_certificate_key'] = "</path/to/certificate.key>"
  2. 保存文件并重新配置极狐GitLab以使更改生效。

  3. 使用以下命令验证:

    shell
    openssl s_client -showcerts -servername gitlab.example.com -connect gitlab.example.com:5050 > cacert.pem

如果您的证书提供商提供 CA Bundle 证书,请将它们附加到 TLS 证书文件中。

管理员可能希望容器容器镜像仓库监听诸如 5678 的任意端口。 然而,容器镜像仓库和应用程序服务器位于仅监听 80443 端口的 AWS 应用程序负载均衡器之后。 管理员可以删除 registry_external_url 的端口号,因此假定 HTTP 或 HTTPS。然后,规则适用于将负载均衡器从 80443 端口映射到容器镜像仓库的任意端口。 如果用户依赖于容器容器镜像仓库中的 docker login 示例,这一点很重要。以下是一个示例:

ruby
registry_external_url '<https://registry-gitlab.example.com>' registry_nginx['redirect_http_to_https'] = true registry_nginx['listen_port'] = 5678

用户现在应该能够使用他们的极狐GitLab 凭据登录容器容器镜像仓库:

shell
docker login <gitlab.example.com:5050>

在自己的域下配置容器容器镜像仓库#

当容器镜像仓库配置为使用自己的域时,您需要为该特定域(例如,registry.example.com)提供 TLS 证书。 如果托管在现有极狐GitLab 域的子域下,您可能需要通配符证书。 例如,*.gitlab.example.com 是一个通配符,匹配 registry.gitlab.example.com,与 *.example.com 不同。

除了手动生成的 SSL 证书(此处解释),自动生成的证书由 Let's Encrypt 也支持 Linux 软件包安装

假设您希望容器容器镜像仓库可在 https://registry.gitlab.example.com 上访问。

  1. 将您的 TLS 证书和密钥放置在 /etc/gitlab/ssl/<registry.gitlab.example.com>.crt/etc/gitlab/ssl/<registry.gitlab.example.com>.key 中,并确保它们具有正确的权限:

    shell
    chmod 600 /etc/gitlab/ssl/<registry.gitlab.example.com>.*
  2. TLS 证书到位后,请编辑 /etc/gitlab/gitlab.rb

    ruby
    registry_external_url '<https://registry.gitlab.example.com>'

    registry_external_url 在 HTTPS 上监听。

  3. 保存文件并重新配置极狐GitLab以使更改生效。

如果您有通配符证书,除了 URL,您还必须指定证书的路径,在这种情况下 /etc/gitlab/gitlab.rb 如下所示:

ruby
registry_nginx['ssl_certificate'] = "/etc/gitlab/ssl/certificate.pem" registry_nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/certificate.key"

用户现在应该能够使用他们的极狐GitLab 凭据登录容器容器镜像仓库:

shell
docker login <registry.gitlab.example.com>

在全站范围内禁用容器容器镜像仓库#

通过执行这些步骤禁用容器镜像仓库时,不会删除任何现有 Docker 镜像。 Docker 镜像删除由容器镜像仓库应用程序本身处理。

  1. 打开 /etc/gitlab/gitlab.rb 并将 registry['enable'] 设置为 false

    ruby
    registry['enable'] = false
  2. 保存文件并重新配置极狐GitLab以使更改生效。

为新项目在全站范围内禁用容器容器镜像仓库#

如果启用了容器容器镜像仓库,则它应该在所有新项目上可用。 要禁用此功能并让项目所有者自行启用容器容器镜像仓库,请按照以下步骤操作。

  1. 编辑 /etc/gitlab/gitlab.rb 并添加以下行:

    ruby
    gitlab_rails['gitlab_default_projects_features_container_registry'] = false
  2. 保存文件并重新配置极狐GitLab以使更改生效。

增加令牌持续时间#

在极狐GitLab 中,容器容器镜像仓库的令牌每五分钟过期。 要增加令牌持续时间:

  1. 在左侧边栏底部,选择 管理员
  2. 选择 设置 > CI/CD
  3. 展开 容器容器镜像仓库
  4. 对于 授权令牌持续时间(分钟),更新值。
  5. 选择 保存更改

配置容器容器镜像仓库的存储#

对于支持的存储后端,您可以使用对象版本控制来保存、检索和恢复存储在存储桶中的每个对象的非当前版本。 然而,这可能导致更高的存储使用和成本。由于容器镜像仓库的操作方式,镜像上传首先存储在临时路径中,然后转移到最终位置。 对于对象存储后端,包括 S3 和 GCS,这种转移是通过复制然后删除来实现的。启用对象版本控制后,这些已删除的临时上传产物将作为非当前版本保留,从而增加存储桶大小。为了确保非当前版本在给定时间后被删除,您应该使用存储提供商配置对象生命周期策略。

请勿直接修改容器容器镜像仓库存储的文件或对象。 除了容器镜像仓库写入或删除这些条目之外的任何操作都可能导致实例范围的数据一致性和稳定性问题,从而无法恢复。

您可以通过配置存储驱动程序为容器容器镜像仓库配置各种存储后端。 默认情况下,极狐GitLab 容器容器镜像仓库配置为使用文件系统驱动程序配置。

支持的不同驱动程序为:

驱动程序描述
filesystem使用本地文件系统上的路径
azureMicrosoft Azure Blob Storage
gcsGoogle Cloud Storage
s3Amazon Simple Storage Service。请确保使用正确的 S3 权限范围配置您的存储桶。

虽然大多数 S3 兼容服务(如 MinIO)应该可以与容器容器镜像仓库一起使用,但我们仅保证支持 AWS S3。因为我们无法断言第三方 S3 实现的正确性,我们可以调试问题,但无法修补容器镜像仓库,除非问题可以在 AWS S3 存储桶上重现。

使用文件系统#

如果您希望将镜像存储在文件系统上,可以更改容器容器镜像仓库的存储路径,请按照以下步骤操作。

此路径可以被以下用户访问:

  • 运行容器容器镜像仓库守护程序的用户。
  • 运行极狐GitLab 的用户。

所有极狐GitLab、容器镜像仓库和 web 服务器用户必须能够访问此目录。

在 Linux 软件包安装中存储镜像的默认位置是 /var/opt/gitlab/gitlab-rails/shared/registry。要更改它:

  1. 编辑 /etc/gitlab/gitlab.rb

    ruby
    gitlab_rails['registry_path'] = "</path/to/registry/storage>"
  2. 保存文件并重新配置极狐GitLab以使更改生效。

使用对象存储#

如果您希望将容器容器镜像仓库镜像存储在对象存储中而不是本地文件系统中,您可以配置其中一个支持的存储驱动程序。

有关更多信息,请参阅对象存储

极狐GitLab 不备份未存储在文件系统上的 Docker 镜像。如果需要,请与您的对象存储提供商启用备份。

为 Linux 软件包安装配置对象存储#

要为您的容器容器镜像仓库配置对象存储:

  1. 选择您要使用的存储驱动程序。
  2. 使用适当的配置编辑 /etc/gitlab/gitlab.rb
  3. 保存文件并重新配置极狐GitLab以使更改生效。

S3 存储驱动程序与 Amazon S3 或任何 S3 兼容的对象存储服务集成。

ruby
1# Deprecated: Will be removed in GitLab 19.0 2registry['storage'] = { 3 's3' => { 4 'accesskey' => '<s3-access-key>', 5 'secretkey' => '<s3-secret-key-for-access-key>', 6 'bucket' => '<your-s3-bucket>', 7 'region' => '<your-s3-region>', 8 'regionendpoint' => '<your-s3-regionendpoint>' 9 } 10} 11 12# Beta: s3_v2 driver 13registry['storage'] = { 14 's3_v2' => { 15 'accesskey' => '<s3-access-key>', 16 'secretkey' => '<s3-secret-key-for-access-key>', 17 'bucket' => '<your-s3-bucket>', 18 'region' => '<your-s3-region>', 19 'regionendpoint' => '<your-s3-regionendpoint>' 20 } 21}

Beta 版的 s3_v2 驱动程序使用 AWS SDK v2,并仅支持用于身份验证的签名版本 4。此驱动程序改善了性能和可靠性,同时确保与 AWS 身份验证要求兼容,因为它们正在逐步淘汰对较旧签名方法的支持。

为了提高安全性,您可以通过省略 accesskeysecretkey 参数来使用 IAM 角色而不是静态凭证。

对于 S3 VPC 端点:

ruby
1registry['storage'] = { 2 's3_v2' => { # Beta driver 3 'accesskey' => '<s3-access-key>', 4 'secretkey' => '<s3-secret-key-for-access-key>', 5 'bucket' => '<your-s3-bucket>', 6 'region' => '<your-s3-region>', 7 'regionendpoint' => '<your-s3-vpc-endpoint>', 8 'pathstyle' => false 9 } 10}
  • regionendpoint 仅在配置 S3 兼容服务(如 MinIO)或使用 AWS S3 VPC 端点时需要。
  • <your-s3-bucket> 应为已存在的存储桶名称,不能包含子目录。
  • pathstyle 应设置为 true 以使用主机/存储桶名称/对象样式路径,而不是存储桶名称.主机/对象。对于 AWS S3,设置为 false

您可以设置连接到 S3 的速率限制,以避免来自 S3 API 的 503 错误:

ruby
1registry['storage'] = { 2 's3' => { 3 'accesskey' => '<s3-access-key>', 4 'secretkey' => '<s3-secret-key-for-access-key>', 5 'bucket' => '<your-s3-bucket>', 6 'region' => '<your-s3-region>', 7 'regionendpoint' => '<your-s3-regionendpoint>', 8 'maxrequestspersecond' => 100 9 } 10}

自编译安装#

存储驱动程序的配置在您部署 Docker 容器镜像仓库时创建的容器镜像仓库配置 YAML 文件中进行。

s3 存储驱动程序示例:

yaml
1storage: 2 s3: 3 accesskey: '<s3-access-key>' # Not needed if IAM role used 4 secretkey: '<s3-secret-key-for-access-key>' # Not needed if IAM role used 5 bucket: '<your-s3-bucket>' 6 region: '<your-s3-region>' 7 regionendpoint: '<your-s3-regionendpoint>' 8 cache: 9 blobdescriptor: inmemory 10 delete: 11 enabled: true

<your-s3-bucket> 应为已存在的存储桶名称,不能包含子目录。

无停机迁移到对象存储#

使用 AWS DataSync 将容器镜像仓库数据复制到或在 S3 存储桶之间复制,会在存储桶中创建无效的元数据对象。有关详细信息,请参阅标签为空的名称。要将数据移动到和在 S3 存储桶之间移动,建议使用 AWS CLI sync 操作。

要在不停止容器容器镜像仓库的情况下迁移存储,请将容器容器镜像仓库设置为只读模式。在大型实例上,这可能需要容器容器镜像仓库长时间处于只读模式。在此期间,您可以从容器容器镜像仓库中拉取,但不能推送。

  1. 可选:要减少迁移的数据量,请运行无停机垃圾收集工具

  2. 此示例使用 aws CLI。如果您之前没有配置 CLI,则必须通过运行 sudo aws configure 配置您的凭证。由于非管理员用户可能无法访问容器容器镜像仓库文件夹,请确保使用 sudo。要检查您的凭证配置,请运行 ls 列出所有存储桶。

    shell
    sudo aws --endpoint-url <https://your-object-storage-backend.com> s3 ls

    如果您使用 AWS 作为后端,则不需要 --endpoint-url

  3. 使用 aws CLI 的 cpsync 命令将初始数据复制到您的 S3 存储桶中。确保将 docker 文件夹保留为存储桶内的顶级文件夹。

    shell
    sudo aws --endpoint-url <https://your-object-storage-backend.com> s3 sync registry s3://mybucket

如果您有大量数据,您可以通过运行并行同步操作来提高性能。

  1. 要执行最终数据同步,将容器容器镜像仓库置于 read-only 模式重新配置极狐GitLab

  2. 将自初始数据加载以来的任何更改同步到您的 S3 存储桶,并删除目标存储桶中存在但在源中不存在的文件:

    shell
    sudo aws --endpoint-url <https://your-object-storage-backend.com> s3 sync registry s3://mybucket --delete --dryrun

    在验证命令执行符合预期后,移除 --dryrun 标志并运行命令。

--delete标志会删除目标中存在但源中不存在的文件。如果交换源和目标,则容器镜像仓库中的所有数据都将被删除。

  1. 通过查看这两个命令返回的文件计数来验证所有容器容器镜像仓库文件已上传到对象存储:

    shell
    sudo find registry -type f | wc -l
    shell
    sudo aws --endpoint-url <https://your-object-storage-backend.com> s3 ls s3://<mybucket> --recursive | wc -l

    这些命令的输出应匹配,除了 _uploads 目录和子目录中的内容。

  2. 配置您的容器镜像仓库以使用 S3 存储桶存储

  3. 为了使更改生效,将容器镜像仓库设置回 read-write 模式并重新配置极狐GitLab

移动到 Azure 对象存储#

ruby
1registry['storage'] = { 2 'azure' => { 3 'accountname' => '<your_storage_account_name>', 4 'accountkey' => '<base64_encoded_account_key>', 5 'container' => '<container_name>', 6 'trimlegacyrootprefix' => true 7 } 8}

默认情况下,Azure 存储驱动程序使用 core.windows.net 领域。您可以在 azure 部分中为领域设置其他值(例如,Azure 政府云的 core.usgovcloudapi.net)。

禁用存储驱动程序的重定向#

默认情况下,访问配置有远程后端的容器镜像仓库的用户会被重定向到存储驱动程序的默认后端。例如,容器镜像仓库可以使用 s3 存储驱动程序进行配置,重定向请求到远程 S3 存储桶,以减轻极狐GitLab 服务器的负载。

然而,对于通常无法访问公共服务器的内部主机使用的容器镜像仓库,这种行为是不理想的。要禁用重定向和代理下载,请将 disable 标志设置为 true,如下所示。这使得所有流量始终通过容器镜像仓库服务进行。 这提高了安全性(攻击面更小,因为存储后端不是公开可访问的),但性能较差(所有流量都通过服务重定向)。

  1. 编辑 /etc/gitlab/gitlab.rb

    ruby
    1registry['storage'] = { 2 's3' => { 3 'accesskey' => '<s3_access_key>', 4 'secretkey' => '<s3_secret_key_for_access_key>', 5 'bucket' => '<your_s3_bucket>', 6 'region' => '<your_s3_region>', 7 'regionendpoint' => '<your_s3_regionendpoint>' 8 }, 9 'redirect' => { 10 'disable' => true 11 } 12}
  2. 保存文件并重新配置极狐GitLab以使更改生效。

加密的 S3 存储桶#

您可以使用 AWS KMS 的服务器端加密来加密 S3 存储桶,这些存储桶默认启用了 SSE-S3 或 SSE-KMS 加密。由于这需要在每次请求中发送加密密钥,因此不支持客户主密钥(CMKs)和 SSE-C 加密。

对于 SSE-S3,您必须在容器镜像仓库设置中启用 encrypt 选项。如何操作取决于您如何安装极狐GitLab。请按照此处与您的安装方法匹配的说明进行操作。

  1. 编辑 /etc/gitlab/gitlab.rb

    ruby
    1registry['storage'] = { 2 's3' => { 3 'accesskey' => '<s3_access_key>', 4 'secretkey' => '<s3_secret_key_for_access_key>', 5 'bucket' => '<your_s3_bucket>', 6 'region' => '<your_s3_region>', 7 'regionendpoint' => '<your_s3_regionendpoint>', 8 'encrypt' => true 9 } 10}
  2. 保存文件并重新配置极狐GitLab以使更改生效。

存储限制#

没有存储限制,这意味着用户可以上传无限量的任意大小的 Docker 镜像。 此设置在未来版本中应可配置。

更改容器镜像仓库的内部端口#

容器镜像仓库服务器默认监听 localhost 的端口 5000,这是容器镜像仓库服务器应该接受连接的地址。 在以下示例中,我们将容器镜像仓库的端口设置为 5010

  1. 打开 /etc/gitlab/gitlab.rb 并设置 registry['registry_http_addr']

    ruby
    registry['registry_http_addr'] = "localhost:5010"
  2. 保存文件并重新配置极狐GitLab以使更改生效。

每个项目禁用容器容器镜像仓库#

如果您的极狐GitLab 实例中启用了容器镜像仓库,但您不需要它用于您的项目,您可以从项目设置中禁用它

使用极狐GitLab 作为身份验证端点的外部容器容器镜像仓库#

如果您使用外部容器容器镜像仓库,则与容器容器镜像仓库相关的一些功能可能不可用或具有固有风险

为了使集成正常工作,外部容器镜像仓库必须配置为使用 JSON Web Token 与极狐GitLab 进行身份验证。外部容器镜像仓库的运行时配置 必须具有以下条目:

yaml
1auth: 2 token: 3 realm: https://<gitlab.example.com>/jwt/auth 4 service: container_registry 5 issuer: gitlab-issuer 6 rootcertbundle: /root/certs/certbundle

没有这些条目,容器镜像仓库登录无法与极狐GitLab 进行身份验证。极狐GitLab 也无法识别项目层次结构下的嵌套镜像名称,例如 registry.example.com/group/project/image-name:tagregistry.example.com/group/project/my/image-name:tag,仅识别 registry.example.com/group/project:tag

Linux 软件包安装#

您可以使用极狐GitLab 作为身份验证端点与外部容器容器镜像仓库。

  1. 打开 /etc/gitlab/gitlab.rb 并设置必要的配置:

    ruby
    gitlab_rails['registry_enabled'] = true gitlab_rails['registry_api_url'] = "https://<external_registry_host>:5000" gitlab_rails['registry_issuer'] = "gitlab-issuer"
    • gitlab_rails['registry_enabled'] = true 用于启用极狐GitLab 容器容器镜像仓库功能和身份验证端点。即使启用,极狐GitLab 捆绑的容器容器镜像仓库服务也不会启动。
    • gitlab_rails['registry_api_url'] = "http://<external_registry_host>:5000" 必须更改为匹配容器镜像仓库安装的主机。如果外部容器镜像仓库配置为使用 TLS,则必须指定 https
  2. 极狐GitLab 和外部容器容器镜像仓库之间需要一个证书密钥对,以便安全地通信。您需要创建一个证书密钥对,使用公钥证书(rootcertbundle)配置外部容器容器镜像仓库,并使用私钥配置极狐GitLab。为此,请在 /etc/gitlab/gitlab.rb 中添加以下内容:

    ruby
    1# registry['internal_key'] 应包含自定义密钥文件的内容。 2# 密钥文件中的换行符应使用 `\n` 字符标记 3# 示例: 4registry['internal_key'] = "---BEGIN RSA PRIVATE KEY---\nMIIEpQIBAA\n" 5 6# 可选地为 Linux 软件包安装定义一个自定义文件,将 registry['internal_key'] 的内容写入其中。 7gitlab_rails['registry_key_path'] = "/custom/path/to/registry-key.key"

    每次执行重新配置时,指定在 registry_key_path 的文件会填充 registry['internal_key'] 指定的内容。如果未指定文件,则 Linux 软件包安装会将其默认为 /var/opt/gitlab/gitlab-rails/etc/gitlab-registry.key 并填充它。

  3. 要更改极狐GitLab 容器容器镜像仓库页面中显示的容器容器镜像仓库 URL,请设置以下配置:

    ruby
    gitlab_rails['registry_host'] = "<registry.gitlab.example.com>" gitlab_rails['registry_port'] = "5005"
  4. 保存文件并重新配置极狐GitLab以使更改生效。

自编译安装#

  1. 打开 /home/git/gitlab/config/gitlab.yml,并编辑 registry 下的配置设置:

    yaml
    1## Container registry 2 3registry: 4 enabled: true 5 host: "<registry.gitlab.example.com>" 6 port: "5005" 7 api_url: "https://<external_registry_host>:5000" 8 path: /var/lib/registry 9 key: </path/to/keyfile> 10 issuer: gitlab-issuer

    阅读更多关于这些参数的含义。

  2. 保存文件并重新启动极狐GitLab以使更改生效。

配置容器容器镜像仓库通知#

您可以配置容器容器镜像仓库以在容器镜像仓库中发生事件时发送 webhook 通知。

threshold 参数的支持在极狐GitLab 17.0 中已弃用,计划在 18.0 中删除。请改用 maxretries

您可以为容器容器镜像仓库配置多个端点。

要为 Linux 软件包安装配置通知端点:

  1. 编辑 /etc/gitlab/gitlab.rb

    ruby
    1registry['notifications'] = [ 2 { 3 'name' => '<test_endpoint>', 4 'url' => 'https://<gitlab.example.com>/api/v4/container_registry_event/events', 5 'timeout' => '500ms', 6 'threshold' => 5, # DEPRECATED: use `maxretries` instead. 7 'maxretries' => 5, 8 'backoff' => '1s', 9 'headers' => { 10 "Authorization" => ["<AUTHORIZATION_EXAMPLE_TOKEN>"] 11 } 12 } 13] 14 15gitlab_rails['registry_notification_secret'] = '<AUTHORIZATION_EXAMPLE_TOKEN>' # 必须与 registry['notifications'] 中的身份验证令牌匹配

替换 <AUTHORIZATION_EXAMPLE_TOKEN> 为一个区分大小写的字母数字字符串,以字母开头。你可以使用以下命令生成一个: < /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c 32 | sed "s/^[0-9]*//"; echo

  1. 保存文件并重新配置极狐GitLab以使更改生效。

运行清理策略#

前提条件:

在您创建清理策略后,可以立即运行它以减少容器容器镜像仓库存储空间。您不必等待计划的清理。

为了减少给定项目使用的容器容器镜像仓库磁盘空间,管理员可以:

  1. 通过项目检查磁盘空间使用情况,以识别需要清理的项目。
  2. 使用极狐GitLab Rails 控制台运行清理策略以移除镜像标签。
  3. 运行垃圾收集,以移除未引用的层和未标记的清单。

项目容器镜像仓库磁盘空间使用情况#

要查找每个项目使用的磁盘空间,请在极狐GitLab Rails 控制台中运行以下命令:

ruby
1projects_and_size = [["project_id", "creator_id", "registry_size_bytes", "project path"]] 2# 您需要指定要查看的项目。您可以通过任何方式获取这些项目。 3projects = Project.last(100) 4 5registry_metadata_database = ContainerRegistry::GitlabApiClient.supports_gitlab_api? 6 7if registry_metadata_database 8 projects.each do |project| 9 size = project.container_repositories_size 10 if size > 0 11 projects_and_size << [project.project_id, project.creator&.id, size, project.full_path] 12 end 13 end 14else 15 projects.each do |project| 16 project_layers = {} 17 18 project.container_repositories.each do |repository| 19 repository.tags.each do |tag| 20 tag.layers.each do |layer| 21 project_layers[layer.digest] ||= layer.size 22 end 23 end 24 end 25 26 total_size = project_layers.values.compact.sum 27 if total_size > 0 28 projects_and_size << [project.project_id, project.creator&.id, total_size, project.full_path] 29 end 30 end 31end 32 33# 打印为逗号分隔的输出 34projects_and_size.each do |ps| 35 puts "%s,%s,%s,%s" % ps 36end

该脚本根据容器镜像层计算大小。因为层可以在多个项目之间共享,所以结果是近似的,但可以很好地指示项目之间的相对磁盘使用情况。

要通过运行清理策略移除镜像标签,请在极狐GitLab Rails 控制台中运行以下命令:

ruby
1# 要清理其容器容器镜像仓库的项目的数字 ID 2P = <project_id> 3 4# 具有开发人员、维护者或所有者角色的用户的数字 ID 5U = <user_id> 6 7# 获取所需的详细信息/对象 8user = User.find_by_id(U) 9project = Project.find_by_id(P) 10policy = ContainerExpirationPolicy.find_by(project_id: P) 11 12# 遍历每个容器容器镜像仓库 13project.container_repositories.find_each do |repo| 14 puts repo.attributes 15 16 # 开始标签清理 17 puts Projects::ContainerRepository::CleanupTagsService.new(container_repository: repo, current_user: user, params: policy.attributes.except("created_at", "updated_at")).execute 18end

您还可以按计划运行清理

要在实例范围内为所有项目启用清理策略,您需要找到所有启用容器容器镜像仓库但禁用清理策略的项目:

ruby
1# 查找所有启用容器容器镜像仓库但禁用清理策略的项目 2 3projects = Project.find_by_sql ("SELECT * FROM projects WHERE id IN (SELECT project_id FROM container_expiration_policies WHERE enabled=false AND id IN (SELECT project_id FROM container_repositories))") 4 5# 遍历每个项目 6projects.each do |p| 7 8# 打印项目 ID 和项目全名 9 puts "#{p.id},#{p.full_name}" 10end

容器容器镜像仓库元数据数据库#

  • 级别:基础版、专业版、旗舰版
  • 提供:极狐GitLab私有化部署
History
    • 极狐GitLab 17.3 中 GA。

元数据数据库启用了许多新的容器镜像仓库功能,包括在线垃圾收集,并提高了许多容器镜像仓库操作的效率。详见容器容器镜像仓库元数据数据库页面。

容器容器镜像仓库垃圾收集#

对象存储提供者(如 Amazon S3 生命周期)中的保留策略可能会阻止对象被正确删除。

容器容器镜像仓库可能会使用大量存储空间,您可能希望减少存储使用。在列出的选项中,删除标签是最有效的选项。但是,标签删除不会删除镜像层,只会留下未标记的镜像清单。

为了更有效地释放空间,容器容器镜像仓库有一个垃圾收集器,可以删除未引用的层和(可选的)未标记的清单。

要启动垃圾收集器,请使用 gitlab-ctl 提供的 registry-garbage-collect 命令。

此命令在垃圾收集之前关闭容器容器镜像仓库,并且只有在垃圾收集完成后才重新启动它。如果您希望避免停机,可以手动将容器容器镜像仓库设置为只读模式并绕过 gitlab-ctl

执行垃圾收集所需的时间与容器容器镜像仓库数据大小成正比。

前提条件:

理解内容可寻址层#

考虑以下示例,其中您首先构建镜像:

shell
# 这会构建一个内容为 sha256:<111111...> 的镜像 docker build -t <my.registry.com>/<my.group>/<my.project>:latest . docker push <my.registry.com>/<my.group>/<my.project>:latest

现在,您使用新版本覆盖 latest

shell
# 这会构建一个内容为 sha256:<222222...> 的镜像 docker build -t <my.registry.com>/<my.group>/<my.project>:latest . docker push <my.registry.com>/<my.group>/<my.project>:latest

现在,latest 标签指向 sha256:<222222...> 的清单。由于容器镜像仓库的架构,当拉取镜像 <my.registry.com>/<my.group>/<my.project>@sha256:<111111...> 时,仍然可以访问此数据,尽管它不再直接通过 latest 标签访问。

移除未引用的层#

镜像层是容器容器镜像仓库存储的主要部分。当没有镜像清单引用它时,层被认为是未引用的。未引用的层是容器容器镜像仓库垃圾收集器的默认目标。

如果您没有更改配置文件的默认位置,请运行:

shell
sudo gitlab-ctl registry-garbage-collect

如果您更改了容器容器镜像仓库 config.yml 的位置:

shell
sudo gitlab-ctl registry-garbage-collect /path/to/config.yml

您还可以移除所有未标记的清单和未引用的层,以恢复额外的空间。

移除未标记的清单和未引用的层#

默认情况下,容器容器镜像仓库垃圾收集器忽略未标记的镜像,用户可以通过摘要继续拉取未标记的镜像。用户还可以在未来重新标记镜像,使其在极狐GitLab UI 和 API 中再次可见。

如果您不关心未标记的镜像及这些镜像唯一引用的层,您可以删除它们。使用 registry-garbage-collect 命令上的 -m 标志:

shell
sudo gitlab-ctl registry-garbage-collect -m

如果您不确定是否要删除未标记的镜像,请在继续之前备份您的容器镜像仓库数据。

无停机进行垃圾收集#

为了在保持容器容器镜像仓库在线的同时进行垃圾收集,请将容器镜像仓库设置为只读模式并绕过内置的 gitlab-ctl registry-garbage-collect 命令。

在容器容器镜像仓库处于只读模式时,您可以拉取但不能推送镜像。容器容器镜像仓库必须在垃圾收集的整个过程中保持只读状态。

默认情况下,容器镜像仓库存储路径/var/opt/gitlab/gitlab-rails/shared/registry

要启用只读模式:

  1. /etc/gitlab/gitlab.rb 中指定只读模式:

    ruby
    1registry['storage'] = { 2 'filesystem' => { 3 'rootdirectory' => "<your_registry_storage_path>" 4 }, 5 'maintenance' => { 6 'readonly' => { 7 'enabled' => true 8 } 9 } 10}
  2. 保存并重新配置极狐GitLab:

    shell
    sudo gitlab-ctl reconfigure

    此命令将容器容器镜像仓库设置为只读模式。

  3. 接下来,触发其中一个垃圾收集命令:

    shell
    # 移除未引用的层 sudo /opt/gitlab/embedded/bin/registry garbage-collect /var/opt/gitlab/registry/config.yml # 移除未标记的清单和未引用的层 sudo /opt/gitlab/embedded/bin/registry garbage-collect -m /var/opt/gitlab/registry/config.yml

    此命令启动垃圾收集。完成所需的时间与容器镜像仓库数据大小成正比。

  4. 完成后,在 /etc/gitlab/gitlab.rb 中将其改回读写模式:

    ruby
    1registry['storage'] = { 2 'filesystem' => { 3 'rootdirectory' => "<your_registry_storage_path>" 4 }, 5 'maintenance' => { 6 'readonly' => { 7 'enabled' => false 8 } 9 } 10}
  5. 保存并重新配置极狐GitLab:

    shell
    sudo gitlab-ctl reconfigure

按计划运行垃圾收集#

理想情况下,您希望在每周定期运行容器镜像仓库垃圾收集,并在容器镜像仓库未使用时进行。最简单的方法是添加一个新的 crontab 作业,使其每周运行一次。

/etc/cron.d/registry-garbage-collect 下创建一个文件:

shell
SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # 每周日凌晨 04:05 运行 5 4 * * 0 root gitlab-ctl registry-garbage-collect

您可能希望添加 -m 标志以移除未标记的清单和未引用的层

停止垃圾收集#

如果您预计会停止垃圾收集,应该手动运行垃圾收集,如无停机进行垃圾收集所述。然后,您可以按 Control+C 停止垃圾收集。

否则,中断 gitlab-ctl 可能会使您的容器镜像仓库服务处于停机状态。在这种情况下,您必须在系统上找到垃圾收集过程本身,以便 gitlab-ctl 命令可以将容器镜像仓库服务重新启动。

此外,在过程的标记阶段期间没有办法保存进度或结果。只有在开始删除 blob 后才会做任何永久性操作。

连续零停机垃圾收集#

如果您迁移到元数据数据库,可以在后台运行垃圾收集,而无需安排或需要只读模式。

按组件扩展#

本节概述了随着容器镜像仓库流量增加可能出现的性能瓶颈。每个子节大致按照从较小到较大的容器镜像仓库工作负载受益的建议进行排序。容器镜像仓库未包含在参考架构中,也没有针对座位数或每秒请求数的扩展指南。

数据库#

  1. 迁移到单独的数据库:随着数据库负载增加,通过将容器镜像仓库元数据库迁移到单独的物理数据库来垂直扩展。单独的数据库可以增加可用于容器镜像仓库数据库的资源,同时隔离容器镜像仓库产生的流量。
  2. 迁移到 HA PostgreSQL 第三方解决方案:类似于 Praefect,迁移到信誉良好的提供商或解决方案可以启用 HA,并适用于多节点容器镜像仓库部署。您必须选择支持原生 Postgres 分区、触发器和函数的提供商,因为容器镜像仓库大量使用这些功能。

容器镜像仓库服务器#

  1. 迁移到单独的节点:一个单独的节点是垂直扩展以增加可用于容器容器镜像仓库服务器进程的资源的一种方法。
  2. 在负载均衡器后面运行多个容器镜像仓库节点:虽然容器镜像仓库可以通过单个大型节点处理大量流量,但容器镜像仓库通常旨在通过多次部署水平扩展。配置多个较小的节点还可以启用自动扩展等技术。

Redis 缓存#

启用 Redis 缓存可以提高性能,还可以启用诸如重命名存储库等功能。

  1. Redis 服务器:支持单个 Redis 实例,这是访问 Redis 缓存优势的最简单方法。
  2. Redis Sentinel:Redis Sentinel 也受到支持,使缓存可以 HA。
  3. Redis 集群:Redis 集群也可以用于随着部署的增长进一步扩展。

存储#

  1. 本地文件系统:本地文件系统是默认的,相对性能较好,但不适用于多节点部署或大量容器镜像仓库数据。
  2. 对象存储使用对象存储以启用实际存储大量容器镜像仓库数据。对象存储也适用于多节点容器镜像仓库部署。

在线垃圾收集#

  1. 调整默认值:如果在线垃圾收集没有可靠地清理审查队列,可以在 gc 配置部分中的 manifestsblobs 部分下调整 interval 设置。默认值为 5s,这些也可以配置为毫秒,例如 500ms
  2. 通过容器镜像仓库服务器水平扩展:如果您正在通过多节点部署水平扩展容器镜像仓库应用程序,在线垃圾收集会自动扩展,无需进行配置更改。

在不同节点上配置极狐GitLab 和容器镜像仓库(Linux 软件包安装)#

默认情况下,极狐GitLab 软件包假设两个服务在同一节点上运行。在不同节点上运行它们需要单独的配置。

配置选项#

以下配置选项应在各个节点上的 /etc/gitlab/gitlab.rb 中设置。

容器镜像仓库节点设置#

选项描述
registry['registry_http_addr']容器镜像仓库监听的网络地址和端口。必须能够被 Web 服务器或负载均衡器访问。默认:程序设置
registry['token_realm']身份验证端点 URL,通常为极狐GitLab 实例 URL。必须能够被用户访问。默认:程序设置
registry['http_secret']用于保护客户端篡改的安全令牌。生成为随机字符串
registry['internal_key']令牌签名密钥,创建于容器镜像仓库服务器,但由极狐GitLab 使用。默认:自动生成
registry['internal_certificate']用于令牌签名的证书。默认:自动生成
registry['rootcertbundle']存储 internal_certificate 的文件路径。默认:程序设置
registry['health_storagedriver_enabled']启用存储驱动程序的健康监测。默认:程序设置
gitlab_rails['registry_key_path']存储 internal_key 的文件路径。默认:程序设置
gitlab_rails['registry_issuer']令牌发行者名称。必须在容器镜像仓库和极狐GitLab 配置之间匹配。默认:程序设置

在极狐GitLab 17.8 中,使用 Amazon S3 签名版本 2 在容器容器镜像仓库中进行身份验证的支持已被弃用,计划在 18.0 中移除。请改用签名版本 4。这是一个重大更改。

极狐GitLab 节点设置#

选项描述
gitlab_rails['registry_enabled']启用极狐GitLab 容器镜像仓库 API 集成。必须设置为 true
gitlab_rails['registry_api_url']极狐GitLab 使用的内部容器镜像仓库 URL(用户不可见)。使用 registry['registry_http_addr'] 和方案。默认:程序设置
gitlab_rails['registry_host']公共容器镜像仓库主机名,无需方案(例如:registry.gitlab.example)。此地址向用户显示。
gitlab_rails['registry_port']显示给用户的公共容器镜像仓库端口号。
gitlab_rails['registry_issuer']必须与容器镜像仓库配置匹配的令牌发行者名称。
gitlab_rails['registry_key_path']容器镜像仓库使用的证书密钥的文件路径。
gitlab_rails['internal_key']极狐GitLab 使用的令牌签名密钥内容。

设置节点#

要在不同节点上配置极狐GitLab 和容器容器镜像仓库:

  1. 在容器镜像仓库节点上,编辑 /etc/gitlab/gitlab.rb,使用以下设置:

    ruby
    1# 容器镜像仓库服务器详细信息 2# - IP 地址:10.30.227.194 3# - 域:registry.example.com 4 5# 禁用不需要的服务 6gitlab_workhorse['enable'] = false 7puma['enable'] = false 8sidekiq['enable'] = false 9postgresql['enable'] = false 10redis['enable'] = false 11gitlab_kas['enable'] = false 12gitaly['enable'] = false 13nginx['enable'] = false 14 15# 配置容器镜像仓库设置 16registry['enable'] = true 17registry['registry_http_addr'] = '0.0.0.0:5000' 18registry['token_realm'] = 'https://<gitlab.example.com>' 19registry['http_secret'] = '<6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b>' 20 21# 配置极狐GitLab Rails 设置 22gitlab_rails['registry_issuer'] = 'omnibus-gitlab-issuer' 23gitlab_rails['registry_key_path'] = '/etc/gitlab/gitlab-registry.key'
  2. 在极狐GitLab 节点上,编辑 /etc/gitlab/gitlab.rb,使用以下设置:

    ruby
    1# 极狐GitLab 服务器详细信息 2# - IP 地址:10.30.227.149 3# - 域:gitlab.example.com 4 5# 配置极狐GitLab URL 6external_url 'https://<gitlab.example.com>' 7 8# 配置容器镜像仓库设置 9gitlab_rails['registry_enabled'] = true 10gitlab_rails['registry_api_url'] = '<http://10.30.227.194:5000>' 11gitlab_rails['registry_host'] = '<registry.example.com>' 12gitlab_rails['registry_port'] = 5000 13gitlab_rails['registry_issuer'] = 'omnibus-gitlab-issuer' 14gitlab_rails['registry_key_path'] = '/etc/gitlab/gitlab-registry.key'
  3. 在两个节点之间同步 /etc/gitlab/gitlab-secrets.json 文件:

    1. 将文件从极狐GitLab 节点复制到容器镜像仓库节点。
    2. 确保文件权限正确。
    3. 在两个节点上运行 sudo gitlab-ctl reconfigure

极狐GitLab 容器容器镜像仓库的架构#

极狐GitLab 容器镜像仓库是用户用来存储自己 Docker 镜像的地方。因此,容器镜像仓库是客户端面向的,这意味着我们直接在 Web 服务器(或负载均衡器,简称 LB)上公开它。

Rendering chart...

上图描述的流程:

  1. 用户在客户端上运行 docker login registry.gitlab.example。这会到达 Web 服务器(或 LB)的端口 443。
  2. Web 服务器连接到容器镜像仓库后端池(默认情况下,使用端口 5000)。由于用户没有提供有效的令牌,容器镜像仓库返回 401 HTTP 代码以及获取令牌的 URL(容器镜像仓库配置中的 token_realm)。这指向极狐GitLab API。
  3. Docker 客户端然后连接到极狐GitLab API 并获取令牌。
  4. API 用容器镜像仓库密钥签署令牌并交给 Docker 客户端。
  5. Docker 客户端现在使用从 API 接收到的令牌再次登录。它现在可以推送和拉取 Docker 镜像。

极狐GitLab 和容器镜像仓库之间的通信#

容器镜像仓库没有内部认证用户的方式,因此它依赖极狐GitLab 验证凭证。容器镜像仓库和极狐GitLab 之间的连接是通过 TLS 加密的。密钥用于极狐GitLab 签署令牌,而证书用于容器镜像仓库验证签名。默认情况下,为所有安装生成自签名证书密钥对。可以根据需要覆盖此设置。

极狐GitLab 使用容器镜像仓库私钥与容器镜像仓库进行交互。当容器镜像仓库请求发出时,会生成一个新的短期(10 分钟)命名空间限制令牌,并使用私钥进行签署。 然后,容器镜像仓库验证签名是否与其配置中指定的容器镜像仓库证书匹配并允许操作。 极狐GitLab 后台作业处理(通过 Sidekiq)也与容器镜像仓库进行交互。 这些作业直接与容器镜像仓库对话以处理镜像删除。

从第三方容器镜像仓库迁移#

在极狐GitLab 15.8 中,使用外部容器容器镜像仓库在极狐GitLab 中已弃用,并在极狐GitLab 16.0 中结束支持。有关更多详细信息,请参阅弃用通知

在极狐GitLab 16.0 中集成未被禁用,但不再提供调试和修复问题的支持。此外,集成不再开发或增强新功能。在新的极狐GitLab 容器容器镜像仓库版本可用于极狐GitLab私有化部署后,第三方容器镜像仓库功能可能会被完全移除。计划仅支持极狐GitLab 容器容器镜像仓库。

本节为从第三方容器镜像仓库迁移到极狐GitLab 容器容器镜像仓库的管理员提供指导。

对于下面提供的所有说明,您应该首先在测试环境中尝试它们。确保一切继续按预期工作,然后在生产中复制。

Docker 分发容器镜像仓库#

Docker 分发容器镜像仓库已捐赠给 CNCF,现在称为分发容器镜像仓库。此容器镜像仓库是极狐GitLab 容器容器镜像仓库的开源实现。极狐GitLab 容器容器镜像仓库与分发容器镜像仓库提供的基本功能兼容,包括所有支持的存储后端。要迁移到极狐GitLab 容器容器镜像仓库,您可以按照本页面上的说明进行操作,并使用与分发容器镜像仓库相同的存储后端。极狐GitLab 容器容器镜像仓库应该接受您为分发容器镜像仓库使用的相同配置。

删除容器镜像的最大重试次数#

History
    • 在极狐GitLab 17.5 中引入,使用名为 set_delete_failed_container_repository 的功能标志。默认禁用。
    • 在极狐GitLab 17.6 中 GA。功能标志 set_delete_failed_container_repository 被移除。

删除容器镜像时可能会发生错误,因此会重试删除以确保错误不是暂时性问题。删除最多重试 10 次,每次重试之间有退避延迟。此延迟为任何暂时性错误解决提供更多时间。

设置最大重试次数还有助于检测在重试之间未解决的任何持久性错误。在删除失败达到最大重试次数后,容器存储库的 status 设置为 delete_failed。有了这种状态,存储库不再重试删除。

您应该调查任何具有 delete_failed 状态的容器存储库并尝试解决问题。解决问题后,您可以将存储库状态设置回 delete_scheduled,以便镜像可以重新开始删除。要更新存储库状态,请从 rails 控制台:

ruby
container_repository = ContainerRepository.find(<id>) container_repository.update(status: 'delete_scheduled')