Geo 数据库复制

本文档描述了将极狐GitLab 主数据库复制到次要站点的数据库所需的最少步骤。您可能必须根据包括数据库设置和大小在内的属性更改一些值。

note如果您的极狐GitLab 安装使用外部(不由 Omnibus GitLab 管理)PostgreSQL 实例,则 Omnibus 角色无法执行所有必要的配置步骤。在这种情况下,请改用使用外部 PostgreSQL 实例的 Geo 流程。
note设置过程的各个阶段必须按记录的顺序完成。如果没有,在继续之前完成所有先前的阶段

确保次要站点与主要站点运行相同版本的极狐GitLab。确认您已将专业版或更高版本的许可证添加到您的主要站点。

在测试或生产环境中执行这些步骤之前,请务必阅读并查看所有这些步骤。

单实例数据库复制

单实例数据库复制更易于设置,并且仍提供与集群化替代方案相同的 Geo 功能。

单个实例可以使用 Patroni 扩展为集群化版本,推荐用于高可用架构。

请按照以下说明将 PostgreSQL 复制设置为单实例数据库。 或者,您可以查看关于使用 Patroni 集群设置复制的多节点数据库复制说明。

PostgreSQL 复制

发生写入操作的极狐GitLab 主要站点连接到主要数据库服务器,而次要站点连接到它们自己的数据库服务器(只读)。

我们建议使用 PostgreSQL 复制槽,确保主要站点保留次要站点恢复所需的所有数据。请参阅下面的更多细节。

以下指南假定:

  • 您使用的是 Omnibus,因此您使用的是 PostgreSQL 12 或更高版本,其中包括 pg_basebackup 工具
  • 您已经设置了一个主要站点(您将从中复制极狐GitLab 服务器),运行 Omnibus 的 PostgreSQL(或等效版本),并且您在所有站点上都使用相同版本的 PostgreSQL、OS 和 GitLab 设置了一个新的次要站点。
cautionGeo 适用于流式复制。目前不支持逻辑复制。

步骤 1. 配置主要站点

  1. SSH 进入您的极狐GitLab 主要站点,并以 root 身份登录:

    sudo -i
    
  2. 编辑 /etc/gitlab/gitlab.rb,并为您的站点添加一个独特的名称:

    ##
    ## The unique identifier for the Geo site. See
    ## https://docs.gitlab.com/ee/user/admin_area/geo_nodes.html#common-settings
    ##
    gitlab_rails['geo_node_name'] = '<site_name_here>'
    
  3. 重新配置主要站点,使更改生效:

    gitlab-ctl reconfigure
    
  4. 执行以下命令将站点定义为主要站点:

    gitlab-ctl set-geo-primary-node
    

    此命令使用您在 /etc/gitlab/gitlab.rb 中定义的 external_url

  5. gitlab 数据库用户定义密码:

    生成所需密码的 MD5 哈希:

    gitlab-ctl pg-password-md5 gitlab
    # Enter password: <your_password_here>
    # Confirm password: <your_password_here>
    # fca0b89a972d69f00eb3ec98a5838484
    

    编辑 /etc/gitlab/gitlab.rb

    # Fill with the hash generated by `gitlab-ctl pg-password-md5 gitlab`
    postgresql['sql_user_password'] = '<md5_hash_of_your_password>'
    
    # Every node that runs Puma or Sidekiq needs to have the database
    # password specified as below. If you have a high-availability setup, this
    # must be present in all application nodes.
    gitlab_rails['db_password'] = '<your_password_here>'
    
  6. 为数据库复制用户定义密码。

    我们将使用在 postgresql['sql_replication_user'] 设置下的 /etc/gitlab/gitlab.rb 中定义的用户名。默认值为 gitlab_replicator,但如果您将其更改为其他值,请调整以下说明。

    生成所需密码的 MD5 哈希:

    gitlab-ctl pg-password-md5 gitlab_replicator
    # Enter password: <your_password_here>
    # Confirm password: <your_password_here>
    # 950233c0dfc2f39c64cf30457c3b7f1e
    

    编辑 /etc/gitlab/gitlab.rb

    # Fill with the hash generated by `gitlab-ctl pg-password-md5 gitlab_replicator`
    postgresql['sql_replication_password'] = '<md5_hash_of_your_password>'
    

    如果您使用的是不受 Omnibus GitLab 管理的外部数据库,则需要创建复制器用户并手动为其定义密码:

    --- Create a new user 'replicator'
    CREATE USER gitlab_replicator;
    
    --- Set/change a password and grants replication privilege
    ALTER USER gitlab_replicator WITH REPLICATION ENCRYPTED PASSWORD '<replication_password>';
    
  7. 将 PostgreSQL 配置为侦听网络接口:

    出于安全原因,默认情况下 PostgreSQL 不侦听任何网络接口。但是,Geo 要求次要站点能够连接到主要站点的数据库。因此,我们需要每个站点的 IP 地址。

    note对于外部 PostgreSQL 实例,请参阅附加说明

    如果您使用云提供商,您可以通过云提供商的管理控制台查找每个 Geo 站点的地址。

    要查找 Geo 站点的地址,请 SSH 到 Geo 站点并执行:

    ##
    ## Private address
    ##
    ip route get 255.255.255.255 | awk '{print "Private address:", $NF; exit}'
    
    ##
    ## Public address
    ##
    echo "External address: $(curl --silent "ipinfo.io/ip")"
    

    在大多数情况下,以下地址用于配置极狐GitLab Geo:

    配置 地址
    postgresql['listen_address'] 主要站点的公开或 VPC 私有地址。
    postgresql['md5_auth_cidr_addresses'] 主要次要站点的公开或 VPC 私有地址。

