配置 Gitaly 集群

要求

Gitaly 集群的最低推荐配置要求:

  • 1 个负载均衡器
  • 1 个 PostgreSQL 服务器(PostgreSQL 11 或更新版本)
  • 3 个 Praefect 节点
  • 3 个 Gitaly 节点(1 个主要节点,2 个次要节点)
note 磁盘要求适用于 Gitaly 节点。
note 如果未在极狐GitLab 中设置,则功能标志会从控制台读取为 false,并且 Praefect 使用其默认值。默认值取决于极狐GitLab 版本。

网络延迟和连接

理想情况下,Gitaly 集群的网络延迟应以个位数毫秒为单位进行测量。延迟对于以下情况尤为重要:

  • Gitaly 节点健康检查。节点必须能够在 1 秒或更快的时间内做出响应。
  • 执行强一致性的参考事务。较低的延迟意味着 Gitaly 节点可以更快地就更改达成一致。

在 Gitaly 节点之间实现可接受的延迟:

  • 在物理网络上通常意味着高带宽、单一位置连接。
  • 云上通常意味着在同一区域内,包括允许跨可用区复制。这些关联是为这种类型的同步而设计的。Gitaly 集群的延迟小于 2 毫秒就足够了。

如果您无法为复制提供低网络延迟(例如,在遥远的位置之间),请考虑 Geo。有关详细信息,请参阅与 Geo 比较

Gitaly 集群组件通过许多路由相互通信。您的防火墙规则必须允许以下条件才能使 Gitaly 集群正常运行:

默认端口 TLS 端口
极狐GitLab Praefect 负载均衡器 2305 3305
Praefect load balancer Praefect 2305 3305
Praefect Gitaly 8075 9999
Praefect 极狐GitLab(内部 API) 80 443
Gitaly 极狐GitLab(内部 API) 80 443
Gitaly Praefect 负载均衡器 2305 3305
Gitaly Praefect 2305 3305
Gitaly Gitaly 8075 9999
note Gitaly 不直接连接到 Praefect。但是,除非 Praefect 节点上的防火墙允许来自 Gitaly 节点的流量,否则从 Gitaly 到 Praefect 负载均衡器的请求可能仍会被阻止。

Praefect 数据库存储

要求相对较低,因为数据库仅包含以下元数据:

  • 仓库所在的位置。
  • 一些排队的工作。

这取决于仓库的数量,但有用的最小值是 5-10 GB,类似于主要的极狐GitLab 应用程序数据库。

设置说明

如果您使用 Omnibus GitLab 包安装的极狐GitLab(强烈推荐),请按照以下步骤操作:

  1. 准备
  2. 配置 Praefect 数据库
  3. 配置 Praefect 代理/路由器
  4. 配置每个 Gitaly 节点(每个 Gitaly 节点一次)
  5. 配置负载均衡器
  6. 更新极狐GitLab 服务器配置
  7. 配置 Grafana

准备

在开始之前,您应该已经有一个可用的极狐GitLab 实例。了解如何安装极狐GitLab

配置 PostgreSQL 服务器。我们建议使用 Omnibus GitLab 附带的 PostgreSQL,并使用它来配置 PostgreSQL 数据库。您可以使用外部 PostgreSQL 服务器(版本 11 或更高版本),但您必须手动进行设置。

通过安装极狐GitLab 准备所有新节点。您需要:

  • 1 个 PostgreSQL 节点
  • 1 个 PgBouncer 节点(可选)
  • 至少 1 个 Praefect 节点(需要最少的存储空间)
  • 3 个 Gitaly 节点(高 CPU、高内存、快速存储)
  • 1 个 GitLab 服务器

您还需要每个节点的 IP/主机地址:

  1. PRAEFECT_LOADBALANCER_HOST:Praefect 负载均衡器的 IP/主机地址
  2. POSTGRESQL_HOST:PostgreSQL 服务器的 IP/主机地址
  3. PGBOUNCER_HOST:PostgreSQL 服务器的 IP/主机地址
  4. PRAEFECT_HOST:Praefect 服务器的 IP/主机地址
  5. GITALY_HOST_*:每个 Gitaly 服务器的 IP/主机地址
  6. GITLAB_HOST:极狐GitLab 服务器的 IP/主机地址

如果您使用任何提供虚拟私有云 (VPC) 的供应商,您可以将每个云实例的私有地址用于 PRAEFECT_HOSTGITALY_HOST_*GITLAB_HOST

Secrets

组件之间的通信使用不同的 secrets 进行保护,如下所述。在开始之前,为每个生成一个唯一的 secrets,并记下它。这使您能够在完成设置过程时将这些占位符令牌替换为安全令牌。

  1. GITLAB_SHELL_SECRET_TOKEN:Git 钩子使用它在接受 Git 推送时向极狐GitLab 发出回调 HTTP API 请求。由于遗留原因,这个 secret 与 Shell 共享。
  2. PRAEFECT_EXTERNAL_TOKEN:托管在您的 Praefect 集群上的仓库只能由携带此令牌的 Gitaly 客户端访问。
  3. PRAEFECT_INTERNAL_TOKEN:此令牌用于您的 Praefect 集群内的复制流量,与 PRAEFECT_EXTERNAL_TOKEN 不同,因为 Gitaly 客户端不能直接访问 Praefect 集群的内部节点;这可能会导致数据丢失。
  4. PRAEFECT_SQL_PASSWORD:这个密码被 Praefect 用来连接 PostgreSQL。
  5. PRAEFECT_SQL_PASSWORD_HASH:Praefect 用户密码的哈希值。使用 gitlab-ctl pg-password-md5 praefect 生成哈希。该命令要求输入 praefect 用户的密码。输入 PRAEFECT_SQL_PASSWORD 明文密码。默认情况下,Praefect 使用 praefect 用户,但您可以更改它。
  6. PGBOUNCER_SQL_PASSWORD_HASH:PgBouncer 用户密码的哈希值。PgBouncer 使用此密码连接到 PostgreSQL。有关更多详细信息,请参阅捆绑的 PgBouncer 文档。

我们会在下面的说明中注明需要这些 secrets 的位置。

note Omnibus GitLab 安装可以使用 gitlab-secrets.json 作为 GITLAB_SHELL_SECRET_TOKEN

PostgreSQL

note 如果使用 Geo,请勿将极狐GitLab 应用程序数据库和 Praefect 数据库存储在同一 PostgreSQL 服务器上。复制状态在极狐GitLab 的每个实例内部,不应被复制。

