Geo 数据库复制

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

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

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

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

单实例数据库复制

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

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

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

PostgreSQL 复制

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

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

以下指南假定:

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

步骤 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/administration/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>'
    

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

    --- 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. 编辑 /etc/gitlab/gitlab.rb 文件并将角色设置为 geo_primary_role(更多详情,可以查看 Geo 角色):

    ## Geo Primary role
    roles(['geo_primary_role'])
    
  8. 将 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 地址替换为适合您的网络配置的地址:

    ##
    ## 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
    
  9. 临时禁用数据库自动迁移,直到 PostgreSQL 重新启动并监听私有地址时。编辑 /etc/gitlab/gitlab.rb 并将配置更改为 false

    ## Disable automatic database migrations
    gitlab_rails['auto_migrate'] = false
    
  10. 可选:如果您想添加另一个次要站点,相关设置如下所示:

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

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

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

    gitlab-ctl reconfigure
    

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

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

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

    gitlab_rails['auto_migrate'] = true
    

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

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

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

    cat ~gitlab-psql/data/server.crt
    

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

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

  15. 可选。生成您自己的 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 用户是否可以连接到主要站点的数据库(默认 Linux 软件包数据库名称为 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. 编辑 /etc/gitlab/gitlab.rb 文件并将角色设置为 geo_secondary_role(更多详情,可以查看 Geo 角色):

    ##
    ## Geo Secondary role
    ## - configure dependent flags automatically to enable Geo
    ##
    roles(['geo_secondary_role'])
    
  8. 配置 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

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

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

    gitlab-ctl restart postgresql
    

步骤 3. 启动复制过程

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

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

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 将它们全部列出,但这里有一些提示:

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

复制过程现已完成。

note 复制进程仅将数据从主要站点数据库拷贝至次要站点数据库。要完成您的次要站点配置,可参考在您的主要站点上添加次要站点

PgBouncer 支持(可选)

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

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

更改复制密码

在使用 Linux 软件包管理的 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
    

多节点数据库复制

将单个 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 集群上。

::Tabs

:::TabTitle Primary with Patroni cluster

要在次要站点上的 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
    

:::TabTitle Primary with single PostgreSQL instance

  1. SSH 到您的单节点实例并切换到 root 用户:

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

    postgresql['max_wal_senders'] = 2 # Use 2 per secondary site (1 temporary slot for initial Patroni replication + 1 reserved slot for a Geo secondary)
    postgresql['max_replication_slots'] = 2 # Use 2 per secondary site (1 temporary slot for initial Patroni replication + 1 reserved slot for a Geo secondary)
    
  3. 重新配置极狐GitLab:

    gitlab-ctl reconfigure
    
  4. 重启 PostgreSQL 服务以便让变更生效:

    gitlab-ctl restart postgresql
    
  5. 启动一个数据库控制台:

    gitlab-psql
    
  6. 在主要站点上配置永久副本槽:

    select pg_create_physical_replication_slot('geo_secondary')
    
  7. 可选。如果主要站点没有 PgBouncer,但是次要站点有:

    在主站点上配置 pgbouncer 用户,并为 Linux 软件包中包含的 PgBouncer 添加必要的 pg_shadow_lookup 函数。次要站点服务器上的 PgBouncer 应该仍然能够连接到次要站点上的 PostgreSQL 节点。

    --- Create a new user 'pgbouncer'
    CREATE USER pgbouncer;
    
    --- Set/change a password and grants replication privilege
    ALTER USER pgbouncer WITH REPLICATION ENCRYPTED PASSWORD '<pgbouncer_password_from_secondary>';
    
    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;
    

::EndTabs

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

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

Linux 软件包不包含负载均衡器。以下是使用 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
    

    当配置 patroni['standby_cluster']['host']patroni['standby_cluster']['port'] 时:

    • INTERNAL_LOAD_BALANCER_PRIMARY_IP 必需指向主站点的内部负载均衡 IP 地址。
    • INTERNAL_LOAD_BALANCER_PRIMARY_PORT 必需指向为主 Patroni 集群 leader 配置的前端端口。不要使用 PgBounder 前端端口。
  3. 重新配置极狐GitLab,使更改生效。这是引导 PostgreSQL 用户和设置所必需的。

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

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

      1. 在所有由 Patroni 管理的节点上停止 Patroni,包括级联副本:

        gitlab-ctl stop patroni
        
      2. 在 leader 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
        
      3. 在 leader Patroni 节点上启动 Patroni 以初始化从主数据库进行复制的进程:

        gitlab-ctl start patroni
        
      4. 检查 Patroni 集群的状态:

        gitlab-ctl patroni members
        

        验证:

        • 当前的 Patroni 节点出现在输出中。
        • 角色是 Standby Leader。角色需要在初始时展示为 Replica
        • 状态是 Running。状态需要在初始时展示为 Creating replica

        等待,指导节点的角色变为稳定的 Standby Leader 且状态变为 Running。这可能需要花费几分钟。

      5. 当 leader Patroni 节点为 Standby Leader 且状态为 Running,在 standby 集群中的其他 Patroni 节点上启动 Patroni:

        gitlab-ctl start patroni
        

        其他的 Patroni 节点应当作为副本加入新的备用集群,并开始自动从主 Patroni 节点进行复制。

  4. 验证集群状态:

    gitlab-ctl patroni members
    

    确保所有的 Patroni 节点都处于 Running 状态。应该有一个 Standby Leader 节点和多个 Replica 节点。

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

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

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

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

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

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

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

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

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

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

故障排查

阅读故障排查文档t