listen_address 选项打开 PostgreSQL 到与给定地址对应的接口的网络连接。有关详细信息,请参阅 PostgreSQL 文档

note 如果需要使用 0.0.0.0* 作为 listen_address,还必须在 postgresql['md5_auth_cidr_addresses'] 设置中添加 127.0.0.1/32,以允许 Rails 通过 127.0. 0.1

编辑 /etc/gitlab/gitlab.rb 并添加以下内容,将 IP 地址替换为适合您的网络配置的地址:

   ##
   ## Geo Primary role
   ## - Configures Postgres settings for replication
   ## - Prevents automatic upgrade of Postgres since it requires downtime of
   ##   streaming replication to Geo secondary sites
   ## - Enables standard single-node GitLab services like NGINX, Puma, Redis,
   ##   or Sidekiq. If you are segregating services, then you will need to
   ##   explicitly disable unwanted services.
   ##
   roles(['geo_primary_role'])

   ##
   ## Primary address
   ## - replace '<primary_node_ip>' with the public or VPC address of your Geo primary node
   ##
   postgresql['listen_address'] = '<primary_site_ip>'

   ##
   # Allow PostgreSQL client authentication from the primary and secondary IPs. These IPs may be
   # public or VPC addresses in CIDR format, for example ['198.51.100.1/32', '198.51.100.2/32']
   ##
   postgresql['md5_auth_cidr_addresses'] = ['<primary_site_ip>/32', '<secondary_site_ip>/32']

   ##
   ## Replication settings
   ##
   # postgresql['max_replication_slots'] = 1 # Set this to be the number of Geo secondary nodes if you have more than one
   # postgresql['max_wal_senders'] = 10
   # postgresql['wal_keep_segments'] = 10

   ##
   ## Disable automatic database migrations temporarily
   ## (until PostgreSQL is restarted and listening on the private address).
   ##
   gitlab_rails['auto_migrate'] = false
  1. 可选:如果您想添加另一个次要站点,相关设置如下所示:

    postgresql['md5_auth_cidr_addresses'] = ['<primary_site_ip>/32', '<secondary_site_ip>/32', '<another_secondary_site_ip>/32']
    

    您可能还想编辑 wal_keep_segmentsmax_wal_senders 以匹配您的数据库复制要求。有关详细信息,请参阅 PostgreSQL - 复制文档

  2. 保存文件,并为数据库监听更改和要应用的复制槽更改,重新配置极狐GitLab:

    gitlab-ctl reconfigure
    

    重新启动 PostgreSQL,使其更改生效:

    gitlab-ctl restart postgresql
    
  3. 现在重新启用迁移,因为 PostgreSQL 已重新启动并侦听私有地址。

    编辑 /etc/gitlab/gitlab.rb,并变更配置为 true

    gitlab_rails['auto_migrate'] = true
    

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

    gitlab-ctl reconfigure
    
  4. 现在 PostgreSQL 服务器已设置为接受远端连接,运行 netstat -plnt | grep 5432,确保 PostgreSQL 在端口 5432 上侦听主要站点的私有地址。

  5. 重新配置极狐GitLab 时会自动生成证书,自动用于保护您的 PostgreSQL 流量免受窃听者的攻击,但为了防止主动(“中间人”)攻击者,次要站点需要证书的副本。通过运行以下命令在主要站点上复制 PostgreSQL server.crt 文件:

    cat ~gitlab-psql/data/server.crt
    

    将输出复制到剪贴板或本地文件。设置次要站点时需要它!证书不是敏感数据。

    但是,此证书创建时使用普通的 PostgreSQL Common Name。为此,复制数据库时必须使用 verify-ca 模式,否则主机名不匹配会导致错误。

  6. 可选。生成您自己的 SSL 证书,并手动为 PostgreSQL 配置 SSL,而不是使用生成的证书。

    根据 Database SSL 文档,您至少需要 SSL 证书和密钥,并将 postgresql['ssl_cert_file']postgresql['ssl_key_file'] 值设置为其完整路径。

    这允许您在复制数据库时使用 verify-full SSL 模式,并获得在 CN 中验证完整主机名的优势。

    您可以使用此证书(您也已在 postgresql['ssl_cert_file'] 中设置),而不是前面的证书。如果 CN 匹配,将允许您使用 verify-full 而不会出现复制错误。

