极狐 GitLab

灾难恢复 (Geo)

Tier: 专业版,旗舰版

Offering: 私有化部署

Geo 复制您的数据库、Git 仓库和其他资产。存在一些已知问题

- 多辅助站点配置需要完全重新同步和重新配置所有未提升的辅助站点,并导致停机。 - 辅助站点提升后,主站点将完全分离。如果您希望恢复主站点,则必须将其添加为新的辅助站点。

启用选择性同步的辅助站点#

提升启用了选择性同步的辅助站点会导致所有未复制到该辅助站点的数据永久丢失。更多信息,请参见提升启用了选择性同步的辅助站点

gitlab-cluster.json 文件#

当您使用 gitlab-ctl geo promote 将辅助站点提升为主站点时,该命令会自动在其执行的每个节点上创建 /etc/gitlab/gitlab-cluster.json 文件。在大多数情况下,您不需要手动编辑此文件。

gitlab-cluster.json 文件允许提升命令自动化配置更改,而无需直接修改 /etc/gitlab/gitlab.rb。以编程方式编辑 gitlab.rb 容易出错,因此 gitlab-cluster.json 充当机器管理的覆盖层。

当两个文件同时存在时,执行 gitlab-ctl reconfigure 时,gitlab-cluster.json 中的值优先于 gitlab.rb 中的相应值。当您运行此命令时,会看到类似以下警告:

plaintext
'geo_primary_role' 在 /etc/gitlab/gitlab-cluster.json 中被定义为 'true',并覆盖了 /etc/gitlab/gitlab.rb 中的设置 'geo_secondary_role' 在 /etc/gitlab/gitlab-cluster.json 中被定义为 'false',并覆盖了 /etc/gitlab/gitlab.rb 中的设置

提升后,出现此警告是正常的。

文件结构#

一个典型的 gitlab-cluster.json 文件如下所示:

json
1{ 2 "primary": true, 3 "secondary": false, 4 "geo_secondary": { 5 "enable": false 6 } 7}
描述
primary当为 true 时,启用 geo_primary_role,将节点配置为 Geo 主站点。
secondary当为 true 时,启用 geo_secondary_role,将节点配置为 Geo 辅助站点。
geo_secondary包含与 Geo 辅助站点配置相关的设置,例如跟踪数据库。"enable": false 禁用辅助站点特定的服务。

primarysecondary 键分别映射到 geo_primary_rolegeo_secondary_role。这些角色对于单节点设置很方便,不应在已在 gitlab.rb 中显式配置了各个服务角色的多节点配置中使用。

删除文件#

成功提升后,您可以保留 gitlab-cluster.json 文件。但是,在以下情况下,您应该将其删除:

  • 如果您将降级的主站点重新作为辅助站点恢复,则必须从每个 Sidekiq、PostgreSQL、Gitaly 和 Rails 节点删除 gitlab-cluster.json

  • 当您更新 gitlab.rb 以设置 Geo 角色(例如 roles(['geo_primary_role']))后,并希望 gitlab.rb 成为唯一的配置源时。

  • 从部分故障转移中恢复后。

    有关恢复期间手动创建该文件的详细信息,请参见从部分故障转移中恢复

删除文件的步骤:

  • 运行以下命令:

    shell
    sudo rm /etc/gitlab/gitlab-cluster.json sudo gitlab-ctl reconfigure

    在多节点设置中,对站点中的每个节点重复执行这些命令。

有关 gitlab-cluster.json 如何与重新配置过程交互的技术细节,请参见Omnibus 重新配置文档

在单辅助站点配置中提升辅助 Geo 站点#

虽然您无法自动提升 Geo 副本并执行故障转移,但如果您有对机器的 root 访问权限,则可以手动提升。

此过程将一个辅助 Geo 站点提升为主站点。为了尽快恢复地理冗余,您应在遵循这些说明后立即添加一个新的辅助站点

如果可能,请允许复制完成#

如果辅助站点仍在从主站点复制数据,请尽可能严格遵循计划的故障转移文档,以避免不必要的数据丢失。

步骤 1. 永久禁用主站点#

如果**主站点**离线,**主站点**上可能保存有尚未复制到**辅助站点**的数据。如果您继续,这些数据应被视为已丢失。

