用于次要站点的容器镜像库
您可以在您的次要 Geo 站点上设置一个容器镜像库,以镜像主要 Geo 站点上的镜像。
支持的容器镜像库
Geo 支持以下类型的容器镜像库:
支持的镜像格式
Geo 支持以下容器镜像格式:
此外,Geo 还支持 BuildKit 缓存镜像。
支持的存储
Docker
有关受支持的镜像库存储驱动程序的更多信息,请参阅 Docker 镜像库存储驱动程序。
阅读部署 Registry 时的负载均衡注意事项,以及如何为极狐GitLab 集成的容器镜像库设置存储驱动。
支持 OCI 产物的镜像库
以下镜像库支持 OCI 产物:
- CNCF Distribution - local/offline verification
- Azure Container Registry (ACR)
- Amazon Elastic Container Registry (ECR)
- Google Artifact Registry (GAR)
- GitHub Packages container registry (GHCR)
- Bundle Bar
获取更多信息,查看 OCI Distribution Specification。
配置容器镜像库复制
您可以启用与存储无关的复制,以便将其用于云或本地存储。每当将新镜像推送到主要站点时,每个次要站点都会将其拉到自己的容器镜像库中。
要配置容器镜像库复制:
- 配置主要站点。
- 配置次要站点。
- 验证容器镜像库复制。
配置主要站点
在执行后续步骤之前,请确保您已设置容器镜像库,并在主要站点上工作。
为了能够复制新的容器镜像,容器镜像库必须针对每次推送,向主要站点发送通知事件。容器镜像库和主要站点上的 Web 节点之间共享的令牌,用于使通信更加安全。
-
SSH 进入您的极狐GitLab 主服务器并以 root 身份登录(对于 HA,只需要一个 Registry 节点):
sudo -i
-
编辑
/etc/gitlab/gitlab.rb
:registry['notifications'] = [ { 'name' => 'geo_event', 'url' => 'https://<example.com>/api/v4/container_registry_event/events', 'timeout' => '500ms', 'threshold' => 5, 'backoff' => '1s', 'headers' => { 'Authorization' => ['<replace_with_a_secret_token>'] } } ]
将<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
部分中指定通知密码。 -
仅适用于 HA。在每个 Web 节点上编辑
/etc/gitlab/gitlab.rb
:registry['notification_secret'] = '<replace_with_a_secret_token_generated_above>'
-
重新配置您刚刚更新的每个节点:
gitlab-ctl reconfigure
配置次要站点
在执行后续步骤之前,请确保您已设置容器镜像库并在次要站点上工作。
应在您希望看到复制的容器镜像的每个次要站点上执行以下步骤。
因为我们需要允许次要站点与主要站点容器镜像库进行安全通信,所以我们需要为所有站点提供一个密钥对。次要站点使用此密钥生成一个短期 JWT,该 JWT 只能拉取以访问主要站点容器镜像库。
对于次要站点上的每个应用程序和 Sidekiq 节点:
-
SSH 进入节点并以
root
用户身份登录:sudo -i
-
将
/var/opt/gitlab/gitlab-rails/etc/gitlab-registry.key
从主要站点复制到节点。 -
编辑
/etc/gitlab/gitlab.rb
并添加:gitlab_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/'
-
重新配置节点,使更改生效:
gitlab-ctl reconfigure
验证复制
要验证容器镜像库复制是否正常工作,请在次要站点上:
- 在左侧边栏中,选择 搜索或转到。
- 选择 管理中心。
- 在左侧边栏中,选择 Geo > 节点。初始复制或“回填”可能仍在进行中。
您可以从浏览器中的主要站点的 Geo 节点 仪表盘监控每个 Geo 站点上的同步过程。
故障排查
确认启用了容器镜像仓库复制功能
可以在 Rails 控制台上使用如下命令进行确认:
Geo::ContainerRepositoryRegistry.replication_enabled?
丢失容器镜像仓库通知事件
- 当镜像被推送到主要站点的容器镜像库时,它应该触发容器镜像库通知。
- 主站点的容器镜像仓库调用主站点的 API
https://<example.com>/api/v4/container_registry_event/events
- 主站点将
replicable_name: 'container_repository', model_record_id: <ID of the container repository>
插入到geo_events
表中形成记录。 - PostgreSQL 将此记录复制到次要站点的数据库。
- Geo Log Cursor 服务处理新的事件并将 Sidekiq 作业
Geo::EventWorker
排入队列。
为了验证这能够正确工作,推送镜像到主要站点的容器镜像库,并在 Rails 控制台中运行以下命令以验证是否已接收到通知,并将其处理为事件:
Geo::Event.where(replicable_name: 'container_repository')
您还可以通过 geo.log
中的 Geo::ContainerRepositorySyncService
来验证是否有对应的条目。
镜像仓库事件日志响应状态为 401 未授权认证不予接受
401 Unauthorized
错误预示着主要站点的容器镜像库通知未被 Rails 应用程序接受,从而阻止它通知极狐GitLab 有东西被推送。
要修复此问题,需要确保被发送的授权标头要和主站点上配置的标头相匹配,正如在配置主要站点中所做。
镜像仓库错误: token from untrusted issuer: "<token>"
要复制一个容器镜像,Sidekiq 使用 JWT 来向容器镜像库进行身份验证。Geo 复制将其作为容器镜像仓库配置正确配置的前提。
确保主次站点共享单个签名的密钥对,正如在配置次要站点中所描述的,并且主次站点的容器镜像库,加上主次站点,都配置为使用相同的令牌颁发者。
在多节点部署中,请确保 Sidekiq 节点上配置的颁发者与注册表上配置的颁发者相匹配。
手动触发容器镜像仓库同步事件
为了帮助排查故障,您可以手动触发容器镜像库复制过程:
- 在左侧导航栏底部,选择管理员。
- 选择 Geo > 节点。
- 在次要站点的复制详细信息中,选择容器镜像库。
- 选择重新同步以重新同步单个容器镜像库,或选择重新同步全部以重新同步所有容器镜像库。
您还可以在次站点的 Rails 控制台中运行以下命令来手动触发容器镜像库复制过程:
registry = Geo::ContainerRepositoryRegistry.first # Choose a Geo registry entry
registry.replicator.sync # Resync the container repository
pp registry.reload # Look at replication state fields
#<Geo::ContainerRepositoryRegistry:0x00007f54c2a36060
id: 1,
container_repository_id: 1,
state: "2",
retry_count: 0,
last_sync_failure: nil,
retry_at: nil,
last_synced_at: Thu, 28 Sep 2023 19:38:05.823680000 UTC +00:00,
created_at: Mon, 11 Sep 2023 15:38:06.262490000 UTC +00:00>
state
字段代表同步状态:
-
"0"
: 等待同步(通常意味着从来没同步过) -
"1"
: 开始同步(当前正有同步作业在运行) -
"2"
: 同步成功 -
"3"
: 同步失败