步骤 2. 配置次要服务器

  1. SSH 进入您的极狐GitLab 次要站点并以 root 身份登录:

    sudo -i
    
  2. 停止应用服务器和 Sidekiq

    gitlab-ctl stop puma
    gitlab-ctl stop sidekiq
    
    note这一步很重要,因此在站点完全配置之前,我们不会尝试执行任何操作。
  3. 检查 TCP 连接主要站点的 PostgreSQL 服务器:

    gitlab-rake gitlab:tcp_check[<primary_site_ip>,5432]
    
    note如果此步骤失败,您可能使用了错误的 IP 地址,或者防火墙可能阻止访问该站点。检查 IP 地址,密切注意公开地址和私有地址之间的区别,并确保在存在防火墙的情况下,允许次要站点在端口 5432 上,连接到主要站点。
  4. 次要站点中创建一个文件 server.crt,其中包含您在主要站点设置的最后一步中获得的内容:

    editor server.crt
    
  5. 次要站点上设置 PostgreSQL TLS 验证:

    安装 server.crt 文件:

    install \
       -D \
       -o gitlab-psql \
       -g gitlab-psql \
       -m 0400 \
       -T server.crt ~gitlab-psql/.postgresql/root.crt
    

    PostgreSQL 现在只在验证 TLS 连接时识别那个证书。该证书只能由有权访问私钥的人复制,该私钥存在于主要站点上。

  6. 测试 gitlab-psql 用户是否可以连接到主要站点的数据库(默认 Omnibus 数据库名称为 gitlabhq_production):

    sudo \
       -u gitlab-psql /opt/gitlab/embedded/bin/psql \
       --list \
       -U gitlab_replicator \
       -d "dbname=gitlabhq_production sslmode=verify-ca" \
       -W \
       -h <primary_site_ip>
    
    note如果您使用手动生成的证书并计划使用 sslmode=verify-full 以受益于完整的主机名验证,请确保在运行命令时将 verify-ca 替换为 verify-full

    当提示输入您在第一步中为 gitlab_replicator 用户设置的明文密码时。如果一切正常,您应该会看到主要站点的数据库列表。

    此处连接失败表示 TLS 配置不正确。确保主要站点上 ~gitlab-psql/data/server.crt 的内容与次要站点上 ~gitlab-psql/.postgresql/root.crt 的内容匹配。

  7. 配置 PostgreSQL:

    此步骤类似于我们配置主要实例的方式。即使使用单个节点,我们也必须启用它。

    编辑 /etc/gitlab/gitlab.rb 并添加以下内容,将 IP 地址替换为适合您的网络配置的地址:

    ##
    ## Geo Secondary role
    ## - configure dependent flags automatically to enable Geo
    ##
    roles(['geo_secondary_role'])
    
    ##
    ## Secondary address
    ## - replace '<secondary_site_ip>' with the public or VPC address of your Geo secondary site
    ##
    postgresql['listen_address'] = '<secondary_site_ip>'
    postgresql['md5_auth_cidr_addresses'] = ['<secondary_site_ip>/32']
    
    ##
    ## Database credentials password (defined previously in primary site)
    ## - replicate same values here as defined in primary site
    ##
    postgresql['sql_replication_password'] = '<md5_hash_of_your_password>'
    postgresql['sql_user_password'] = '<md5_hash_of_your_password>'
    gitlab_rails['db_password'] = '<your_password_here>'
    

    对于外部 PostgreSQL 实例,请参阅附加说明。如果您将以前的主要站点重新上线,用作次要站点,那么您还必须删除 roles(['geo_primary_role'])geo_primary_role['enable'] = true

  8. 重新配置极狐GitLab,使更改生效:

    gitlab-ctl reconfigure
    
  9. 重启 PostgreSQL,使 IP 更改生效:

    gitlab-ctl restart postgresql
    

步骤 3. 启动复制过程

下面我们提供一个脚本,将次要站点上的数据库连接到主要站点上的数据库,复制数据库,并创建流复制所需的文件。

使用的目录是在 Omnibus 中设置的默认目录。如果您更改了任何默认值,请按照您认为合适的方式配置它,替换目录和路径。