如果发生主站点中断,您应尽一切可能避免裂脑情况,即写入可能发生在两个不同的极狐GitLab 实例中,从而使恢复工作复杂化。因此,为了准备故障转移,我们必须禁用主站点

  • 如果您有 SSH 访问权限:

    1. 通过 SSH 登录主站点并停止和禁用极狐GitLab:

      shell
      sudo gitlab-ctl stop
    2. 防止极狐GitLab 在服务器意外重启时再次启动:

      shell
      sudo systemctl disable gitlab-runsvdir
  • 如果您没有主站点的 SSH 访问权限,请将机器离线并采取任何可用手段阻止其重启。 您可能需要:

    • 重新配置负载均衡器。
    • 更改 DNS 记录(例如,将主 DNS 记录指向辅助站点以停止使用主站点)。
    • 停止虚拟服务器。
    • 通过防火墙阻止流量。
    • 撤销主站点的对象存储权限。
    • 物理断开机器。

    如果您计划更新主域 DNS 记录,您可能希望保持较低的 TTL 以确保 DNS 更改快速传播。

    此过程中不会自动将主站点的/etc/gitlab/gitlab.rb 文件复制到辅助站点。请确保备份主站点的 /etc/gitlab/gitlab.rb 文件,以便稍后在辅助站点上恢复所需的值。

步骤 2. 提升辅助站点#

提升辅助站点时请注意以下几点:

  • 如果辅助站点已暂停,则提升会执行到最后一个已知状态的时间点恢复。辅助站点暂停期间在主站点上创建的数据将丢失。
  • 如果辅助站点已暂停,并且在此过程中遇到 ActiveRecord::StatementInvalid: PG::ReadOnlySqlTransaction: ERROR: cannot execute DELETE in a read-only transaction 错误消息,请参阅此知识库文章:Geo 提升失败并出现只读事务错误或主站点意外关闭后超时
  • 此时不应添加新的辅助站点。如果您想添加新的辅助站点,请在完成将辅助站点提升为主站点的整个过程之后进行。
  • 如果在此过程中遇到 ActiveRecord::RecordInvalid: Validation failed: Name has already been taken 错误消息,请参阅此故障排除建议
  • 如果您使用的是独立 URL,则应将主域 DNS 指向新提升的站点。否则,必须重新向新提升的站点注册 Runner,并更新所有 Git 远程、书签和外部集成。
  • 如果您正在使用位置感知 DNS,则在从 DNS 条目中移除旧主站点后,Runner 应自动连接到新的主站点。
  • 在主站点关闭后,在辅助站点上运行 gitlab-ctl promotion-preflight-checks 以检查 Geo 同步状态并执行最终验证检查。
  • 如果您不期望连接到先前主站点的 Runner 会重新上线,则应将其移除:
    • 通过 UI:
      1. 在右上角,选择 管理员
      2. 选择 CI/CD > Runners 并将其移除。
    • 使用 Runners API

提升在单节点上运行的辅助站点#

  1. 通过 SSH 登录辅助站点并执行:

    • 将辅助站点提升为主站点:

      shell
      sudo gitlab-ctl geo promote
    • 在不进一步确认的情况下将辅助站点提升为主站点:

      shell
      sudo gitlab-ctl geo promote --force
  2. 使用先前用于辅助站点的 URL 验证您能否连接到新提升的主站点

  3. 如果成功,辅助站点现已提升为主站点

运行 gitlab-ctl geo promote 时,会在节点上创建一个 gitlab-cluster.json 文件。该文件在重新配置时会覆盖 gitlab.rb 中的 Geo 角色设置。

步骤 3. 删除原辅助站点的跟踪数据库#

如果您的 /etc/gitlab/gitlab.rb 文件中启用了任何 geo_secondary[] 配置选项,请将其注释掉或删除,然后重新配置极狐GitLab 以使更改生效。

此时,您提升后的站点就是新的主极狐GitLab 站点。可选地,如果您希望再次将 Geo 设置为新的辅助站点,可以将旧站点恢复为辅助站点

提升具有多个节点和单辅助站点辅助站点#

  1. 通过 SSH 登录辅助站点中的每个 Sidekiq、PostgreSQL 和 Gitaly 节点,并运行以下命令之一:

    • 在辅助站点上将节点提升为主站点:

      shell
      sudo gitlab-ctl geo promote
    • 在不进一步确认的情况下将辅助站点提升为主站点:

      shell
      sudo gitlab-ctl geo promote --force
  2. 通过 SSH 登录辅助站点上的每个 Rails 节点,并运行以下命令之一:

    • 将辅助站点提升为主站点:

      shell
      sudo gitlab-ctl geo promote
    • 在不进一步确认的情况下将辅助站点提升为主站点:

      shell
      sudo gitlab-ctl geo promote --force
  3. 使用先前用于辅助站点的 URL 验证您能否连接到新提升的主站点

  4. 如果成功,辅助站点现已提升为主站点