这些说明有助于设置单个 PostgreSQL 数据库,这会产生单点故障。为避免这种情况,您可以配置自己的集群 PostgreSQL。

可以使用以下选项:

设置 PostgreSQL 会创建空的 Praefect 表。

在同一台服务器上运行极狐GitLab 和 Praefect 数据库

极狐GitLab 应用程序数据库和 Praefect 数据库可以在同一台服务器上运行。但是,在使用 Omnibus GitLab PostgreSQL 时,Praefect 应该有自己的数据库服务器。如果发生故障转移,Praefect 不会意识到并因为它尝试使用的数据库会处于以下情况而开始失败:

  • 不可用。
  • 在只读模式下。

手动数据库设置

要完成此部分,您需要:

  • 一个 Praefect 节点
  • 一个 PostgreSQL 节点(版本 11 或更高版本)
    • 具有管理数据库服务器权限的 PostgreSQL 用户

在本节中,我们配置 PostgreSQL 数据库,可用于外部和 Omnibus 提供的 PostgreSQL 服务器。

要运行以下指令,您可以使用 Praefect 节点,其中 psql 由 Omnibus GitLab (/opt/gitlab/embedded/bin/psql) 安装。如果您使用的是 Omnibus 提供的 PostgreSQL,您可以在 PostgreSQL 节点上使用 gitlab-psql

  1. 创建一个供 Praefect 使用的新用户 praefect

    CREATE ROLE praefect WITH LOGIN PASSWORD 'PRAEFECT_SQL_PASSWORD';
    

    PRAEFECT_SQL_PASSWORD 替换为您在准备步骤中生成的强密码。

  2. 创建一个由 praefect 用户拥有的新数据库 praefect_production

    CREATE DATABASE praefect_production WITH OWNER praefect ENCODING UTF8;
    

要使用 Omnibus 提供的 PgBouncer,您需要执行以下附加步骤。我们强烈建议使用 Omnibus 附带的 PostgreSQL 作为后端。以下说明仅适用于 Omnibus 提供的 PostgreSQL:

  1. 对于 Omnibus 提供的 PgBouncer,您需要使用 praefect 密码的哈希值而不是实际密码:

    ALTER ROLE praefect WITH PASSWORD 'md5<PRAEFECT_SQL_PASSWORD_HASH>';
    

    <PRAEFECT_SQL_PASSWORD_HASH> 替换为您在准备步骤中生成的密码的哈希值。 它以 md5 文字为前缀。

  2. Omnibus 附带的 PgBouncer 配置为使用 auth_query 并使用 pg_shadow_lookup 功能。您需要在 praefect_production 数据库中创建此函数:

    CREATE OR REPLACE FUNCTION public.pg_shadow_lookup(in i_username text, out username text, out password text) RETURNS record AS $$
    BEGIN
        SELECT usename, passwd FROM pg_catalog.pg_shadow
        WHERE usename = i_username INTO username, password;
        RETURN;
    END;
    $$ LANGUAGE plpgsql SECURITY DEFINER;
    
    REVOKE ALL ON FUNCTION public.pg_shadow_lookup(text) FROM public, pgbouncer;
    GRANT EXECUTE ON FUNCTION public.pg_shadow_lookup(text) TO pgbouncer;
    

现在配置了 Praefect 使用的数据库。

您现在可以配置 Praefect 以使用数据库:

praefect['configuration'] = {
   # ...
   database: {
      # ...
      host: POSTGRESQL_HOST,
      port: 5432,
      password: PRAEFECT_SQL_PASSWORD,
      dbname: 'praefect_production',
   }
}

读取分布缓存

通过额外配置 database_direct 设置可以提高 Praefect 性能:

praefect['configuration'] = {
   # ...
   database: {
      # ...
      session_pooled: {
         # ...
         host: POSTGRESQL_HOST,
         port: 5432

         # Use the following to override parameters of direct database connection.
         # Comment out where the parameters are the same for both connections.
         user: 'praefect',
         password: PRAEFECT_SQL_PASSWORD,
         dbname: 'praefect_production',
         # sslmode: '...',
         # sslcert: '...',
         # sslkey: '...',
         # sslrootcert: '...',
      }
   }
}

配置后,此连接将自动用于 SQL LISTEN 功能,并允许 Praefect 接收来自 PostgreSQL 的缓存失效通知。

通过在 Praefect 日志中查找以下日志条目来验证此功能是否正常工作:

reads distribution caching is enabled by configuration

使用 PgBouncer

为了减少 PostgreSQL 资源消耗,我们建议在 PostgreSQL 实例前设置和配置 PgBouncer。但是,不需要 PgBouncer,因为 Praefect 建立的连接数很少。如果您选择使用 PgBouncer,您可以为极狐GitLab 应用程序数据库和 Praefect 数据库使用相同的 PgBouncer 实例。

要在 PostgreSQL 实例前配置 PgBouncer,您必须通过在 Praefect 配置上设置数据库参数将 Praefect 指向 PgBouncer:

praefect['configuration'] = {
   # ...
   database: {
      # ...
      host: PGBOUNCER_HOST,
      port: 6432,
      user: 'praefect',
      password: PRAEFECT_SQL_PASSWORD,
      dbname: 'praefect_production',
      # sslmode: '...',
      # sslcert: '...',
      # sslkey: '...',
      # sslrootcert: '...',
   }
}

Praefect 需要额外连接到支持 LISTEN 功能的 PostgreSQL。对于 PgBouncer,此功能仅适用于 session 池模式(pool_mode = session)。transaction 池模式(pool_mode = transaction)不支持它。

要配置附加连接,您必须:

  • 配置一个新的 PgBouncer 数据库,该数据库使用相同的 PostgreSQL 数据库端点,但具有不同的池模式。也就是说,pool_mode = session
  • 将 Praefect 直接连接到 PostgreSQL 并绕过 PgBouncer。

使用 pool_mode = session 配置新的 PgBouncer 数据库

我们建议使用带有 session 池模式的 PgBouncer。您可以使用捆绑的 PgBouncer 或使用外部 PgBouncer 并手动配置

以下示例使用捆绑的 PgBouncer 并在 PostgreSQL 主机上设置两个独立的连接池,一个在 session 池模式下,另一个在 transaction 池模式下。要使此示例正常工作,您需要按照设置说明中的说明准备 PostgreSQL 服务器:

pgbouncer['databases'] = {
  # Other database configuration including gitlabhq_production
  ...

  praefect_production: {
    host: POSTGRESQL_HOST,
    # Use `pgbouncer` user to connect to database backend.
    user: 'pgbouncer',
    password: PGBOUNCER_SQL_PASSWORD_HASH,
    pool_mode: 'transaction'
  },
  praefect_production_direct: {
    host: POSTGRESQL_HOST,
    # Use `pgbouncer` user to connect to database backend.
    user: 'pgbouncer',
    password: PGBOUNCER_SQL_PASSWORD_HASH,
    dbname: 'praefect_production',
    pool_mode: 'session'
  },

  ...
}

# Allow the praefect user to connect to PgBouncer
pgbouncer['users'] = {
  'praefect': {
    'password': PRAEFECT_SQL_PASSWORD_HASH,
  }
}

praefect_productionpraefect_production_direct 都使用相同的数据库端点(praefect_production),但使用不同的池模式,转换为 PgBouncer 的以下 databases 部分:

[databases]
praefect_production = host=POSTGRESQL_HOST auth_user=pgbouncer pool_mode=transaction
praefect_production_direct = host=POSTGRESQL_HOST auth_user=pgbouncer dbname=praefect_production pool_mode=session

现在您可以将 Praefect 配置为对两个连接都使用 PgBouncer:

praefect['configuration'] = {
   # ...
   database: {
      # ...
      host: PGBOUNCER_HOST,
      port: 6432,
      user: 'praefect',
      # `PRAEFECT_SQL_PASSWORD` is the plain-text password of
      # Praefect user. Not to be confused with `PRAEFECT_SQL_PASSWORD_HASH`.
      password: PRAEFECT_SQL_PASSWORD,
      dbname: 'praefect_production',
      session_pooled: {
         # ...
         dbname: 'praefect_production_direct',
         # There is no need to repeat the following. Parameters of direct
         # database connection will fall back to the values above.
         #
         # host: PGBOUNCER_HOST,
         # port: 6432,
         # user: 'praefect',
         # password: PRAEFECT_SQL_PASSWORD,
      },
   },
}

使用此配置,Praefect 将 PgBouncer 用于两种连接类型。

note Omnibus GitLab 处理身份验证要求(使用 auth_query),但如果您手动准备数据库并配置外部 PgBouncer,则必须在 PgBouncer 使用的文件中包含 praefect 用户及其密码。例如,设置了 auth_file 配置选项,则为 userlist.txt。有关更多详细信息,请参阅 PgBouncer 文档。

配置 Praefect 以直接连接到 PostgreSQL

作为使用 session 池模式配置 PgBouncer 的替代方法,可以将 Praefect 配置为使用不同的连接参数来直接访问 PostgreSQL。这是支持 LISTEN 功能的连接。

绕过 PgBouncer 直接连接 PostgreSQL 的 Praefect 配置示例:

praefect['configuration'] = {
   # ...
   database: {
      # ...
      session_pooled: {
         # ...
         host: POSTGRESQL_HOST,
         port: 5432,

         # Use the following to override parameters of direct database connection.
         # Comment out where the parameters are the same for both connections.
         #
         user: 'praefect',
         password: PRAEFECT_SQL_PASSWORD,
         dbname: 'praefect_production',
         # sslmode: '...',
         # sslcert: '...',
         # sslkey: '...',
         # sslrootcert: '...',
      },
   },
}

Praefect

引入于 13.4 版本,Praefect 节点不能再被指定为 primary

如果有多个 Praefect 节点:

  1. 指定一个节点为部署节点,按照以下步骤进行配置。
  2. 为每个附加节点完成以下步骤。

要完成本节,您需要一个已配置的 PostgreSQL 服务器,包括:

caution Praefect 应该在专用节点上运行。不要在应用服务器或 Gitaly 节点上运行 Praefect。