caution确保在次要站点上运行,因为这样会在运行 pg_basebackup 之前删除所有 PostgreSQL 的数据。
  1. SSH 进入您的极狐GitLab 次要站点,并以 root 身份登录:

    sudo -i
    
  2. 选择一个对数据库友好的名称,用于您的次要站点,作为复制槽名称。例如,您的域名是 secondary.geo.example.com,您可以使用 secondary_example 作为槽名称,如下面的命令所示。

  3. 执行以下命令开始备份/恢复,并开始复制。

    caution每个 Geo 次要站点必须有自己唯一的复制槽名称。在两个次要节点之间使用相同的槽名称会中断 PostgreSQL 复制。
    note复制槽名称只能包含小写字母、数字和下划线字符。

    出现提示时,输入您在第一步中为 gitlab_replicator 用户设置的明文密码。

    gitlab-ctl replicate-geo-database \
       --slot-name=<secondary_site_name> \
       --host=<primary_site_ip> \
       --sslmode=verify-ca
    
    note如果您已生成自定义 PostgreSQL 证书,您将需要使用 --sslmode=verify-full(或完全省略 sslmode 行),受益于证书 CN / SAN 中完整主机名的额外验证,可以获得额外的安全性。否则,使用带有 verify-full 的自动创建的证书将失败,因为它有一个通用的 PostgreSQL CN,它与此命令中的 --host 值不匹配。

    此命令还采用许多附加选项。您可以使用 --help 将它们全部列出,但这里有一些提示:

    • 如果 PostgreSQL 正在侦听非标准端口,请添加 --port=
    • 如果您的数据库太大而无法在 30 分钟内完成传输,则需要增加超时时间,例如,如果您预计初始复制需要不到一个小时,则需要增加 --backup-timeout=3600
    • 传递 --sslmode=disable 以完全跳过 PostgreSQL TLS 身份验证(例如,您知道网络路径是安全的,或者您正在使用站点到站点 VPN)。在公共互联网上安全!
    • 您可以在 PostgreSQL 文档 中阅读有关每个 sslmode 的更多详细信息;上面的说明经过精心编写,以确保防止被动窃听者和主动“中间人”攻击者。
    • --slot-name 更改为要在主要数据库上使用的复制槽的名称。如果复制槽不存在,脚本会尝试自动创建它。
    • 如果您要将旧站点重新用于 Geo 次要站点,则必须将 --force 添加到命令行。
    • 当不在生产机器中时,如果您确定,可以通过添加 --skip-backup 来禁用备份步骤。

复制过程现已完成。

PgBouncer 支持(可选)

PgBouncer 可以与极狐GitLab Geo 一起使用,来池化 PostgreSQL 连接,即使在单实例安装中使用也可以提高性能。

如果您在高可用性配置中使用极狐GitLab,我们建议使用 PgBouncer,其中一个节点集群支持 Geo 主要站点,另外两个节点集群支持 Geo 次要站点。一个用于主数据库,另一个用于跟踪数据库。有关更多信息,请参阅 Omnibus GitLab 的高可用性

更改复制密码

在使用 Omnibus 管理的 PostgreSQL 实例时更改复制用户的密码:

在极狐GitLab Geo 主要站点上:

  1. 复制用户的默认值为 gitlab_replicator,但如果您在 /etc/gitlab/gitlab.rb 中的 postgresql['sql_replication_user'] 设置下设置了自定义复制用户,请确保以下说明适用于您自己的用户。

    生成所需密码的 MD5 哈希:

    sudo gitlab-ctl pg-password-md5 gitlab_replicator
    # Enter password: <your_password_here>
    # Confirm password: <your_password_here>
    # 950233c0dfc2f39c64cf30457c3b7f1e
    

    编辑 /etc/gitlab/gitlab.rb

    # Fill with the hash generated by `gitlab-ctl pg-password-md5 gitlab_replicator`
    postgresql['sql_replication_password'] = '<md5_hash_of_your_password>'
    
  2. 保存文件并重新配置极狐GitLab,更改 PostgreSQL 中的复制用户密码:

    sudo gitlab-ctl reconfigure
    
  3. 重新启动 PostgreSQL,使复制密码更改生效:

    sudo gitlab-ctl restart postgresql
    

在任何次要站点上更新密码之前,次要节点上的 PostgreSQL 日志将报告以下错误消息:

FATAL:  could not connect to the primary server: FATAL:  password authentication failed for user "gitlab_replicator"

在所有 Geo 次要站点上:

  1. 从配置的角度来看,第一步不是必需的,因为在 Geo 次要站点上不使用哈希的 sql_replication_password。但是,如果次要站点需要升级到主要站点,请确保匹配次要站点配置中的 'sql_replication_password'

    编辑 /etc/gitlab/gitlab.rb

    # Fill with the hash generated by `gitlab-ctl pg-password-md5 gitlab_replicator` on the Geo primary
    postgresql['sql_replication_password'] = '<md5_hash_of_your_password>'
    
  2. 在初始复制设置期间,gitlab-ctl replicate-geo-database 命令将复制用户帐户的明文密码写入两个位置:

    • gitlab-geo.conf:由 PostgreSQL 复制进程使用,写入 PostgreSQL 数据目录,默认为 /var/opt/gitlab/postgresql/data/gitlab-geo.conf
    • .pgpass:由 gitlab-psql 用户使用,默认位于 /var/opt/gitlab/postgresql/.pgpass

    更新这两个文件中的明文密码,然后重新启动 PostgreSQL:

    sudo gitlab-ctl restart postgresql
    

多节点数据库复制

在 14.0 版本中,Patroni 将 repmgr 替换为受支持的高度可用的 PostgreSQL 解决方案

note如果您还没有从 repmgr 迁移到 Patroni,强烈建议您这样做。

