次要站点的 Geo 代理
- Tier: 专业版,旗舰版
- Offering: 私有化部署
History
- HTTP 代理用于具有单独 URL 的次要站点,在极狐GitLab 14.5 中引入,使用名为 geo_secondary_proxy_separate_urls 的功能标志。默认禁用。
- 在极狐GitLab 15.1 中,为 JihuLab.com 和私有化部署启用。
次要站点的行为与完整的读写极狐GitLab 实例相同。它们透明地将所有操作代理到主站点,除了 一些显著例外。
此行为支持的用例包括:
- 将所有 Geo 站点放在单个 URL 后面,以提供一致、无缝和全面的体验,无论用户访问哪个站点。用户不需要处理多个极狐GitLab URL。
- 地理负载平衡流量,无需担心写访问。
有关已知问题,请参阅 Geo 文档中的代理相关项。
为 Geo 站点设置统一 URL
次要站点可以透明地提供读写流量。因此,您可以使用单个外部 URL,以便请求可以到达主 Geo 站点或任何次要 Geo 站点。这提供了无论用户访问哪个站点的一致、无缝和全面的体验。用户无需处理多个 URL,甚至不需要知道多个站点的概念。
您可以通过以下方式将流量路由到 Geo 站点:
- 地理位置感知的 DNS。用于将流量路由到最近的 Geo 站点,无论是主站点还是次要站点。有关示例,请遵循 配置位置感知 DNS。
- 轮循 DNS。
- 负载均衡器。它必须使用粘性会话,以避免身份验证失败和跨站请求错误。DNS 路由本质上是粘性的,因此不共享此警告。
配置位置感知 DNS
按照此示例将流量路由到最近的 Geo 站点,无论是主站点还是次要站点。
先决条件
此示例创建一个 gitlab.example.com 子域,自动定向请求:
- 来自欧洲的请求到 次要 站点。
- 来自所有其他位置的请求到 主 站点。
对于此示例,您需要:
- 一个正在运行的 Geo 主 站点和 次要 站点,请参阅 Geo 设置说明。
- 管理您的域的 DNS 区域。虽然以下说明使用 AWS Route53,但其他服务如 Cloudflare 也可以使用。
AWS Route53
在此示例中,您使用 Route53 设置的 Route53 托管区域来管理您的域。
在 Route53 托管区域中,可以使用流量策略来设置各种路由配置。要创建流量策略:
-
转到 Route53 仪表板并选择 流量策略。
-
选择 创建流量策略。
-
在 策略名称 字段中填写 Single Git Host 并选择 下一步。
-
将 DNS 类型 保留为 A: IP Address in IPv4 format。
-
选择 连接到,然后选择 地理位置规则。
-
对于第一个 位置:
- 保留为 Default。
- 选择 连接到,然后选择 新终端。
- 选择 类型 value 并填写 <您的 **主** IP 地址>。
-
对于第二个 位置:
- 选择 Europe。
- 选择 连接到,然后选择 新终端。
- 选择 类型 value 并填写 <您的 **次要** IP 地址>。

-
选择 创建流量策略。
-
在 策略记录 DNS 名称 中填写 gitlab。