Praefect 节点上:

  1. 通过编辑 /etc/gitlab/gitlab.rb 禁用所有其他服务:
   # Avoid running unnecessary services on the Praefect server
   gitaly['enable'] = false
   postgresql['enable'] = false
   redis['enable'] = false
   nginx['enable'] = false
   puma['enable'] = false
   sidekiq['enable'] = false
   gitlab_workhorse['enable'] = false
   prometheus['enable'] = false
   alertmanager['enable'] = false
   grafana['enable'] = false
   gitlab_exporter['enable'] = false
   gitlab_kas['enable'] = false

   # Enable only the Praefect service
   praefect['enable'] = true

   # Prevent database migrations from running on upgrade automatically
   praefect['auto_migrate'] = false
   gitlab_rails['auto_migrate'] = false
  1. 通过编辑 /etc/gitlab/gitlab.rbPraefect 配置为监听网络接口:

    praefect['configuration'] = {
       # ...
       listen_addr: '0.0.0.0:2305',
    }
    
  2. 通过编辑 /etc/gitlab/gitlab.rb 配置 Prometheus 指标:

    praefect['configuration'] = {
       # ...
       #
       # Enable Prometheus metrics access to Praefect. You must use firewalls
       # to restrict access to this address/port.
       # The default metrics endpoint is /metrics
       prometheus_listen_addr: '0.0.0.0:9652',
       # Some metrics run queries against the database. Enabling separate database metrics allows
       # these metrics to be collected when the metrics are
       # scraped on a separate /db_metrics endpoint.
       prometheus_exclude_database_from_default_metrics: true,
    }
    
  3. 通过编辑 /etc/gitlab/gitlab.rbPraefect 配置一个验证令牌。集群外的客户端(如 Shell)需要此功能才能与 Praefect 集群通信:

    praefect['configuration'] = {
       # ...
       auth: {
          # ...
          token: 'PRAEFECT_EXTERNAL_TOKEN',
       },
    }
    
  4. Praefect 配置为连接到 PostgreSQL 数据库。我们强烈建议也使用 PgBouncer

    如果要使用 TLS 客户端证书,可以使用以下选项:

    praefect['configuration'] = {
       # ...
       database: {
          # ...
          #
          # Connect to PostgreSQL using a TLS client certificate
          # sslcert: '/path/to/client-cert',
          # sslkey: '/path/to/client-key',
          #
          # Trust a custom certificate authority
          # sslrootcert: '/path/to/rootcert',
       },
    }
    

    默认情况下,Praefect 拒绝与 PostgreSQL 建立未加密的连接。 您可以通过取消注释以下行来覆盖它:

    praefect['configuration'] = {
       # ...
       database: {
          # ...
          # sslmode: 'disable',
       },
    }
    
  5. 通过编辑 /etc/gitlab/gitlab.rb 配置 Praefect 集群以连接到集群中的每个 Gitaly 节点。

    虚拟存储的名称必须与极狐GitLab 配置中配置的存储名称匹配。在后面的步骤中,我们将存储名称配置为 default,因此我们在这里也使用 default。该集群具有三个 Gitaly 节点:gitaly-1gitaly-2gitaly-3,它们旨在作为彼此的副本。

    caution 如果您在已存在的名为 default 的存储上拥有数据,则应使用另一个名称配置虚拟存储,然后将数据迁移到 Gitaly 集群存储

    PRAEFECT_INTERNAL_TOKEN 替换为强密钥,Praefect 在与集群中的 Gitaly 节点通信时使用该密钥。此令牌与 PRAEFECT_EXTERNAL_TOKEN 不同。

    GITALY_HOST_* 替换为每个 Gitaly 节点的 IP 或主机地址。

    可以将更多的 Gitaly 节点添加到集群中以增加副本的数量。还可以为非常大的极狐GitLab 实例添加更多集群。

    note 将其他 Gitaly 节点添加到虚拟存储时,该虚拟存储中的所有存储名称必须是唯一的。此外,在 Praefect 配置中引用的所有 Gitaly 节点地址都必须是唯一的。
    # Name of storage hash must match storage name in git_data_dirs on GitLab
    # server ('default') and in git_data_dirs on Gitaly nodes ('gitaly-1')
    praefect['configuration'] = {
       # ...
       virtual_storage: [
          {
             # ...
             name: 'default',
             node: [
                {
                   storage: 'gitaly-1',
                   address: 'tcp://GITALY_HOST_1:8075',
                   token: 'PRAEFECT_INTERNAL_TOKEN'
                },
                {
                   storage: 'gitaly-2',
                   address: 'tcp://GITALY_HOST_2:8075',
                   token: 'PRAEFECT_INTERNAL_TOKEN'
                },
                {
                   storage: 'gitaly-3',
                   address: 'tcp://GITALY_HOST_3:8075',
                   token: 'PRAEFECT_INTERNAL_TOKEN'
                },
             ],
          },
       ],
    }
    
    note 在 13.8 及更早版本中,Gitaly 节点直接配置在虚拟存储下,而不是在 nodes 键下。
  6. 在 13.1 及更高版本中引入,启用读取分布

  7. 将更改保存到 /etc/gitlab/gitlab.rb重新配置 Praefect

    gitlab-ctl reconfigure
    
  8. 对于:

    • “部署节点”:
      1. 通过在 /etc/gitlab/gitlab.rb 中设置 praefect['auto_migrate'] = true 再次启用 Praefect 数据库自动迁移。
      2. 要确保数据库迁移仅在重新配置期间运行而不是在升级时自动运行,请运行:

        sudo touch /etc/gitlab/skip-auto-reconfigure
        
    • 其他节点,您可以保持设置不变。虽然 /etc/gitlab/skip-auto-reconfigure 不是必需的,但您可能需要设置它以防止极狐GitLab 在运行诸如 apt-get update 之类的命令时自动运行重新配置。这样,可以完成任何其他配置更改,然后可以手动运行重新配置。
  9. 将更改保存到 /etc/gitlab/gitlab.rb重新配置 Praefect

    gitlab-ctl reconfigure
    
  10. 为确保 Praefect 已更新其 Prometheus 监听地址,重启 Praefect

    gitlab-ctl restart praefect
    
  11. 验证 Praefect 是否可以访问 PostgreSQL:

    sudo -u git /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml sql-ping
    

    如果检查失败,请确保您已正确执行这些步骤。如果您编辑了 /etc/gitlab/gitlab.rb,记得在尝试 sql-ping 命令之前再次运行 sudo gitlab-ctl reconfigure

启用 TLS 支持

引入于 13.2 版本。

Praefect 支持 TLS 加密。要与侦听安全连接的 Praefect 实例通信,您必须:

  • 确保为 TLS 配置 Gitaly,并在极狐GitLab 配置中相应存储条目的 gitaly_address 中使用 tls:// URL 方案。
  • 带上您自己的证书,因为这不是自动提供的。每个 Praefect 服务器对应的证书必须安装在该 Praefect 服务器上。

此外,证书或其证书颁发机构必须按照极狐GitLab 自定义证书配置中描述的过程(并在下面重复)安装在所有 Gitaly 服务器和与其通信的所有 Praefect 客户端上。

请注意以下事项:

  • 证书必须指定您用于访问 Praefect 服务器的地址。 您必须将主机名或 IP 地址作为主题备用名称添加到证书中。
  • 在启用 Gitaly TLS 从命令行运行 Praefect 子命令(例如 dial-nodeslist-untracked-repositories)时,您必须设置 SSL_CERT_DIRSSL_CERT_FILE 环境变量,以便 Gitaly 证书受信任。例如:

     sudo SSL_CERT_DIR=/etc/gitlab/trusted-certs /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml dial-nodes
    
  • 您可以同时使用未加密的监听地址listen_addr 和加密的监听地址tls_listen_addr 配置 Praefect 服务器。如有必要,这使您可以从未加密流量逐渐过渡到加密流量。

    要禁用未加密的侦听器,请设置:

    praefect['configuration'] = {
      # ...
      listen_addr: nil,
    }
    

使用 TLS 配置 Praefect:

Omnibus GitLab 实例

  1. 为 Praefect 服务器创建证书。

  2. 在 Praefect 服务器上,创建 /etc/gitlab/ssl 目录并将您的密钥和证书复制到那里:

    sudo mkdir -p /etc/gitlab/ssl
    sudo chmod 755 /etc/gitlab/ssl
    sudo cp key.pem cert.pem /etc/gitlab/ssl/
    sudo chmod 644 key.pem cert.pem
    
  3. 编辑 /etc/gitlab/gitlab.rb 并添加:

    praefect['configuration'] = {
       # ...
       tls_listen_addr: '0.0.0.0:3305',
       tls: {
          # ...
          certificate_path: '/etc/gitlab/ssl/cert.pem',
          key_path: '/etc/gitlab/ssl/key.pem',
       },
    }
    
  4. 保存文件并重新配置

  5. 在 Praefect 客户端(包括每个 Gitaly 服务器)上,将证书或其证书颁发机构复制到 /etc/gitlab/trusted-certs 中:

    sudo cp cert.pem /etc/gitlab/trusted-certs/
    
  6. 在 Praefect 客户端(Gitaly 服务器除外)上,编辑 /etc/gitlab/gitlab.rb 中的 git_data_dirs,如下所示:

    git_data_dirs({
      "default" => {
        "gitaly_address" => 'tls://PRAEFECT_LOADBALANCER_HOST:3305',
        "gitaly_token" => 'PRAEFECT_EXTERNAL_TOKEN'
      }
    })
    
  7. 保存文件并重新配置极狐GitLab