从 repmgr 迁移到 Patroni

  1. 在迁移之前,我们建议在主要次要站点之间没有复制延迟,并且复制已暂停。在 13.2 及更高版本中,您可以在 Geo 辅助数据库节点上使用 gitlab-ctl geo-replication-pausegitlab-ctl geo replication-resume 暂停和恢复复制。
  2. 按照将 repmgr 迁移到 Patroni 的说明。在每个主要站点数据库节点上配置 Patroni 时,将 patroni['replication_slots'] = { '<slot_name>' => 'physical' } 添加到 gitlab.rb,其中 <slot_name>次要站点的复制槽的名称。这确保了 Patroni 将复制槽识别为永久的,并且不会在重新启动时将其删除。
  3. 如果在迁移之前暂停到次要站点的数据库复制,一旦确认 Patroni 在主要站点上工作,恢复复制。

将单个 PostgreSQL 节点迁移到 Patroni

在引入 Patroni 之前,Geo 在 次要站点上没有对 HA 设置的 Omnibus 支持。

有了 Patroni,现在可以支持这一点。要将现有的 PostgreSQL 迁移到 Patroni:

  1. 确保您在次要节点上设置了 Consul 集群(类似于您在主要站点上的设置方式)。
  2. 配置永久复制槽。
  3. 配置内部负载均衡器。
  4. 配置 PgBouncer 节点。
  5. 在该单节点机器上配置备用集群。

您最终会得到一个带有单个节点的“备用集群”,允许您稍后按照上述相同的说明添加额外的 Patroni 节点。

Patroni 支持

Patroni 是 Geo 的官方复制管理解决方案。它可用于在主要次要 Geo 站点上构建高可用性集群。 在次要站点上使用 Patroni 是可选的,您不必在每个 Geo 站点上使用相同数量的节点。

有关如何在主要站点上设置 Patroni 的说明,请参阅使用 Omnibus GitLab 进行 PostgreSQL 复制和故障转移页面。

为 Geo 次要站点配置 Patroni 集群

在 Geo 次要站点中,主 PostgreSQL 数据库是主要站点的 PostgreSQL 数据库的只读副本。

如果您当前在 Geo 主要站点上使用 repmgr,请参阅这些从 repmgr 迁移到 Patroni 的说明。

生产就绪且安全的设置至少需要:

  • 3 个 Consul 节点 (主要和次要站点)
  • 2 个 Patroni 节点 (主要和次要站点)
  • 1 个 PgBouncer 节点 (主要和次要站点)
  • 1 个内部负载均衡器 (仅主要站点)

内部负载均衡器提供了一个端点,用于在选举新 leader 时连接到 Patroni 集群的 leader,并且需要从次要站点启用级联复制。

请务必使用密码凭据和其他数据库最佳实践。

步骤 1. 在主要站点上配置 Patroni 永久复制槽

要在次要站点上使用 Patroni 设置数据库复制,我们必须在主要站点的 Patroni 集群上配置一个永久复制槽,并确保使用密码验证。

在主要站点上运行 Patroni 实例的每个节点上从 Patroni Leader 实例开始

  1. SSH 到您的 Patroni 实例并以 root 身份登录:

    sudo -i
    
  2. 编辑 /etc/gitlab/gitlab.rb 并添加以下内容:

    roles(['patroni_role'])
    
    consul['services'] = %w(postgresql)
    consul['configuration'] = {
      retry_join: %w[CONSUL_PRIMARY1_IP CONSUL_PRIMARY2_IP CONSUL_PRIMARY3_IP]
    }
    
    # You need one entry for each secondary, with a unique name following PostgreSQL slot_name constraints:
    #
    # Configuration syntax is: 'unique_slotname' => { 'type' => 'physical' },
    # We don't support setting a permanent replication slot for logical replication type
    patroni['replication_slots'] = {
      'geo_secondary' => { 'type' => 'physical' }
    }
    
    patroni['use_pg_rewind'] = true
    patroni['postgresql']['max_wal_senders'] = 8 # Use double of the amount of patroni/reserved slots (3 patronis + 1 reserved slot for a Geo secondary).
    patroni['postgresql']['max_replication_slots'] = 8 # Use double of the amount of patroni/reserved slots (3 patronis + 1 reserved slot for a Geo secondary).
    patroni['username'] = 'PATRONI_API_USERNAME'
    patroni['password'] = 'PATRONI_API_PASSWORD'
    patroni['replication_password'] = 'PLAIN_TEXT_POSTGRESQL_REPLICATION_PASSWORD'
    
    # Add all patroni nodes to the allowlist
    patroni['allowlist'] = %w[
      127.0.0.1/32
      PATRONI_PRIMARY1_IP/32 PATRONI_PRIMARY2_IP/32 PATRONI_PRIMARY3_IP/32
      PATRONI_SECONDARY1_IP/32 PATRONI_SECONDARY2_IP/32 PATRONI_SECONDARY3_IP/32
    ]
    
    # We list all secondary instances as they can all become a Standby Leader
    postgresql['md5_auth_cidr_addresses'] = %w[
      PATRONI_PRIMARY1_IP/32 PATRONI_PRIMARY2_IP/32 PATRONI_PRIMARY3_IP/32 PATRONI_PRIMARY_PGBOUNCER/32
      PATRONI_SECONDARY1_IP/32 PATRONI_SECONDARY2_IP/32 PATRONI_SECONDARY3_IP/32 PATRONI_SECONDARY_PGBOUNCER/32
    ]
    
    postgresql['pgbouncer_user_password'] = 'PGBOUNCER_PASSWORD_HASH'
    postgresql['sql_replication_password'] = 'POSTGRESQL_REPLICATION_PASSWORD_HASH'
    postgresql['sql_user_password'] = 'POSTGRESQL_PASSWORD_HASH'
    postgresql['listen_address'] = '0.0.0.0' # You can use a public or VPC address here instead
    
  3. 重新配置极狐GitLab,使更改生效:

    gitlab-ctl reconfigure
    