运行 gitlab-ctl geo promote 时,会在节点上创建一个 gitlab-cluster.json 文件。该文件在重新配置时会覆盖 gitlab.rb 中的 Geo 角色设置。

使用 Patroni 备用集群提升辅助站点#

  1. 通过 SSH 登录辅助站点中的每个 Sidekiq、PostgreSQL 和 Gitaly 节点,并运行以下命令之一:

    • 将辅助站点提升为主站点:

      shell
      sudo gitlab-ctl geo promote
    • 在不进一步确认的情况下将辅助站点提升为主站点:

      shell
      sudo gitlab-ctl geo promote --force
  2. 通过 SSH 登录辅助站点上的每个 Rails 节点,并运行以下命令之一:

    • 将辅助站点提升为主站点:

      shell
      sudo gitlab-ctl geo promote
    • 在不进一步确认的情况下将辅助站点提升为主站点:

      shell
      sudo gitlab-ctl geo promote --force
  3. 使用先前用于辅助站点的 URL 验证您能否连接到新提升的主站点

  4. 如果成功,辅助站点现已提升为主站点

使用外部 PostgreSQL 数据库提升辅助站点#

gitlab-ctl geo promote 命令可与外部 PostgreSQL 数据库结合使用。在这种情况下,您必须首先手动提升与辅助站点关联的副本数据库:

  1. 提升与辅助站点关联的副本数据库。这会将数据库设置为读写。具体说明因数据库托管位置而异:

    • Amazon RDS

    • Azure PostgreSQL

    • Google Cloud SQL

    • 对于其他外部 PostgreSQL 数据库,请在辅助站点上保存以下脚本,例如 /tmp/geo_promote.sh,并修改连接参数以匹配您的环境。然后执行它以提升副本:

      shell
      1#!/bin/bash 2 3PG_SUPERUSER=postgres 4 5# The path to your pg_ctl binary. You may need to adjust this path to match 6# your PostgreSQL installation 7PG_CTL_BINARY=/usr/lib/postgresql/16/bin/pg_ctl 8 9# The path to your PostgreSQL data directory. You may need to adjust this 10# path to match your PostgreSQL installation. You can also run 11# `SHOW data_directory;` from PostgreSQL to find your data directory 12PG_DATA_DIRECTORY=/etc/postgresql/16/main 13 14# Promote the PostgreSQL database and allow read/write operations 15sudo -u $PG_SUPERUSER $PG_CTL_BINARY -D $PG_DATA_DIRECTORY promote
  2. 通过 SSH 登录辅助站点中的每个 Sidekiq、PostgreSQL 和 Gitaly 节点,并运行以下命令之一:

    • 将辅助站点提升为主站点:

      shell
      sudo gitlab-ctl geo promote
    • 在不进一步确认的情况下将辅助站点提升为主站点:

      shell
      sudo gitlab-ctl geo promote --force
  3. 通过 SSH 登录辅助站点上的每个 Rails 节点,并运行以下命令之一:

    • 将辅助站点提升为主站点:

      shell
      sudo gitlab-ctl geo promote
    • 在不进一步确认的情况下将辅助站点提升为主站点:

      shell
      sudo gitlab-ctl geo promote --force
  4. 使用先前用于辅助站点的 URL 验证您能否连接到新提升的主站点

  5. 如果成功,辅助站点现已提升为主站点

(可选)更新主域 DNS 记录#

更新主域的 DNS 记录以指向辅助站点。这样就不需要更新所有对主域的引用,例如更改 Git 远程和 API URL。

  1. 通过 SSH 登录辅助站点并作为 root 登录:

    shell
    sudo -i
  2. 更新主域 DNS 记录。将主域的 DNS 记录更新为指向辅助站点后,编辑辅助站点上的 /etc/gitlab/gitlab.rb 以反映新 URL:

    ruby
    # Change the existing external_url configuration external_url 'https://<new_external_url>'

    更改external_url 不会阻止通过旧的辅助站点 URL 访问,只要辅助站点 DNS 记录仍然完好。

  3. 更新辅助站点的 SSL 证书:

    • 如果您使用 Let's Encrypt 集成,证书会自动更新。

    • 如果您手动设置了辅助站点的证书,请将证书从主站点复制到辅助站点。如果您无法访问主站点,请颁发新证书,并确保其主题备用名称中包含主站点辅助站点的 URL。您可以使用以下命令检查:

      shell
      /opt/gitlab/embedded/bin/openssl x509 -noout -dates -subject -issuer \ -nameopt multiline -ext subjectAltName -in /etc/gitlab/ssl/new-gitlab.new-example.com.crt
  4. 重新配置辅助站点以使更改生效:

    shell
    gitlab-ctl reconfigure
  5. 执行以下命令以更新新提升的主站点 URL:

    shell
    gitlab-rake geo:update_primary_node_url

    此命令使用在 /etc/gitlab/gitlab.rb 中定义的更改后的 external_url 配置。

  6. 验证您能否使用其 URL 连接到新提升的主站点。如果您更新了主域的 DNS 记录,根据之前的 DNS 记录 TTL,这些更改可能尚未传播。