源安装

  1. 为 Praefect 服务器创建证书。
  2. 在 Praefect 服务器上,创建 /etc/gitlab/ssl 目录并将您的密钥和证书复制到那里:

    sudo mkdir -p /etc/gitlab/ssl
    sudo chmod 755 /etc/gitlab/ssl
    sudo cp key.pem cert.pem /etc/gitlab/ssl/
    sudo chmod 644 key.pem cert.pem
    
  3. 在 Praefect 客户端(包括每个 Gitaly 服务器)上,将证书或其证书颁发机构复制到系统受信任的证书中:

    sudo cp cert.pem /usr/local/share/ca-certificates/praefect.crt
    sudo update-ca-certificates
    
  4. 在 Praefect 客户端(Gitaly 服务器除外)上,编辑 /home/git/gitlab/config/gitlab.yml 中的 storages,如下所示:

    gitlab:
      repositories:
        storages:
          default:
            gitaly_address: tls://PRAEFECT_LOADBALANCER_HOST:3305
            path: /some/local/path
    
    note /some/local/path 应设置为存在的本地文件夹,但此文件夹中不存储任何数据。
  5. 保存文件并重新启动极狐GitLab
  6. 将所有 Praefect 服务器证书或其证书颁发机构复制到每个 Gitaly 服务器上的系统信任证书,以便 Praefect 服务器在 Gitaly 服务器调用时信任该证书:

    sudo cp cert.pem /usr/local/share/ca-certificates/praefect.crt
    sudo update-ca-certificates
    
  7. 编辑 /home/git/praefect/config.toml 并添加:

    tls_listen_addr = '0.0.0.0:3305'
    
    [tls]
    certificate_path = '/etc/gitlab/ssl/cert.pem'
    key_path = '/etc/gitlab/ssl/key.pem'
    
  8. 保存文件并重新启动极狐GitLab

Gitaly

note 每个 Gitaly 节点完成这些步骤。

要完成此部分,您需要:

  • 配置的 Praefect 节点
  • 3 台(或更多)服务器,安装极狐GitLab,配置为 Gitaly 节点。这些节点应该是专用节点,不要在这些节点上运行其他服务。

每个分配给 Praefect 集群的 Gitaly 服务器都需要进行配置。配置与普通的独立 Gitaly 服务器相同,除了:

  • 存储名称暴露给 Praefect,而不是极狐GitLab
  • Secrets 令牌与 Praefect 共享,而不是极狐GitLab

Praefect 集群中所有 Gitaly 节点的配置可以相同,因为我们依靠 Praefect 来正确路由操作。

应特别注意:

  • 本节配置的 gitaly['auth_token'] 必须与 Praefect 节点上的 praefect['configuration'][:virtual_storage][<index>][:node][<index>][:token] 下的 token 值匹配。这是在上一节中设置的。本文档始终使用占位符 PRAEFECT_INTERNAL_TOKEN
  • 本节配置的 git_data_dirs 中的存储名称必须与 Praefect 节点上的 praefect['configuration'][:virtual_storage] 下的存储名称匹配。这是在上一节中设置的。本文档使用 gitaly-1gitaly-2gitaly-3 作为 Gitaly 存储名称。
  1. SSH 进入 Gitaly 节点并以 root 身份登录:

    sudo -i
    
  2. 通过编辑 /etc/gitlab/gitlab.rb 禁用所有其他服务:

    # Disable all other services on the Praefect node
    postgresql['enable'] = false
    redis['enable'] = false
    nginx['enable'] = false
    grafana['enable'] = false
    puma['enable'] = false
    sidekiq['enable'] = false
    gitlab_workhorse['enable'] = false
    prometheus_monitoring['enable'] = false
    gitlab_kas['enable'] = false
    
    # Enable only the Gitaly service
    gitaly['enable'] = true
    
    # Enable Prometheus if needed
    prometheus['enable'] = true
    
    # Disable database migrations to prevent database connections during 'gitlab-ctl reconfigure'
    gitlab_rails['auto_migrate'] = false
    
  3. 通过编辑 /etc/gitlab/gitlab.rbGitaly 配置为监听网络接口:

    # Make Gitaly accept connections on all network interfaces.
    # Use firewalls to restrict access to this address/port.
    gitaly['listen_addr'] = '0.0.0.0:8075'
    
    # Enable Prometheus metrics access to Gitaly. You must use firewalls
    # to restrict access to this address/port.
    gitaly['prometheus_listen_addr'] = '0.0.0.0:9236'
    
  4. 通过编辑 /etc/gitlab/gitlab.rbGitaly 配置一个强大的 auth_token。这是客户端与此 Gitaly 节点通信所必需的。通常,此令牌对于所有 Gitaly 节点都是相同的。

    gitaly['auth_token'] = 'PRAEFECT_INTERNAL_TOKEN'
    
  5. 配置 git push 操作所需的 Shell secrets 令牌。 任何一个:

    • 方法一:

      1. 从 Gitaly 客户端复制 /etc/gitlab/gitlab-secrets.json 到 Gitaly 服务器和任何其他 Gitaly 客户端上的相同路径。
      2. 在 Gitaly 服务器上重新配置极狐GitLab
    • 方法二:

      1. 编辑 /etc/gitlab/gitlab.rb
      2. 用真正的 secret 替换 GITLAB_SHELL_SECRET_TOKEN

        gitlab_shell['secret_token'] = 'GITLAB_SHELL_SECRET_TOKEN'
        
  6. 配置一个 internal_api_urlgit push 操作也需要它:

    # Configure the gitlab-shell API callback URL. Without this, `git push` will
    # fail. This can be your front door GitLab URL or an internal load balancer.
    # Examples: 'https://gitlab.example.com', 'http://10.0.2.2'
    gitlab_rails['internal_api_url'] = 'https://gitlab.example.com'
    
  7. 通过在 /etc/gitlab/gitlab.rb 中设置 git_data_dirs 来配置 Git 数据的存储位置。每个 Gitaly 节点都应该有一个唯一的存储名称(例如 gitaly-1)。

    与其为每个 Gitaly 节点单独配置 git_data_dirs,通常更容易在每个 Gitaly 节点上包含所有 Gitaly 节点的配置。这是支持的,因为 Praefect virtual_storages 配置将每个存储名称(例如 gitaly-1)映射到特定节点,并相应地路由请求。这意味着您的 fleet 中的每个 Gitaly 节点都可以共享相同的配置。

    # You can include the data dirs for all nodes in the same config, because
    # Praefect will only route requests according to the addresses provided in the
    # prior step.
    git_data_dirs({
      "gitaly-1" => {
        "path" => "/var/opt/gitlab/git-data"
      },
      "gitaly-2" => {
        "path" => "/var/opt/gitlab/git-data"
      },
      "gitaly-3" => {
        "path" => "/var/opt/gitlab/git-data"
      }
    })
    
  8. 将更改保存到 /etc/gitlab/gitlab.rb重新配置 Gitaly

    gitlab-ctl reconfigure
    
  9. 为确保 Gitaly 已更新其 Prometheus 监听地址,重启 Gitaly

    gitlab-ctl restart gitaly
    