步骤 2. 在主要站点上配置内部负载均衡器

为了避免在主要站点上选出新的 leader 时重新配置次要站点上的备用 leader,我们必须设置一个 TCP 内部负载均衡器,它提供一个端点来连接到 Patroni 集群的 leader。

Omnibus GitLab 软件包不包含负载均衡器。以下是使用 HAProxy 的方法。

以下 IP 和名称用作示例:

  • 10.6.0.21:Patroni 1 (patroni1.internal)
  • 10.6.0.22:Patroni 2 (patroni2.internal)
  • 10.6.0.23:Patroni 3 (patroni3.internal)
global
    log /dev/log local0
    log localhost local1 notice
    log stdout format raw local0

defaults
    log global
    default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions

frontend internal-postgresql-tcp-in
    bind *:5000
    mode tcp
    option tcplog

    default_backend postgresql

backend postgresql
    option httpchk
    http-check expect status 200

    server patroni1.internal 10.6.0.21:5432 maxconn 100 check port 8008
    server patroni2.internal 10.6.0.22:5432 maxconn 100 check port 8008
    server patroni3.internal 10.6.0.23:5432 maxconn 100 check port 8008

请参阅您首选的负载均衡器文档以获取更多指导。

步骤 3. 在次要站点上配置 PgBouncer 节点

生产就绪且高度可用的配置需要至少三个 Consul 节点,至少一个 PgBouncer 节点,但建议每个数据库节点有一个。当有多个 PgBouncer 服务节点时,需要一个内部负载均衡器 (TCP)。内部负载均衡器提供了一个用于连接到 PgBouncer 集群的端点。有关更多信息,请参阅 Omnibus GitLab 的高可用性

次要站点上运行 PgBouncer 实例的每个节点上:

  1. SSH 到您的 PgBouncer 节点并以 root 身份登录:

    sudo -i
    
  2. 编辑 /etc/gitlab/gitlab.rb 并添加以下内容:

    # Disable all components except Pgbouncer and Consul agent
    roles(['pgbouncer_role'])
    
    # PgBouncer configuration
    pgbouncer['admin_users'] = %w(pgbouncer gitlab-consul)
    pgbouncer['users'] = {
    'gitlab-consul': {
       # Generate it with: `gitlab-ctl pg-password-md5 gitlab-consul`
       password: 'GITLAB_CONSUL_PASSWORD_HASH'
     },
      'pgbouncer': {
        # Generate it with: `gitlab-ctl pg-password-md5 pgbouncer`
        password: 'PGBOUNCER_PASSWORD_HASH'
      }
    }
    
    # Consul configuration
    consul['watchers'] = %w(postgresql)
    consul['configuration'] = {
      retry_join: %w[CONSUL_SECONDARY1_IP CONSUL_SECONDARY2_IP CONSUL_SECONDARY3_IP]
    }
    consul['monitoring_service_discovery'] =  true
    
  3. 重新配置极狐GitLab,使更改生效:

    gitlab-ctl reconfigure
    
  4. 创建一个 .pgpass 文件,以便 Consul 能够重新加载 PgBouncer。询问时输入 PLAIN_TEXT_PGBOUNCER_PASSWORD 两次:

    gitlab-ctl write-pgpass --host 127.0.0.1 --database pgbouncer --user pgbouncer --hostuser gitlab-consul
    
  5. 重新加载 PgBouncer 服务:

    gitlab-ctl hup pgbouncer
    
步骤 4. 在次要站点上配置备用集群
note如果要将具有单个 PostgreSQL 实例的次要站点转换为 Patroni 集群,则必须从 PostgreSQL 实例开始。它成为 Patroni Standby Leader 实例,然后您可以根据需要切换到另一个副本。