-
选择 创建策略记录。
您已成功设置了一个单一主机,如 gitlab.example.com,通过地理位置将流量分配到您的 Geo 站点。
配置每个站点使用相同的外部 URL
在您已设置从单个 URL 到所有 Geo 站点的路由后,如果您的站点使用不同的 URL,请遵循以下步骤:
-
在每个极狐GitLab 站点上,SSH 到运行 Rails(Puma、Sidekiq、Log-Cursor)的 每个 节点,并将 external_url 设置为单个 URL:
shellsudo -e /etc/gitlab/gitlab.rb -
重新配置更新的节点以使更改生效:
shellsudo gitlab-ctl reconfigure -
为了与次要 Geo 站点上设置的新外部 URL 匹配,主数据库需要反映此更改。
在 主 站点的 Geo 管理页面中,编辑每个使用次要代理的 Geo 次要站点,并将 URL 字段设置为单个 URL。确保主站点也在使用此 URL。
为了允许站点相互通信,确保 Internal URL 字段对每个站点都是唯一的。
在 Kubernetes 中,您可以 使用与主站点相同的 global.hosts.domain 域。
为次要 Geo 站点设置单独的 URL
您可以为每个站点使用不同的外部 URL。您可以使用此方法为特定用户组提供特定站点。或者,您可以让用户控制他们使用哪个站点,但他们必须了解其选择的含义。
将次要 Geo 站点配置为与主站点不同的外部 URL
如果您的次要站点使用与主站点相同的外部 URL:
-
在次要站点上,SSH 到运行 Rails(Puma、Sidekiq、Log-Cursor)的 每个 节点,并将 external_url 设置为次要站点的所需 URL:
shellsudo -e /etc/gitlab/gitlab.rb -
重新配置更新的节点以使更改生效:
shellsudo gitlab-ctl reconfigure -
为了与次要 Geo 站点上设置的新外部 URL 匹配,主数据库需要反映此更改。
在 主 站点的 Geo 管理页面中,编辑目标次要站点并将 URL 字段设置为所需 URL。
为了允许站点相互通信,确保 Internal URL 字段对每个站点都是唯一的。如果所需 URL 对此站点是唯一的,则可以清除 Internal URL 字段。在保存时,它默认为外部 URL。
主 Geo 站点关闭时次要站点的行为
考虑到网络流量被代理到主站点,当主站点不可访问时,次要站点的行为有所不同:
- UI 和 API 流量返回与主站点相同的错误(或如果主站点完全不可访问则失败),因为它们被代理。
- 对于完全更新到正在访问的特定次要站点上的存储库,Git 读取操作仍然按预期工作,包括通过 HTTP(s) 或 SSH 进行身份验证。然而,极狐GitLab Runner 执行的 Git 读取将失败。
- 对于未复制到次要站点的存储库的 Git 操作返回与主站点相同的错误,因为它们被代理。
- 所有 Git 写操作返回与主站点相同的错误,因为它们被代理。
次要 Geo 站点加速的功能
发送到次要 Geo 站点的大多数 HTTP 流量被代理到主 Geo 站点。通过这种架构,次要 Geo 站点能够支持写请求,并避免写后读问题。某些 读 请求由次要站点本地处理,以提高附近的延迟和带宽。
下表详细描述了通过 Geo 次要站点 Workhorse 代理测试的组件。它不涵盖所有数据类型。
在此上下文中,加速读取指的是从次要站点提供的读请求,前提是次要站点上的组件数据是最新的。如果次要站点上的数据被确定为过时,则请求将被转发到主站点。未在下表中列出的组件的读请求始终自动转发到主站点。
| 功能 / 组件 | 加速读取? | 备注 |
|---|---|---|
| 项目、wiki、设计存储库(使用 Web UI) | 否 | |
| 项目、wiki 存储库(使用 Git) | 是 | Git 读取从本地次要站点提供,而推送被代理到主站点。选择性同步或存储库在 Geo 次要站点上不存在的情况会抛出“未找到”错误。 |
| 项目、个人代码片段(使用 Web UI) | 否 | |
| 项目、个人代码片段(使用 Git) | 是 | Git 读取从本地次要站点提供,而推送被代理到主站点。选择性同步或存储库在 Geo 次要站点上不存在的情况会抛出“未找到”错误。 |
| 群组 wiki 存储库(使用 Web UI) | 否 | |
| 群组 wiki 存储库(使用 Git) | 是 | Git 读取从本地次要站点提供,而推送被代理到主站点。选择性同步或存储库在 Geo 次要站点上不存在的情况会抛出“未找到”错误。 |
| 用户上传 | 否 | |
| LFS 对象(使用 Web UI) | 否 | |
| LFS 对象(使用 Git) | 是 | |
| Pages | 否 | Pages 可以使用相同的 URL(无需访问控制),但必须单独配置且不被代理。 |
| 高级搜索(使用 Web UI) | 否 | |
| 容器注册表 | 否 | 容器注册表仅推荐用于灾难恢复场景。如果次要站点的容器注册表不是最新的,则读取请求将提供旧数据,因为请求不会转发到主站点。加速容器注册表是计划中的。 |
| 依赖代理 | 否 | 读取请求到 Geo 次要站点的依赖代理始终被代理到主站点。 |
| 所有其他数据 | 否 | 未在此表中列出的组件的读取请求始终自动转发到主站点。 |
禁用次要站点 HTTP 代理
次要站点 HTTP 代理在次要站点使用统一 URL 时默认启用,意味着它配置了与主站点相同的 external_url。在这种情况下禁用代理往往没有帮助,因为在相同的 URL 下服务完全不同的行为,具体取决于路由。
如果禁用次要代理会发生什么
禁用代理功能标志具有以下一般效果:
- 次要站点不代理 HTTP 请求到主站点。相反,它尝试自己服务请求或失败。
- Git 请求通常成功。Git 推送被重定向或代理到主站点。
- 除 Git 请求外,任何可能写入数据的 HTTP 请求都失败。读取请求通常成功。
- 次要站点 UI 显示一个横幅:

| 功能 / 组件 | 成功 | 备注 |
|---|---|---|
| 项目、wiki、设计存储库(使用 Web UI) | {dotted-circle} 可能 | 读取从本地存储的数据提供。写入导致错误。 |
| 项目、wiki 存储库(使用 Git) | {check-circle} 是 | Git 读取从本地存储的数据提供,而推送被代理到主站点。如果存储库在 Geo 次要站点上不存在,例如由于选择性同步排除,则会导致“未找到”错误。 |
| 项目、个人代码片段(使用 Web UI) | {dotted-circle} 可能 | 读取从本地存储的数据提供。写入导致错误。 |
| 项目、个人代码片段(使用 Git) | {check-circle} 是 | Git 读取从本地存储的数据提供,而推送被代理到主站点。如果存储库在 Geo 次要站点上不存在,例如由于选择性同步排除,则会导致“未找到”错误。 |
| 群组 wiki 存储库(使用 Web UI) | {dotted-circle} 可能 | 读取从本地存储的数据提供。写入导致错误。 |
| 群组 wiki 存储库(使用 Git) | {check-circle} 是 | Git 读取从本地存储的数据提供,而推送被代理到主站点。如果存储库在 Geo 次要站点上不存在,例如由于选择性同步排除,则会导致“未找到”错误。 |
| 用户上传 | {dotted-circle} 可能 | 上传文件从本地存储的数据提供。尝试在次要站点上传文件会导致错误。 |
| LFS 对象(使用 Web UI) | {dotted-circle} 可能 | 读取从本地存储的数据提供。写入导致错误。 |
| LFS 对象(使用 Git) | {check-circle} 是 | LFS 对象从本地存储的数据提供,而推送被代理到主站点。如果 LFS 对象在 Geo 次要站点上不存在,例如由于选择性同步排除,则会导致“未找到”错误。 |
| Pages | {dotted-circle} 可能 | Pages 可以使用相同的 URL(无需访问控制),但必须单独配置且不被代理。 |
| 高级搜索(使用 Web UI) | {dotted-circle} 否 | |
| 容器注册表 | {dotted-circle} 否 | 容器注册表仅推荐用于灾难恢复场景。如果次要站点的容器注册表不是最新的,则读取请求将提供旧数据,因为请求不会转发到主站点。 |
| 依赖代理 | {dotted-circle} 否 | |
| 所有其他数据 | {dotted-circle} 可能 | 读取从本地存储的数据提供。写入导致错误。 |
您应该使用功能标志而不是使用 GEO_SECONDARY_PROXY 环境变量。
在极狐GitLab 15.1 中,即使没有统一 URL,也在次要站点上默认启用 HTTP 代理。如果需要在所有次要站点上禁用代理,最简单的方法是禁用功能标志:
-
SSH 到您的主 Geo 站点上运行 Puma 或 Sidekiq 的节点并运行:
shellsudo gitlab-rails runner "Feature.disable(:geo_secondary_proxy_separate_urls)" -
在您的次要 Geo 站点上运行 Puma 的所有节点上重启 Puma:
shellsudo gitlab-ctl restart puma
要恢复更改以重新启用次要站点代理:
-
SSH 到您的主 Geo 站点上运行 Puma 或 Sidekiq 的节点并运行:
shellsudo gitlab-rails runner "Feature.enable(:geo_secondary_proxy_separate_urls)" -
在您的次要 Geo 站点上运行 Puma 的所有节点上重启 Puma:
shellsudo gitlab-ctl restart puma
每个站点禁用次要站点 HTTP 代理
如果有多个次要站点,您可以单独在每个次要站点上禁用 HTTP 代理,方法如下:
-
SSH 到您的次要 Geo 站点上每个应用节点(直接服务用户流量)并添加以下环境变量:
shellsudo -e /etc/gitlab/gitlab.rbrubygitlab_workhorse['env'] = { "GEO_SECONDARY_PROXY" => "0" } -
重新配置更新的节点以使更改生效:
shellsudo gitlab-ctl reconfigure
禁用次要站点 Git 代理
无法禁用以下操作的转发:
- 通过 SSH 的 Git 推送
- 当 Git 存储库在次要站点上过时时通过 SSH 的 Git 拉取
- 通过 HTTP 的 Git 推送
- 当 Git 存储库在次要站点上过时时通过 HTTP 的 Git 拉取