次要站点的 Geo 代理
- 具有单独 URL 的次要站点 HTTP 代理默认启用于极狐GitLab 15.1。
次要站点的行为时具有完全读取权限的极狐GitLab 实例。他们会将所有操作透明代理至主要站点,需要注意某些值得注意的例外。
这种行为支持以下用例,包括:
- 将所有 Geo 站点置于一个单一的 URL 之后,以便为用户提供一致、无缝且全面的体验,无论用户访问哪个站点。用户无需在多个极狐GitLab URL 之间周旋。
- 无需担心写访问的 Geo 负载均衡流量。
为 Geo 站点设置统一的 URL
次要站点可以透明地处理读写流量。因此,您可以使用一个单一的外部 URL,这样请求可以访问主 Geo 站点或任何次要 Geo 站点。无论用户访问哪个站点,这都能提供一致、无缝且全面的体验。用户无需在多个 URL 之间来回切换,甚至无需知晓存在多个站点的情况。
你可以通过以下方式将流量路由到 Geo 站点:
- 具有地理位置感知的 DNS。将流量路由到最近的地理站点,无论是主要站点还是次要站点。例如,请遵循配置具有地理位置感知的 DNS。
- 轮询 DNS。
- 负载均衡器。它必须使用粘性会话以避免认证失败和跨站点请求错误。DNS 路由本质上具有粘性,因此没有此问题。
配置位置敏感的 DNS
遵循此示例将流量路由至最近的 Geo 站点,不管是主要站点还是次要站点。
先决条件
此示例会创建一个 gitlab.example.com
的子域名,该子域名会自动将路由请求:
- 从欧洲到 次要 站点。
- 从所有其他地方到 主要 站点。
次要站点可以透明地提供读写流量。您可以使用单个外部 URL,以便请求可以到达主要 Geo 站点或任何使用 Geo 代理的次要 Geo 站点。
配置每个站点使用相同的外部 URL
在您将路由从一个单一的 URL 设置到您所有的 Geo 站点之后,如果您的站点使用不同的 URL,请遵循以下步骤:
-
在每个极狐GitLab 站点上,SSH 到运行 Rails(Puma、Sidekiq、Log-Cursor)的 每个 节点上,将
external_url
设置为单个 URL:sudo -e /etc/gitlab/gitlab.rb
-
重新配置极狐GitLab 以让配置生效:
sudo gitlab-ctl reconfigure
-
为了和设置在次要 Geo 站点上的外部 URL 相匹配,主数据库需要映射以变更。
在 主要 站点的 Geo 管理员界面,编辑目标次要站点,并将
URL
字段设置为期望的 URL。确保主要站点也在使用此 URL。为了允许站点间能够互相通信,确保每个站点的
URL
字段是独一无二的。
在 Kubernetes 中,您可以为主站点使用 global.hosts.domain
下的相同域名。
为次要 Geo 站点设置单独的 URL
您可以为每个站点使用不同的外部 URL。您可以使用此功能为特定的用户提供特定的站点。或者,你可以让用户控制他们使用哪个站点,不过他们必须明白自己选择的影响。
皮质次要站点使用不同的外部 URL 而不是主站点的
如果主从站点使用相同的 UR:
-
在次要站点上,SSH 到每个运行 Rails(Puma、Sidekiq、Log-Cursor)的节点,并将次要站点的期望 URL 设置为
external_url
:sudo -e /etc/gitlab/gitlab.rb
-
重新配置极狐GitLab 以让配置生效:
sudo gitlab-ctl reconfigure
-
为了和设置在次要 Geo 站点上的外部 URL 相匹配,主数据库需要映射以变更。
在 主要 站点的 Geo 管理员界面,编辑目标次要站点,并将
URL
字段设置为期望的 URL。为了允许站点之间互相通信,确保每个站点的
Internal URL
字段是独一无二的。如果此站点的期望 URL 是第一无二的,则可以清除URL
字段。保存时,它将默认为外部 URL。
已知问题
在 Geo 限制的综合列表中查看与代理相关的条目。
当主 Geo 站点宕机时,次要站点的行为
考虑到 web 流量会被代理到主站点,当主站点不可访问时,次要站点的行为是不同的:
- UI 和 API 流量会返回和主站点相同的错误(如果主站点一点也不可访问,则失败),因为它们被代理了。
- 对于正在被访问的特定次要站点上已完全更新的存储库,Git 读取操作仍能按预期工作,包括通过 HTTP (s) 或 SSH 进行的身份验证。然而,由极狐GitLab runner 执行的 Git 读取操作将会失败。
- 对于未复制到次要站点的存储库的 Git 操作会返回与主站点相同的错误,因为它们是被代理的。
- 所有 Git 写操作会返回与主站点相同的错误,因为它们是被代理的。
由次要 Geo 站点加速的功能
发送到次要 Geo 站点的大多数 HTTP 流量都可以代理到主要 Geo 站点。有了这个架构,次要 Geo 站点能够支持写入请求。次要站点会本地处理某些读取请求以改善附近的时延和带宽。所有写入请求都被代理到主要站点。
下表详细介绍了当前通过 Geo 次要站点 Workhorse 代理测试的组件。不涵盖所有的数据类型。
在此上下文中,加速读取是指从次要站点提供的读取请求,前提是次要站点上的组件数据是最新的。如果确定次要站点上的数据已过期,则将请求转发到主要站点上。对下表中未列出的组件的读取请求始终会自动转发到主要站点上。
功能/组件 | 读写加速? | Notes |
---|---|---|
项目、wiki、设计仓库(使用 web UI) | No | |
项目、wiki 仓库(使用 Git) | Yes | |
项目、个人代码片段(使用 web UI) | No | |
项目、个人代码片段(使用 Git) | Yes | Git 的读取操作由本地的次要站点提供服务,而推送操作被代理到主站点。选择性同步或在 Geo 次要站点本地不存在仓库的情况下会抛出“未找到”错误。 |
群组 wiki 仓库(使用 web UI) | No | |
群组 wiki 仓库(使用 Git) | Yes | Git 的读取操作由本地的次要站点提供服务,而推送操作被代理到主站点。选择性同步或在 Geo 次要站点本地不存在仓库的情况下会抛出“未找到”错误。 |
用户上传 | No | |
LFS 对象(使用 web UI) | No | |
LFS 对象(使用 Git) | Yes | |
Pages | No | Pages 可以使用相同的 URL(无访问控制权限),但是必需分开配置并不能够被代理。 |
高级搜索(使用 web UI) | No | |
容器镜像仓库 | No | 容器镜像仓库仅推荐用于灾备场景。如果次要站点的容器镜像仓库未更新,那么读请求将使用旧数据来处理,因为该请求不会转发到主站点。加速容器镜像仓库目前正在计划中。 |
依赖代理 | No | 对于 Geo 次要站点的依赖代理的读请求总是被代理到主站点。 |
所有其他数据 | No | 针对此表中未列出的组件的读请求总是自动转发到主站点。 |
禁用次要站点的 HTTP 代理
当次要站点使用统一的 URL 时,其 HTTP 代理默认启用,它和主站点配置的 external_url
一致。在这种情况下,由于根据路由的不同,在相同的 URL 上会提供完全不同的行为,所以禁用代理通常没有帮助。
在极狐GitLab 15.1 中,即使没有统一的 URL,在次要站点上默认也会启用 HTTP 代理。如果需要在所有次要站点上禁用代理,最简单的方法是禁用功能标志:
-
SSH 到运行 Puma 或 Sidekiq 的主 Geo 站点上并运行:
sudo gitlab-rails runner "Feature.disable(:geo_secondary_proxy_separate_urls)"
-
在所有运行 Puma 的次要 Geo 站点上重启此服务:
sudo gitlab-ctl restart puma
在 Kubernetes 情况下,您可以在 toolbox pod 中运行同样的命令。更多详情,可以参考 Kubernetes chart 表格
为每个站点禁用次要站点 HTTP 代理
如果有多个次要站点,则您可以通过如下步骤,在每个次要站点上单独禁用 HTTP 代理:
::Tabs
:::TabTitle Linux package (Omnibus)
-
SSH 到次要 Geo 站点的每个应用程序节点(直接服务于用户流量)上,添加如下环境变量:
sudo -e /etc/gitlab/gitlab.rb
gitlab_workhorse['env'] = { "GEO_SECONDARY_PROXY" => "0" }
-
重新配置极狐GitLab,让配置生效:
sudo gitlab-ctl reconfigure
:::TabTitle Helm chart (Kubernetes)
您可以使用 --set gitlab.webservice.extraEnv.GEO_SECONDARY_PROXY="0"
或在您的 values 文件中指定如下内容:
You can use --set gitlab.webservice.extraEnv.GEO_SECONDARY_PROXY="0"
,
gitlab:
webservice:
extraEnv:
GEO_SECONDARY_PROXY: "0"
::EndTabs
禁用次要站点的 Git 代理
无法禁用以下的转发操作:
- 基于 SSH 的 Git push
- 当次要站点上的 Git 仓库过期时,基于 SSH 的 Git pull
- 基于 HTTP 的 Git push
- 当次要站点上的 Git 仓库过期时,基于 HTTP 的 Git pull