对于在次要站点上运行 Patroni 实例的每个节点:

  1. SSH 到您的 Patroni 节点并以 root 身份登录:

    sudo -i
    
  2. 编辑 /etc/gitlab/gitlab.rb 并添加以下内容:

    roles(['consul_role', 'patroni_role'])
    
    consul['enable'] = true
    consul['configuration'] = {
      retry_join: %w[CONSUL_SECONDARY1_IP CONSUL_SECONDARY2_IP CONSUL_SECONDARY3_IP]
    }
    
    postgresql['md5_auth_cidr_addresses'] = [
      'PATRONI_SECONDARY1_IP/32', 'PATRONI_SECONDARY2_IP/32', 'PATRONI_SECONDARY3_IP/32', 'PATRONI_SECONDARY_PGBOUNCER/32',
      # Any other instance that needs access to the database as per documentation
    ]
    
    
    # Add patroni nodes to the allowlist
    patroni['allowlist'] = %w[
      127.0.0.1/32
      PATRONI_SECONDARY1_IP/32 PATRONI_SECONDARY2_IP/32 PATRONI_SECONDARY3_IP/32
    ]
    
    patroni['standby_cluster']['enable'] = true
    patroni['standby_cluster']['host'] = 'INTERNAL_LOAD_BALANCER_PRIMARY_IP'
    patroni['standby_cluster']['port'] = INTERNAL_LOAD_BALANCER_PRIMARY_PORT
    patroni['standby_cluster']['primary_slot_name'] = 'geo_secondary' # Or the unique replication slot name you setup before
    patroni['username'] = 'PATRONI_API_USERNAME'
    patroni['password'] = 'PATRONI_API_PASSWORD'
    patroni['replication_password'] = 'PLAIN_TEXT_POSTGRESQL_REPLICATION_PASSWORD'
    patroni['use_pg_rewind'] = true
    patroni['postgresql']['max_wal_senders'] = 5 # A minimum of three for one replica, plus two for each additional replica
    patroni['postgresql']['max_replication_slots'] = 5 # A minimum of three for one replica, plus two for each additional replica
    
    postgresql['pgbouncer_user_password'] = 'PGBOUNCER_PASSWORD_HASH'
    postgresql['sql_replication_password'] = 'POSTGRESQL_REPLICATION_PASSWORD_HASH'
    postgresql['sql_user_password'] = 'POSTGRESQL_PASSWORD_HASH'
    postgresql['listen_address'] = '0.0.0.0' # You can use a public or VPC address here instead
    
    gitlab_rails['dbpassword'] = 'POSTGRESQL_PASSWORD'
    gitlab_rails['enable'] = true
    gitlab_rails['auto_migrate'] = false
    
  3. 重新配置极狐GitLab,使更改生效。这是引导 PostgreSQL 用户和设置所必需的。

    • 如果这是全新安装的 Patroni:

      gitlab-ctl reconfigure
      
    • 如果您在以前有工作的 Patroni 集群的站点上配置 Patroni 备用集群:

      gitlab-ctl stop patroni
      rm -rf /var/opt/gitlab/postgresql/data
      /opt/gitlab/embedded/bin/patronictl -c /var/opt/gitlab/patroni/patroni.yaml remove postgresql-ha
      gitlab-ctl reconfigure
      gitlab-ctl start patroni
      

将单个跟踪数据库节点迁移到 Patroni

在引入 Patroni 之前,Geo 对次要站点上的 HA 设置没有 Omnibus 支持。

有了 Patroni,现在可以支持这一点。由于 Omnibus 上的 Patroni 实现有一些限制,不允许我们在同一台机器上管理两个不同的集群,我们建议按照上面的相同说明为跟踪数据库设置一个新的 Patroni 集群。

次要节点回填新的跟踪数据库,不需要数据同步。

为跟踪 PostgreSQL 数据库配置 Patroni 集群

次要站点使用单独的 PostgreSQL 安装实例,作为跟踪数据库来跟踪复制状态并自动从潜在的复制问题中恢复。设置了 roles(['geo_secondary_role']) 时,Omnibus 会自动配置跟踪数据库。

如果您想在高可用配置中运行这个数据库,不要使用上面的 geo_secondary_role。相反,请按照以下说明进行操作。

用于跟踪 PostgreSQL 数据库的生产就绪和安全设置需要辅助站点上至少三个 Consul 节点、两个 Patroni 节点和一个 PgBouncer 节点。

Consul 无法跟踪多个服务,因此这些服务必须不同于用于备用集群数据库的节点。

请务必使用密码凭据和其他数据库最佳实践。

步骤 1. 在次要站点上配置 PgBouncer 节点

