辅助站点的容器镜像仓库
Tier: 专业版,旗舰版
Offering: 私有化部署
你可以在 辅助 Geo 站点上设置一个容器镜像仓库,用于从 主 Geo 站点的容器镜像仓库复制镜像。此容器镜像复制仅用于灾难恢复目的。
不要向 辅助 Geo 站点的容器镜像仓库推送镜像,因为数据不会传播到 主 站点。
我们不建议从 辅助 站点拉取容器镜像仓库数据,因为数据可能过期。
支持的容器镜像仓库
Geo 支持以下类型的容器镜像仓库:
支持的镜像格式
Geo 支持以下容器镜像格式:
此外,Geo 还支持 BuildKit 缓存镜像。
支持的存储
Docker
有关支持的镜像仓库存储驱动,请参阅 Docker 镜像仓库存储驱动
在部署镜像仓库时,请阅读 负载均衡注意事项 ,以及如何为极狐GitLab 集成的 容器镜像仓库 配置存储驱动。
支持 OCI 制品的镜像仓库
以下镜像仓库支持 OCI 制品:
- CNCF Distribution - 本地/离线验证
- Azure Container Registry (ACR)
- Amazon Elastic Container Registry (ECR)
- Google Artifact Registry (GAR)
- GitHub Packages container registry (GHCR)
- Bundle Bar
更多信息,请参阅 OCI 分发规范。
配置容器镜像仓库复制
你可以启用与存储无关的复制,以便可用于云或本地存储。每当新镜像推送到 主 站点时,每个 辅助 站点都会将其拉取到自己的容器 仓库。
要配置容器镜像仓库复制:
配置主站点
在继续执行以下步骤之前,请确保你已在 主 站点上设置容器镜像仓库并使其正常工作。
为了能够复制新的容器镜像,容器镜像仓库必须在每次推送时向 主 站点发送通知事件。容器镜像仓库与 主 站点上的 Web 节点之间共享的令牌用于使通信更加安全。
-
SSH 到你的极狐GitLab 主 服务器并以 root 身份登录(对于极狐GitLab HA,你只需要一个 Registry 节点):
shellsudo -i -
编辑 /etc/gitlab/gitlab.rb:
ruby1# Configure the registry to listen on the public/internal interface 2# Replace with the appropriate interface (for example, '0.0.0.0' for all interfaces) 3registry['registry_http_addr'] = '0.0.0.0:5000' 4registry['notifications'] = [ 5 { 6 'name' => 'geo_event', 7 'url' => 'https://<example.com>/api/v4/container_registry_event/events', 8 'timeout' => '500ms', 9 'threshold' => 5, 10 'backoff' => '1s', 11 'headers' => { 12 'Authorization' => ['<replace_with_a_secret_token>'] 13 } 14 } 15]将 <example.com> 替换为主站点 /etc/gitlab/gitlab.rb 文件中定义的 external_url,并将 <replace_with_a_secret_token> 替换为一个区分大小写的字母数字字符串, 该字符串以字母开头。你可以使用 /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c 32 | sed "s/^[0-9]*//"; echo 生成一个。
如果你使用外部镜像仓库(非极狐GitLab 集成的),则只需在/etc/gitlab/gitlab.rb 文件中指定通知密钥(registry['notification_secret'])。
-
仅限极狐GitLab HA。在每个 Web 节点上编辑 /etc/gitlab/gitlab.rb:
rubyregistry['notification_secret'] = '<replace_with_a_secret_token_generated_above>' -
重新配置你刚刚更新的每个节点:
shellgitlab-ctl reconfigure
配置辅助站点
在继续执行以下步骤之前,请确保你已在 辅助 站点上设置容器镜像仓库并使其正常工作。
以下步骤应在你希望看到容器镜像被复制的每个 辅助 站点上执行。
因为我们需要允许 辅助 站点与 主 站点容器镜像仓库安全通信,所以我们需要为所有站点提供一个单一密钥 对。辅助 站点使用此密钥 生成一个短期的、仅有拉取权限的 JWT,以访问 主 站点容器镜像仓库。
对于 辅助 站点上的每个应用程序和 Sidekiq 节点:
-
SSH 到节点并以 root 用户身份登录:
shellsudo -i -
将 /var/opt/gitlab/gitlab-rails/etc/gitlab-registry.key 从 主 站点复制到节点。
-
编辑 /etc/gitlab/gitlab.rb 并添加:
rubygitlab_rails['geo_registry_replication_enabled'] = true # Primary registry's hostname and port, it will be used by # the secondary node to directly communicate to primary registry gitlab_rails['geo_registry_replication_primary_api_url'] = 'https://primary.example.com:5050/' -
重新配置节点以使更改生效:
shellgitlab-ctl reconfigure
验证复制
要验证容器镜像仓库复制是否正常工作,在 辅助 站点上:
- 在右上角,选择 管理员。
- 在左侧边栏中,选择 Geo > 节点。 初始复制(或称为“回填”)可能仍在进行中。
你可以在浏览器中从 主 站点的 Geo 节点 仪表板监控每个 Geo 站点的同步过程。
故障排查
确认容器镜像仓库复制已启用
可以在 Rails 控制台 中使用以下命令进行检查:
rubyGeo::ContainerRepositoryRegistry.replication_enabled?
缺少容器镜像仓库通知事件
- 当镜像被推送到主站点的容器镜像仓库时,应该触发一个 容器镜像仓库通知
- 主站点的容器镜像仓库调用主站点的 API,地址为 https://<example.com>/api/v4/container_registry_event/events
- 主站点向 geo_events 表插入一条记录,其中包含 replicable_name: 'container_repository', model_record_id: <容器镜像仓库的 ID>。
- 该记录通过 PostgreSQL 复制到辅助站点的数据库。
- Geo 日志游标服务处理该新事件,并将一个 Sidekiq 作业 Geo::EventWorker 加入队列。
要验证此操作是否正确,请将镜像推送到主站点上的镜像仓库,并在 Rails 控制台中运行以下命令以验证通知已被接收并处理为事件:
rubyGeo::Event.where(replicable_name: 'container_repository')
你还可以通过检查 geo.log 中来自 Geo::ContainerRepositorySyncService 的条目来进一步验证。
镜像仓库事件日志响应状态 401 未授权不可接受
401 Unauthorized 错误表示主站点的容器镜像仓库通知未被 Rails 应用程序接受,从而无法通知极狐GitLab 有镜像被推送。
要解决此问题,请确保随镜像仓库通知发送的授权标头与主站点上配置的内容匹配,就像在 配置主站点 步骤中所做的那样。
镜像仓库错误:token from untrusted issuer: "<token>"
在 Geo 中复制容器镜像时,你可能会看到错误 token from untrusted issuer: "<token>"。
当容器镜像仓库配置不正确,导致 Sidekiq 的 JWT 认证失败时,会出现此问题。
要解决此问题:
- 确保两个站点共享一个签名密钥对,如 配置辅助站点 中所述。
- 验证两个容器镜像仓库以及主站点和辅助站点都配置为使用相同的令牌颁发者。更多信息,请参阅 在单独的节点上配置极狐GitLab 和容器镜像仓库。
- 对于多节点部署,请确认 Sidekiq 节点上配置的颁发者与镜像仓库上配置的值匹配。
手动触发容器镜像仓库同步事件
为帮助排查故障,你可以手动触发容器镜像仓库复制过程:
- 在右上角,选择 管理员。
- 在左侧边栏中,选择 Geo > 站点。
- 在 辅助站点 的 复制详情 中,选择 容器镜像仓库。
- 对某一行选择 重新同步,或选择 全部重新同步。
你还可以在辅助站点的 Rails 控制台中运行以下命令来手动触发重新同步:
ruby1registry = Geo::ContainerRepositoryRegistry.first # Choose a Geo registry entry 2registry.replicator.sync # Resync the container repository 3pp registry.reload # Look at replication state fields 4 5#<Geo::ContainerRepositoryRegistry:0x00007f54c2a36060 6 id: 1, 7 container_repository_id: 1, 8 state: "2", 9 retry_count: 0, 10 last_sync_failure: nil, 11 retry_at: nil, 12 last_synced_at: Thu, 28 Sep 2023 19:38:05.823680000 UTC +00:00, 13 created_at: Mon, 11 Sep 2023 15:38:06.262490000 UTC +00:00>
state 字段表示同步状态:
- "0":等待同步(通常表示从未同步)
- "1":同步已启动(当前正在运行同步作业)
- "2":已成功同步
- "3":同步失败
停机后仓库未重新同步
如果容器镜像仓库复制因 geo_container_repository_replication 功能标志或错误配置而被禁用了一段时间,那么在此期间推送的镜像可能不会自动同步到 辅助 站点。
在复制重新启用后,停机期间创建的新容器镜像仓库会自动被回填工作进程捕获。但是,对现有容器镜像仓库的更新(例如,向现有仓库推送新标签)不会自动重新同步。Geo 管理界面可能仍会报告 100% 复制,因为同步状态是基于仓库条目状态,而不是内容验证。
在 主 站点的重新验证周期检测到校验和不匹配后,更新的容器镜像仓库最终会重新同步。有关重新验证间隔的更多信息,请参阅 仓库重新验证。
要强制立即重新同步而不等待重新验证,请参阅 手动重试复制或验证。