(可选)将辅助 Geo 站点添加到已提升的主站点#

要将新的辅助站点上线,请遵循 Geo 设置说明

在多辅助站点配置中提升辅助 Geo 副本#

如果您有多个辅助站点,并且需要提升其中一个,我们建议您按照在单辅助站点配置中提升辅助 Geo 站点中的说明操作,之后还需两个额外步骤。

步骤 1. 准备新的主站点以服务一个或多个辅助站点#

  1. 通过 SSH 登录新的主站点并作为 root 登录:

    shell
    sudo -i
  2. 编辑 /etc/gitlab/gitlab.rb

    ruby
    1## Enable a Geo Primary role (if you haven't yet) 2roles ['geo_primary_role'] 3 4## 5# Allow PostgreSQL client authentication from the primary and secondary IPs. These IPs may be 6# public or VPC addresses in CIDR format, for example ['198.51.100.1/32', '198.51.100.2/32'] 7## 8postgresql['md5_auth_cidr_addresses'] = ['<primary_site_ip>/32', '<secondary_site_ip>/32'] 9 10# Every secondary site needs to have its own slot so specify the number of secondary sites you're going to have 11# postgresql['max_replication_slots'] = 1 # Set this to be the number of Geo secondary nodes if you have more than one 12 13## 14## Disable automatic database migrations temporarily 15## (until PostgreSQL is restarted and listening on the private address). 16## 17gitlab_rails['auto_migrate'] = false

    (有关这些设置的更多详细信息,请参阅配置主服务器

  3. 保存文件并重新配置极狐GitLab 以应用数据库监听更改和复制槽更改:

    shell
    gitlab-ctl reconfigure

    重启 PostgreSQL 以使其更改生效:

    shell
    gitlab-ctl restart postgresql
  4. 在 PostgreSQL 已重启并在私有地址上监听后,重新启用迁移。

    编辑 /etc/gitlab/gitlab.rb 并将配置更改true

    ruby
    gitlab_rails['auto_migrate'] = true

    保存文件并重新配置极狐GitLab:

    shell
    gitlab-ctl reconfigure

步骤 2. 启动复制过程#

现在,我们需要使每个辅助站点监听新主站点上的更改。为此,您需要再次启动复制过程,但这次是针对另一个主站点。所有旧的复制设置都将被覆盖。

现有的辅助站点都有已填充的数据库,因此您可能会看到类似以下消息:

shell
Found data inside the gitlabhq_production database! If you are sure you are in the secondary server, override with --force

确认您位于正确的辅助站点后,使用 --force 启动复制。

使用 `--force` 会导致**该辅助服务器上数据库中的所有现有数据被删除**。

在极狐GitLab Helm Chart 中提升辅助 Geo 集群#

在更新云原生 Geo 部署时,更新辅助 Kubernetes 集群之外的任何节点的过程与非云原生方法没有区别。因此,您可以随时参考在单辅助站点配置中提升辅助 Geo 站点以获取更多信息。

以下部分假设您使用的是 gitlab 命名空间。如果在设置集群时使用了不同的命名空间,则应将 --namespace gitlab 替换为您的命名空间。

步骤 1. 永久禁用主集群#

如果**主站点**离线,**主站点**上可能保存有尚未复制到**辅助站点**的数据。如果您继续,这些数据应被视为已丢失。

如果发生主站点中断,您应尽一切可能避免裂脑情况,即写入可能发生在两个不同的极狐GitLab 实例中,从而使恢复工作复杂化。因此,为了准备故障转移,您必须禁用主站点

  • 如果您有权访问主站点 Kubernetes 集群,请连接到它并禁用极狐GitLab webserviceSidekiq Pod:

    shell
    kubectl --namespace gitlab scale deploy gitlab-geo-webservice-default --replicas=0 kubectl --namespace gitlab scale deploy gitlab-geo-sidekiq-all-in-1-v1 --replicas=0
  • 如果您无权访问主站点 Kubernetes 集群,请将该集群离线并采取任何可用手段阻止其重新上线。 您可能需要:

    • 重新配置负载均衡器。
    • 更改 DNS 记录(例如,将主 DNS 记录指向辅助站点以停止使用主站点)。
    • 停止虚拟服务器。
    • 通过防火墙阻止流量。
    • 撤销主站点的对象存储权限。
    • 物理断开机器。

步骤 2. 提升集群外部的所有辅助站点节点#

如果辅助站点[已暂停](../_index.md#pausing-and-resuming-replication),此操作将执行到最后一个已知状态的时间点恢复。辅助站点暂停期间在主站点上创建的数据将丢失。
  1. 对于使用 Linux 软件包的辅助站点 Kubernetes 集群外部的每个节点(例如 PostgreSQL 或 Gitaly),通过 SSH 登录该节点并运行以下命令之一:

    • 将 Kubernetes 集群外部的辅助站点节点提升为主站点:

      shell
      sudo gitlab-ctl geo promote
    • 在不进一步确认的情况下将 Kubernetes 集群外部的辅助站点节点提升为主站点:

      shell
      sudo gitlab-ctl geo promote --force
  2. 找到 toolbox Pod:

    shell
    kubectl --namespace gitlab get pods -lapp=toolbox
  3. 提升辅助站点:

    shell
    kubectl --namespace gitlab exec -ti gitlab-geo-toolbox-XXX -- gitlab-rake geo:set_secondary_as_primary

    可以提供环境变量来修改任务的行为。可用变量如下:

    名称默认值描述
    ENABLE_SILENT_MODEfalse如果为 true,则在提升前启用静默模式(极狐GitLab 16.4 及更高版本)

步骤 3. 提升辅助集群#

  1. 更新现有集群配置。

    您可以使用 Helm 检索现有配置:

    shell
    helm --namespace gitlab get values gitlab-geo > gitlab.yaml

    现有配置中包含一个 Geo 部分,应类似于:

yaml
1geo: 2 enabled: true 3 role: secondary 4 nodeName: secondary.example.com 5 psql: 6 host: geo-2.db.example.com 7 port: 5431 8 password: 9 secret: geo 10 key: geo-postgresql-password

要将 次要 集群提升为 主要 集群,请将 role: secondary 更新为 role: primary

如果该集群已成为主要站点,则必须删除 geo 下的整个 psql 部分;它指向跟踪数据库。如果保留该配置,应用程序在启动时会将节点识别为次要节点,导致路由注册问题,当使用统一 URL 添加新次要节点时会破坏身份验证。

使用新配置更新集群:

shell
helm upgrade --install --version <current Chart version> gitlab-geo gitlab/gitlab --namespace gitlab -f gitlab.yaml
  1. 验证您可以使用之前次要节点所用的 URL 连接到新提升的主要节点。
  2. 成功!次要节点现已提升为主要节点。

步骤 4.(可选)提升 OpenBao HA 集群#

如果您启用了极狐GitLab 密钥管理器,请在提升 Kubernetes 集群后完成以下步骤以提升 OpenBao 高可用 (HA) 集群。

重启 OpenBao Pod#

在 PostgreSQL 副本提升为主要节点后,重启 OpenBao Pod,使其重新连接到现在的可写数据库:

shell
kubectl --namespace gitlab rollout restart deployment -l app=openbao

(可选)配置 JWT 认证#

如果您已将主域名的 DNS 记录更新为指向次要站点,请跳过此步骤。

要重新配置 JWT 认证,您需要一个 root 令牌。使用恢复密钥生成一个。更多信息,请参阅 从恢复密钥生成 root 令牌

获得 root 令牌后,重新配置 JWT 认证挂载以指向次要域名。 配置详情请参阅 Geo 配置

如有需要,恢复解封密钥#

次要集群上的解封密钥必须与主密钥上的相同,否则 OpenBao 将无法在次要集群上解封存储库。

如果不匹配,请从您的密钥备份中恢复次要集群上的 gitlab-openbao-unseal 密钥,然后重启 OpenBao Pod:

shell
kubectl --namespace gitlab rollout restart deployment -l app=openbao

验证 OpenBao 是否正常工作#

  1. 检查所有 OpenBao Pod 是否正在运行:

    shell
    kubectl --namespace gitlab get pods -l app=openbao
  2. 通过运行使用密钥管理器变量的 CI 流水线来测试 OpenBao 集成。

故障排除#

本节内容已移至另一位置