在为 PostgreSQL 跟踪数据库运行 PgBouncer 服务的每个节点上:

  1. SSH 到您的 PgBouncer 节点并以 root 身份登录:

    sudo -i
    
  2. 编辑 /etc/gitlab/gitlab.rb 并添加以下内容:

    # Disable all components except Pgbouncer and Consul agent
    roles(['pgbouncer_role'])
    
    # PgBouncer configuration
    pgbouncer['users'] = {
      'pgbouncer': {
        password: 'PGBOUNCER_PASSWORD_HASH'
      }
    }
    
    pgbouncer['databases'] = {
      gitlabhq_geo_production: {
        user: 'pgbouncer',
        password: 'PGBOUNCER_PASSWORD_HASH'
      }
    }
    
    # Consul configuration
    consul['watchers'] = %w(postgresql)
    
    consul['configuration'] = {
      retry_join: %w[CONSUL_TRACKINGDB1_IP CONSUL_TRACKINGDB2_IP CONSUL_TRACKINGDB3_IP]
    }
    
    consul['monitoring_service_discovery'] =  true
    
    # GitLab database settings
    gitlab_rails['db_database'] = 'gitlabhq_geo_production'
    gitlab_rails['db_username'] = 'gitlab_geo'
    
  3. 重新配置极狐GitLab,使更改生效:

    gitlab-ctl reconfigure
    
  4. 创建一个 .pgpass 文件,以便 Consul 能够重新加载 PgBouncer。询问时输入 PLAIN_TEXT_PGBOUNCER_PASSWORD 两次:

    gitlab-ctl write-pgpass --host 127.0.0.1 --database pgbouncer --user pgbouncer --hostuser gitlab-consul
    
  5. 重启 PgBouncer 服务:

    gitlab-ctl restart pgbouncer
    

步骤 2. 配置 Patroni 集群

在 PostgreSQL 跟踪数据库的次要站点上运行 Patroni 实例的每个节点上:

  1. SSH 到您的 Patroni 节点并以 root 身份登录:

    sudo -i
    
  2. 编辑 /etc/gitlab/gitlab.rb 并添加以下内容:

    # Disable all components except PostgreSQL, Patroni, and Consul
    roles(['patroni_role'])
    
    # Consul configuration
    consul['services'] = %w(postgresql)
    
    consul['configuration'] = {
      server: true,
      retry_join: %w[CONSUL_TRACKINGDB1_IP CONSUL_TRACKINGDB2_IP CONSUL_TRACKINGDB3_IP]
    }
    
    # PostgreSQL configuration
    postgresql['listen_address'] = '0.0.0.0'
    postgresql['hot_standby'] = 'on'
    postgresql['wal_level'] = 'replica'
    
    postgresql['pgbouncer_user_password'] = 'PGBOUNCER_PASSWORD_HASH'
    postgresql['sql_replication_password'] = 'POSTGRESQL_REPLICATION_PASSWORD_HASH'
    postgresql['sql_user_password'] = 'POSTGRESQL_PASSWORD_HASH'
    
    postgresql['md5_auth_cidr_addresses'] = [
       'PATRONI_TRACKINGDB1_IP/32', 'PATRONI_TRACKINGDB2_IP/32', 'PATRONI_TRACKINGDB3_IP/32', 'PATRONI_TRACKINGDB_PGBOUNCER/32',
       # Any other instance that needs access to the database as per documentation
    ]
    
    # Add patroni nodes to the allowlist
    patroni['allowlist'] = %w[
      127.0.0.1/32
      PATRONI_TRACKINGDB1_IP/32 PATRONI_TRACKINGDB2_IP/32 PATRONI_TRACKINGDB3_IP/32
    ]
    
    # Patroni configuration
    patroni['username'] = 'PATRONI_API_USERNAME'
    patroni['password'] = 'PATRONI_API_PASSWORD'
    patroni['replication_password'] = 'PLAIN_TEXT_POSTGRESQL_REPLICATION_PASSWORD'
    patroni['postgresql']['max_wal_senders'] = 5 # A minimum of three for one replica, plus two for each additional replica
    
    # GitLab database settings
    gitlab_rails['db_database'] = 'gitlabhq_geo_production'
    gitlab_rails['db_username'] = 'gitlab_geo'
    gitlab_rails['enable'] = true
    
    # Disable automatic database migrations
    gitlab_rails['auto_migrate'] = false
    
  3. 重新配置极狐GitLab,使更改生效。这是引导 PostgreSQL 用户和设置所必需的:

    gitlab-ctl reconfigure
    

步骤 3. 在次要站点上配置跟踪数据库

对于运行 gitlab-railssidekiqgeo-logcursor 服务的每个节点:

  1. SSH 到您的节点并以 root 身份登录:

    sudo -i
    
  2. 编辑 /etc/gitlab/gitlab.rb 并添加以下属性。您可以设置其他属性,但必须设置以下属性。

    # Tracking database settings
    geo_secondary['db_username'] = 'gitlab_geo'
    geo_secondary['db_password'] = 'PLAIN_TEXT_PGBOUNCER_PASSWORD'
    geo_secondary['db_database'] = 'gitlabhq_geo_production'
    geo_secondary['db_host'] = 'PATRONI_TRACKINGDB_PGBOUNCER_IP'
    geo_secondary['db_port'] = 6432
    geo_secondary['auto_migrate'] = false
    
    # Disable the tracking database service
    geo_postgresql['enable'] = false
    
  3. 重新配置极狐GitLab,使更改生效。

    gitlab-ctl reconfigure
    
  4. 运行跟踪数据库迁移:

    gitlab-rake db:migrate:geo