每个 Gitaly 节点都必须完成上述步骤!

配置完所有 Gitaly 节点后,运行 Praefect 连接检查程序以验证 Praefect 可以连接到 Praefect 配置中的所有 Gitaly 服务器。

  1. SSH 进入每个 Praefect 节点并运行 Praefect 连接检查器:

    sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml dial-nodes
    

Load Balancer

在容错 Gitaly 配置中,需要负载均衡器将内部流量从极狐GitLab 应用程序路由到 Praefect 节点。关于使用哪个负载均衡器或确切配置的细节超出了极狐GitLab 文档的范围。

note 除了极狐GitLab 节点之外,负载均衡器必须配置为接受来自 Gitaly 节点的流量。由 gitaly-ruby sidecar 进程处理的一些请求调用主 Gitaly 进程。gitaly-ruby 使用极狐GitLab 服务器的 git_data_dirs 设置中设置的 Gitaly 地址来建立此连接。
note 我们推荐等效的 HAProxy leastconn 负载均衡策略,因为长时间运行的操作(例如,克隆)会使某些连接长时间保持打开状态。
LB 端口 后端端口 协议
2305 2305 TCP

极狐GitLab

要完成此部分,您需要:

Praefect 集群需要作为存储位置公开给极狐GitLab 应用程序。这是通过更新 git_data_dirs 来完成的。

应特别注意:

  • 在本节中添加到 git_data_dirs 的存储名称必须与 Praefect 节点上的 praefect['configuration'][:virtual_storage] 下的存储名称匹配。这是在本指南的 Praefect 部分中设置的。本文档使用 default 作为 Praefect 存储名称。
  1. SSH 进入极狐GitLab 节点并以 root 身份登录:

    sudo -i
    
  2. 配置 external_url 以便极狐GitLab 可以通过编辑 /etc/gitlab/gitlab.rb 通过适当的端点访问来提供文件:

    您需要将 GITLAB_SERVER_URL 替换为当前极狐GitLab 实例所服务的真实外部 URL:

    external_url 'GITLAB_SERVER_URL'
    
  3. 禁用在极狐GitLab 主机上运行的默认 Gitaly 服务。不需要它,因为极狐GitLab 连接到配置的集群。

    caution 如果您将现有数据存储在默认 Gitaly 存储上,则应首先将数据迁移到 Gitaly 集群存储。
    gitaly['enable'] = false
    
  4. 通过编辑 /etc/gitlab/gitlab.rb 将 Praefect 集群添加为存储位置。

    您需要更换:

    • PRAEFECT_LOADBALANCER_HOST 带有负载均衡器的 IP 地址或主机名。
    • PRAEFECT_EXTERNAL_TOKEN 带有真正的 secret。

    如果您使用 TLS:

    • gitaly_address 应该以 tls:// 开头。
    • 端口应更改为 3305
    git_data_dirs({
      "default" => {
        "gitaly_address" => "tcp://PRAEFECT_LOADBALANCER_HOST:2305",
        "gitaly_token" => 'PRAEFECT_EXTERNAL_TOKEN'
      }
    })
    
  5. 配置 Shell secret 令牌,以便在 git push 期间来自 Gitaly 节点的回调得到正确身份验证。

    • 方法一:

      1. /etc/gitlab/gitlab-secrets.json 从 Gitaly 客户端复制到 Gitaly 服务器和任何其他 Gitaly 客户端上的相同路径。
      2. 在 Gitaly 服务器上重新配置极狐GitLab
    • 方法二:

      1. 编辑 /etc/gitlab/gitlab.rb
      2. 用真正的 secret 替换 GITLAB_SHELL_SECRET_TOKEN

        gitlab_shell['secret_token'] = 'GITLAB_SHELL_SECRET_TOKEN'
        
  6. 通过编辑 /etc/gitlab/gitlab.rb 添加 Prometheus 监控设置。如果在其他节点上启用了 Prometheus,请改为在该节点上进行编辑。

    • 您需要将 PRAEFECT_HOST 替换为 Praefect 节点的 IP 地址或主机名
    • 您需要将 GITALY_HOST_* 替换为每个 Gitaly 节点的 IP 地址或主机名
    prometheus['scrape_configs'] = [
      {
        'job_name' => 'praefect',
        'static_configs' => [
          'targets' => [
            'PRAEFECT_HOST:9652', # praefect-1
            'PRAEFECT_HOST:9652', # praefect-2
            'PRAEFECT_HOST:9652', # praefect-3
          ]
        ]
      },
      {
        'job_name' => 'praefect-gitaly',
        'static_configs' => [
          'targets' => [
            'GITALY_HOST_1:9236', # gitaly-1
            'GITALY_HOST_2:9236', # gitaly-2
            'GITALY_HOST_3:9236', # gitaly-3
          ]
        ]
      }
    ]
    
  7. 将更改保存到 /etc/gitlab/gitlab.rb重新配置极狐GitLab

    gitlab-ctl reconfigure
    
  8. 在每个 Gitaly 节点上验证 Git Hook 可以访问 GitLab。在每个 Gitaly 节点上运行:
    • 对于 15.3 及更高版本,运行 sudo /opt/gitlab/embedded/bin/gitaly check /var/opt/gitlab/gitaly/config.toml
    • 对于 15.2 及更早版本,运行 sudo /opt/gitlab/embedded/bin/gitaly-hooks check /var/opt/gitlab/gitaly/config.toml
  9. 验证极狐GitLab 是否可以访问 Praefect:

    gitlab-rake gitlab:gitaly:check
    
  10. 检查 Praefect 存储是否已配置为存储新仓库:

    1. 在左侧边栏中,选择 搜索或转到
    2. 选择 管理中心
    3. 在左侧边栏中,选择 设置 > 仓库
    4. 展开 仓库存储 部分。

    按照本指南,default 存储的权重应为 100,存储所有新仓库。

  11. 通过创建一个新项目来验证一切是否正常。 选中使用 README 初始化仓库框,以便仓库中有已查看的内容。如果项目已创建,并且您可以看到 README 文件,那么它可以工作!

