极狐 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
The 'geo_primary_role' is defined in /etc/gitlab/gitlab-cluster.json as 'true' and overrides the setting in the /etc/gitlab/gitlab.rb The 'geo_secondary_role' is defined in /etc/gitlab/gitlab-cluster.json as 'false' and overrides the setting in the /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>'

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

  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 gitlab: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. 提升集群外部的所有从站点节点#

如果从站点已暂停,此操作会执行到最后一个已知状态的时间点恢复。 从站点暂停期间在主站点上创建的数据将会丢失。

  1. 对于从 Kubernetes 集群外部使用 Linux 软件包的每个节点(例如 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 gitlab:geo:set_secondary_as_primary

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

    名称默认值描述
    ENABLE_SILENT_MODEfalse如果为 true,则在提升前启用静默模式

步骤 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
  2. 验证您可以使用先前用于从站点的 URL 连接到新提升的主站点。

  3. 成功!从站点现已提升为主站点。

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

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

重启 OpenBao Pod#

在 PostgreSQL 副本提升为主站点后,重启 OpenBao Pod,以便它们在数据库现在可写后重新连接到数据库:

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

配置 JWT 身份验证#

更新 DNS 记录,使主域名指向已提升的从站点。OpenBao 不支持故障转移到使用不同域名的从站点。更多信息,请参见 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 集成。

故障排除#

本节已移至另一个位置