对现有极狐GitLab 实例使用 TCP

将 Gitaly 集群添加到现有 Gitaly 实例时,现有 Gitaly 存储必须侦听 TCP/TLS。如果未指定 gitaly_address,则使用 Unix 套接字,这会阻止与集群的通信。

例如:

git_data_dirs({
  'default' => { 'gitaly_address' => 'tcp://old-gitaly.internal:8075' },
  'cluster' => {
    'gitaly_address' => 'tls://<PRAEFECT_LOADBALANCER_HOST>:3305',
    'gitaly_token' => '<praefect_external_token>'
  }
})

Grafana

Grafana 包含在极狐GitLab 中,可用于监控您的 Praefect 集群。有关详细文档,请参阅 Grafana Dashboard Service

快速开始:

  1. SSH 进入极狐GitLab 节点(或启用 Grafana 的任何节点)并以 root 身份登录:

    sudo -i
    
  2. 通过编辑 /etc/gitlab/gitlab.rb 启用 Grafana 登录表单。

    grafana['disable_login_form'] = false
    
  3. 将更改保存到 /etc/gitlab/gitlab.rb重新配置极狐GitLab

    gitlab-ctl reconfigure
    
  4. 设置 Grafana 管理员密码。此命令提示您输入新密码:

    gitlab-ctl set-grafana-password
    
  5. 在 Web 浏览器中,打开极狐GitLab 服务器上的 /-/grafana(例如 https://gitlab.example.com/-/grafana)。

    使用您设置的密码和用户名 admin 登录。

  6. 转到 Explore 并查询 gitlab_build_info 以验证您是否从所有机器获取指标。

恭喜!您已经配置了一个可观察的容错 Praefect 集群。

配置复制系数

caution 可配置的复制系数需要使用特定于仓库的主节点

Praefect 支持在每个仓库的基础上配置复制系数,方法是分配特定的存储节点来托管仓库。

Praefect 不存储实际的复制系数,但会分配足够的存储空间来托管仓库,以便满足所需的复制系数。如果稍后从虚拟存储中删除存储节点,则分配给存储的仓库的复制系数会相应降低。

您可以配置:

  • 应用于新创建的仓库的每个虚拟存储的默认复制系数。配置被添加到 /etc/gitlab/gitlab.rb 文件中:

     praefect['configuration'] = {
        # ...
        virtual_storage: [
           {
              # ...
              name: 'default',
              default_replication_factor: 1,
           },
        ],
     }
    
  • 使用 set-replication-factor 子命令的现有仓库的复制系数。set-replication-factor 根据需要自动分配或取消分配随机存储节点以达到所需的复制系数。仓库的主节点始终首先分配,并且永远不会取消分配。

    sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml set-replication-factor -virtual-storage <virtual-storage> -repository <relative-path> -replication-factor <replication-factor>
    
    • -virtual-storage 是仓库所在的虚拟存储。
    • -repository 是仓库在存储中的相对路径。
    • -replication-factor 是仓库的所需复制系数。最小值为 1,因为主节点需要仓库的副本。最大复制系数是虚拟存储中的存储数量。

    成功后,将打印分配的主机存储。例如:

    $ sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml set-replication-factor -virtual-storage default -repository @hashed/3f/db/3fdba35f04dc8c462986c992bcf875546257113072a909c162f7e470e581e278.git -replication-factor 2
    
    current assignments: gitaly-1, gitaly-2
    

如果 default_replication_factor 未设置,则仓库总是在 virtual_storages 中定义的每个节点上复制。如果将新节点引入虚拟存储,则新仓库和现有仓库都会自动复制到该节点。

仓库存储建议

所需存储的大小可能因实例而异,并且取决于设置的复制系数。您可能希望包括实现仓库存储冗余。

对于复制系数:

  • 1:Gitaly 和 Gitaly 集群的存储要求大致相同。
  • 大于 1:所需存储量为 used space * replication factorused space 应包括任何计划的未来增长。

仓库验证

引入于 15.0 版本。

Praefect 将有关仓库的元数据存储在数据库中。如果未通过 Praefect 在磁盘上修改仓库,则元数据可能会变得不准确。因为元数据用于复制和路由决策,所以任何不准确都可能导致问题。Praefect 包含一个后台 worker,它定期根据磁盘上的实际状态验证元数据。

  1. 挑选一批副本在健康存储上进行验证。副本要么未经验证,要么已超过配置的验证间隔。从未验证过的副本优先,其次是自上次成功验证以来按最长时间排序的其他副本。
  2. 检查副本是否存在于各自的存储上。如果:
    • 副本存在,更新其最后一次成功验证时间。
    • 副本不存在,删除其元数据记录。
    • 检查失败,当下一个 worker 使更多工作出队列时,将再次提取副本进行验证。

Worker 在它要验证的每个副本上获得一个独占的验证租约,避免了多个 worker 同时验证同一个副本。Worker 在完成检查后释放租约。 Praefect 包含一个后台 goroutine,当 worker 因某种原因终止而不释放租约时,它每 10 秒释放一次旧租约。

Worker 在执行之前记录每个元数据删除。perform_deletions 键指示是否实际删除了无效的元数据记录。例如:

{
  "level": "info",
  "msg": "removing metadata records of non-existent replicas",
  "perform_deletions": false,
  "replicas": {
    "default": {
      "@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.git": [
        "praefect-internal-0"
      ]
    }
  }
}

配置验证 worker

Worker 默认启用,每 7 天验证一次元数据记录。验证间隔可以使用任何有效的 Go 持续时间字符串进行配置。

每三天验证一次元数据:

praefect['configuration'] = {
   # ...
   background_verification: {
      # ...
      verification_interval: '72h',
   },
}

0 及以下的值禁用后台验证程序。

praefect['configuration'] = {
   # ...
   background_verification: {
      # ...
      verification_interval: '0',
   },
}

启用删除

caution 由于仓库重命名的竞争条件可能导致不正确的删除,因此在 15.9 之前的版本中,默认情况下禁用删除。这在 Geo 实例中尤为突出,因为 Geo 比没有 Geo 的实例执行更多的重命名。从 15.0 到 15.5 版本,仅当启用了 gitaly_praefect_generated_replica_paths 功能标志时,才应启用删除。15.6 版本中删除了功能标志,使删除始终可以安全启用。

默认情况下,worker 会删除无效的元数据记录。它还会记录已删除的记录,并输出 Prometheus 指标。

您可以通过以下方式启用删除无效元数据记录:

praefect['configuration'] = {
   # ...
   background_verification: {
      # ...
      delete_invalid_records: false,
   },
}

手动优先验证

您可以在某些副本的下一个计划验证时间之前优先验证它们。这可能在磁盘故障后需要,例如,当管理员知道磁盘内容可能已更改时。Praefect 最终会再次验证副本,但用户可能会在此期间遇到错误。

要手动优先考虑某些副本的重新验证,请使用 praefect verify 子命令。该子命令将副本标记为未验证。未验证的副本由后台验证 worker 优先处理。必须为要验证的副本启用验证 worker。

优先验证特定仓库的副本:

sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml verify -repository-id=<repository-id>

优先验证存储在虚拟存储上的所有副本:

sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml verify -virtual-storage=<virtual-storage>

优先验证存储在存储中的所有副本:

sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml verify -virtual-storage=<virtual-storage> -storage=<storage>

输出包括标记为未验证的副本数。

自动故障转移和主要选举策略

Praefect 定期检查每个 Gitaly 节点的运行状况。

我们建议使用特定于仓库的主节点。这是 14.0 版本中唯一可用的选举策略。

特定于仓库的主节点

  • 引入于极狐GitLab 13.12,当 Praefect 启动或集群对 Gitaly 节点健康状况的共识发生变化时进行主要选举。
  • 变更于极狐GitLab 14.1,缓慢进行主要选举。

Gitaly Cluster 为每个仓库单独选择一个主 Gitaly 节点。结合可配置的复制因子,您可以水平扩展存储容量并在 Gitaly 节点之间分配写入负载。

主要选举是缓慢进行的。如果当前主节点运行状况不佳,Praefect 不会立即选举新的主节点。如果当前主节点不可用时必须处理请求,则会选择新的主节点。

一个有效的主节点候选者是一个 Gitaly 节点:

  • 那么它是健康的。如果 >=50% Praefect 节点在前十秒内成功检查了 Gitaly 节点的健康状况,则认为 Gitaly 节点是健康的。
  • 它拥有完全最新的仓库副本。

如果有多个候选主节点,Praefect:

  • 随机选择其中之一。
  • 优先提升分配用于托管仓库的 Gitaly 节点。如果没有指定的 Gitaly 节点可以选择为主节点,Praefect 可能会临时选择一个未指定的节点。当一个可用时,未分配的主节点将降级以支持已分配的主节点。

如果仓库没有有效的主要候选者:

  • 不健康的主节点被降级,并且仓库没有主节点。
  • 需要主节点的操作会失败,直到成功选出主节点。

迁移到特定于仓库的主要 Gitaly 节点

新的 Gitaly 集群可以立即开始使用 per_repository 选举策略。

要迁移现有集群:

  1. Praefect 节点历来不会保留集群上存储的每个仓库的数据库记录。当配置 per_repository 选举策略时,Praefect 期望拥有每个存储库的数据库记录。13.6 及更高版本中包含后台数据库迁移,用于为仓库创建任何缺失的数据库记录。在迁移之前,请检查 Praefect 的日志以验证数据库迁移是否已运行。

    检查 Praefect 的日志中是否有 repository importer finished 消息。virtual_storages 字段包含虚拟存储的名称以及它们是否创建了任何缺失的数据库记录。

    例如,default 虚拟存储已成功迁移:

    {"level":"info","msg":"repository importer finished","pid":19752,"time":"2021-04-28T11:41:36.743Z","virtual_storages":{"default":true}}
    

    如果虚拟存储没有成功迁移,它旁边会显示 false

    {"level":"info","msg":"repository importer finished","pid":19752,"time":"2021-04-28T11:41:36.743Z","virtual_storages":{"default":false}}
    

    数据库迁移在 Praefect 启动时运行。如果数据库迁移不成功,您可以重新启动 Praefect 节点以重新尝试。

  2. 并行运行两种不同的选举策略可能会导致脑裂,不同的 Praefect 节点认为仓库具有不同的初选。这可以避免:

    • 如果可以接受短停机时间:

      1. 在更改选举策略之前关闭所有 Praefect 节点。通过在 Praefect 节点上运行 gitlab-ctl stop praefect 来做到这一点。

      2. 在 Praefect 节点上,使用 praefect['failover_election_strategy'] = 'per_repository'/etc/gitlab/gitlab.rb 中配置选举策略。

      3. 运行 gitlab-ctl reconfigure && gitlab-ctl start 重新配置并启动 Praefects 节点。

    • 如果停机时间不可接受:

      1. 确定哪个 Gitaly 节点是当前主节点。

      2. 从所有 Praefect 节点上的 /etc/gitlab/gitlab.rb 中的虚拟存储配置中注释掉次要 Gitaly 节点。这确保了只配置了一个 Gitaly 节点,导致两种选举策略都选择同一个 Gitaly 节点作为主节点。

      3. 在所有 Praefect 节点上运行 gitlab-ctl reconfigure。等到所有 Praefect 进程都重新启动并且旧进程退出。这最多可能需要一分钟。

      4. 在所有 Praefect 节点上,在 /etc/gitlab/gitlab.rb 中使用 praefect['failover_election_strategy'] = 'per_repository' 配置选举策略。

      5. 在所有 Praefect 节点上运行 gitlab-ctl reconfigure。等到所有 Praefect 进程都重新启动并且旧进程退出。这最多可能需要一分钟。

      6. 在所有 Praefect 节点上取消注释在前面步骤中注释掉的次要 Gitaly 节点配置。

      7. 在所有 Praefect 节点上运行 gitlab-ctl reconfigure,重新配置和重新启动 Praefect 进程。