地理数据库复制
- 层级:Premium、Ultimate
- 提供:GitLab 自托管
本文档描述了将主 GitLab 数据库复制到辅助站点数据库所需的最小步骤。您可能需要根据数据库设置和大小等属性更改某些值。
如果您的 GitLab 安装使用外部 PostgreSQL 实例(不由 Linux 包安装管理),则角色无法执行所有必要的配置步骤。在这种情况下,请改用 带有外部 PostgreSQL 实例的 Geo 流程。
设置过程的各个阶段必须按文档顺序完成。如果不是,请在继续之前 完成所有先前阶段。
确保 辅助 站点运行与 主 站点相同的 GitLab Enterprise Edition 版本。确认你已向 主 站点添加了 Premium 或 Ultimate 订阅 的许可证。
在测试或生产环境中执行这些步骤之前,务必阅读并审查所有这些步骤。
数据库密码一致性要求
每种与数据库相关的密码类型必须在所有 Geo 站点(主站点和辅助站点)中具有匹配值。这包括:
postgresql['sql_replication_password'](复制用户密码,MD5)postgresql['sql_user_password'](GitLab 数据库用户密码,MD5)gitlab_rails['db_password'](GitLab 数据库用户密码,明文)patroni['replication_password'](针对 Patroni 设置,明文)patroni['password'](针对 Patroni API 身份验证,明文)postgresql['pgbouncer_user_password'](使用 PgBouncer 时,MD5)
例如,主站点上配置的 patroni['password'] 值必须与所有辅助站点的 patroni['password'] 值相同。
这些密码用于主站点和辅助站点之间的数据库身份验证和复制。使用不同的密码会导致复制失败,并阻止 Geo 正常运行。
单实例数据库复制
单实例数据库复制更容易设置,并且仍然提供与集群替代方案相同的 Geo 功能。它适用于在单个机器上运行的设置,或尝试评估未来集群安装的 Geo。
单实例可以使用 Patroni 扩展为集群版本,这推荐用于高可用架构。
按照以下说明设置 PostgreSQL 复制作为单实例数据库。或者,您可以查看 多节点数据库复制 说明,了解如何使用 Patroni 集群设置复制。
PostgreSQL 复制
发生写操作的 GitLab 主 站点连接到 主 数据库服务器。辅助 站点连接到自己的数据库服务器(仅读)。
你应该使用 PostgreSQL 的复制槽,以确保 主 站点保留 辅助 站点恢复所需的所有数据。详见下文。
以下指南假设:
- 你正在使用 Linux 包(因此使用 PostgreSQL 12 或更高版本),其中包含
pg_basebackup工具。 - 你已经设置了 主 站点(你要从中复制的 GitLab 服务器),运行由 Linux 包安装管理的 PostgreSQL(或等效版本),并且你有一个新的 辅助 站点,所有站点都安装了相同的 PostgreSQL 版本、操作系统和 GitLab。
Geo 使用流式复制工作。逻辑复制不受支持,但 epic 18022 提议改变此行为。
步骤1. 配置主站点
-
通过SSH连接到你的GitLab主站点并以root身份登录:
sudo -i -
选择退出自动PostgreSQL升级(https://docs.gitlab.com/omnibus/settings/database/#opt-out-of-automatic-postgresql-upgrades),以避免在升级GitLab时出现意外停机。请注意使用Geo升级PostgreSQL时的已知注意事项(https://docs.gitlab.com/omnibus/settings/database/#caveats-when-upgrading-postgresql-with-geo)。特别是对于较大的环境,PostgreSQL升级必须经过计划和有意识地执行。因此,今后请确保将PostgreSQL升级纳入常规维护活动。
-
编辑
/etc/gitlab/gitlab.rb并为你的站点添加一个唯一的名称:## ## 站点的唯一标识符。参见 ## https://docs.gitlab.com/ee/administration/geo_sites.html#common-settings ## gitlab_rails['geo_node_name'] = '<site_name_here>' -
重新配置主站点以使更改生效:
gitlab-ctl reconfigure -
执行以下命令将站点定义为主站点:
gitlab-ctl set-geo-primary-node此命令会使用你在
/etc/gitlab/gitlab.rb中定义的external_url。 -
为
gitlab数据库用户定义密码:生成所需密码的MD5哈希值:
gitlab-ctl pg-password-md5 gitlab # Enter password: <your_db_password_here> # Confirm password: <your_db_password_here> # fca0b89a972d69f00eb3ec98a5838484编辑
/etc/gitlab/gitlab.rb:# 填入由 `gitlab-ctl pg-password-md5 gitlab` 生成的哈希值 postgresql['sql_user_password'] = '<md5_hash_of_your_db_password>' # 每个运行Puma或Sidekiq的节点都需要指定数据库密码,如下所示。如果你有高可用性设置,此配置必须在所有应用节点中存在。 gitlab_rails['db_password'] = '<your_db_password_here>' -
为数据库复制用户定义密码。
使用在
/etc/gitlab/gitlab.rb的postgresql['sql_replication_user']设置下定义的用户名。默认值为gitlab_replicator。如果你将其更改为其他名称,请相应调整以下说明。生成所需密码的MD5哈希值:
gitlab-ctl pg-password-md5 gitlab_replicator # Enter password: <your_replication_password_here> # Confirm password: <your_replication_password_here> # 950233c0dfc2f39c64cf30457c3b7f1e编辑
/etc/gitlab/gitlab.rb:# 填入由 `gitlab-ctl pg-password-md5 gitlab_replicator` 生成的哈希值 postgresql['sql_replication_password'] = '<md5_hash_of_your_replication_password>'如果你使用的是不受Linux包安装管理的外部数据库,则需要手动创建
gitlab_replicator用户并为该用户定义密码:--- 创建新用户 'replicator' CREATE USER gitlab_replicator; --- 设置/修改密码并授予复制权限 ALTER USER gitlab_replicator WITH REPLICATION ENCRYPTED PASSWORD '<replication_password>'; -
编辑
/etc/gitlab/gitlab.rb并将角色设置为geo_primary_role(有关更多信息,请参阅Geo角色):## Geo 主角色 roles(['geo_primary_role']) -
配置PostgreSQL监听网络接口:
出于安全考虑,PostgreSQL默认不会监听任何网络接口。但是,Geo要求次级站点能够连接到主站点的数据库。因此,你需要每个站点的IP地址。
如果你是使用外部PostgreSQL实例,请参阅额外说明。
如果你使用云服务提供商,可以通过云服务提供商的管理控制台查找每个Geo站点的地址。
要查找Geo站点的地址,通过SSH连接到该Geo站点并执行:
## ## 私有地址 ## ip route get 255.255.255.255 | awk '{print "私有地址:", $NF; exit}' ## ## 公共地址 ## echo "外部地址: $(curl --silent "ipinfo.io/ip")"在大多数情况下,以下地址用于配置GitLab Geo:
Configuration Address postgresql['listen_address']Primary 站点的公共或VPC私有地址。
| postgresql['md5_auth_cidr_addresses'] | 主站点和副站点的公共或VPC私有地址。 |
如果您使用Google Cloud Platform、SoftLayer或其他提供虚拟专用云(VPC)的供应商,我们建议对postgresql['md5_auth_cidr_addresses']和postgresql['listen_address']使用主站点和副站点的“私有”或“内部”地址。
listen_address选项会将PostgreSQL开放给与给定地址对应的接口的网络连接。更多详情请参阅PostgreSQL文档。
如果您需要使用0.0.0.0或*作为listen_address,您还必须将127.0.0.1/32添加到postgresql['md5_auth_cidr_addresses']设置中,以允许Rails通过127.0.0.1连接。更多信息请参见问题5258。
根据您的网络配置,建议的地址可能不正确。如果您的主站点和副站点通过局域网或虚拟网络(如Amazon VPC或Google VPC)连接可用区,则应使用副站点的私有地址作为postgresql['md5_auth_cidr_addresses']。
编辑/etc/gitlab/gitlab.rb并添加以下内容,将IP地址替换为适合您网络配置的地址:
##
## 主地址
## - 将'<primary_node_ip>'替换为您的Geo主节点的公共或VPC地址
##
postgresql['listen_address'] = '<primary_site_ip>'
##
# 允许来自主站点和副站点IP的PostgreSQL客户端认证。这些IP可以是CIDR格式的公共或VPC地址,例如['198.51.100.1/32', '198.51.100.2/32']
##
postgresql['md5_auth_cidr_addresses'] = ['<primary_site_ip>/32', '<secondary_site_ip>/32']
##
## 复制设置
##
# postgresql['max_replication_slots'] = 1 # 如果有多个Geo副节点,将其设置为副节点数量
# postgresql['max_wal_senders'] = 10
# postgresql['wal_keep_segments'] = 10-
暂时禁用自动数据库迁移,直到PostgreSQL重启并监听在私有地址上。编辑
/etc/gitlab/gitlab.rb并将配置改为false:## 禁用自动数据库迁移 gitlab_rails['auto_migrate'] = false -
可选:如果要添加另一个副站点,相关设置如下所示:
postgresql['md5_auth_cidr_addresses'] = ['<primary_site_ip>/32', '<secondary_site_ip>/32', '<another_secondary_site_ip>/32']您可能还需要编辑
wal_keep_segments和max_wal_senders以满足数据库复制的需求。有关更多信息,请参阅PostgreSQL - 复制文档。 -
保存文件并重新配置GitLab,以应用数据库监听更改和复制槽位更改:
gitlab-ctl reconfigure重启PostgreSQL以使更改生效:
gitlab-ctl restart postgresql -
现在PostgreSQL已重启并监听在私有地址上,重新启用迁移。编辑
/etc/gitlab/gitlab.rb并将配置更改为true:gitlab_rails['auto_migrate'] = true保存文件并重新配置GitLab:
gitlab-ctl reconfigure -
现在PostgreSQL服务器已设置为接受远程连接,运行
netstat -plnt | grep 5432以确保PostgreSQL正在监听端口5432上的主站点私有地址。 -
当GitLab重新配置时,证书会自动生成。此证书用于自动保护您的PostgreSQL流量免受窃听者攻击。为了防范主动(“中间人”)攻击者,副站点需要一份签署该证书的CA副本。对于此自签名证书,请在主站点上运行以下命令来复制PostgreSQL的
server.crt文件:cat ~gitlab-psql/data/server.crt将输出复制到剪贴板或本地文件中。在设置副站点时需要它!该证书不是敏感数据。
但是,此证书使用通用的
PostgreSQL通用名称创建。因此,在复制数据库时必须使用verify-ca模式,否则主机名不匹配会导致错误。 -
可选。生成自己的SSL证书并手动
你应该为PostgreSQL配置SSL,而不是使用自动生成的证书。
你至少需要SSL证书和密钥。根据数据库SSL文档,将postgresql['ssl_cert_file']和postgresql['ssl_key_file']的值设置为它们的完整路径。
这允许你在复制数据库时使用verify-full SSL模式,并获得额外的好处——验证CN(通用名称)中的完整主机名。
今后,你可以使用此证书(你也已在postgresql['ssl_cert_file']中设置)来代替之前自动生成的自签名证书。如果CN匹配,这将使你能够使用verify-full而不会出现复制错误。
在你的主数据库上,打开/etc/gitlab/gitlab.rb并搜索postgresql['ssl_ca_file'](CA证书)。将其值复制到剪贴板,稍后你会将其粘贴到server.crt中。
步骤 2. 配置次要服务器
-
通过SSH进入你的GitLab次要站点并以root身份登录:
sudo -i -
退出自动PostgreSQL升级,以避免在升级GitLab时发生意外停机。了解在使用Geo升级PostgreSQL时的已知注意事项。特别是对于较大的环境,必须有计划地执行PostgreSQL升级。因此,请确保PostgreSQL升级成为常规维护活动的一部分。
-
停止应用服务器和Sidekiq:
gitlab-ctl stop puma gitlab-ctl stop sidekiq此步骤很重要,这样你就不会在站点完全配置之前尝试执行任何操作。
-
检查TCP连接到主站点的PostgreSQL服务器:
gitlab-rake gitlab:tcp_check[<primary_site_ip>,5432]如果此步骤失败,你可能使用了错误的IP地址,或者防火墙可能阻止了对站点的访问。检查IP地址,特别注意公共地址和私有地址的区别。确保如果存在防火墙,次要站点被允许连接到主站点的5432端口。
-
在次要站点创建一个名为
server.crt的文件,内容是你在上一步主站点设置中获取到的:editor server.crt -
在次要站点上设置PostgreSQL TLS验证:
安装
server.crt文件:install \ -D \ -o gitlab-psql \ -g gitlab-psql \ -m 0400 \ -T server.crt ~gitlab-psql/.postgresql/root.crtPostgreSQL现在仅在验证TLS连接时识别该确切证书。只有拥有私钥的人才能复制该证书,而私钥仅存在于主站点。
-
测试
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>如果你使用手动生成的证书并希望使用
sslmode=verify-full以获得完整的hostname验证,请在运行命令时将verify-ca替换为verify-full。当提示输入密码时,输入你在第一步中为
gitlab_replicator用户设置的明文密码。如果一切正常,你应该看到主站点的数据库列表。连接失败表明TLS配置不正确。确保主站点上的
~gitlab-psql/data/server.crt内容和次要站点上的~gitlab-psql/.postgresql/root.crt内容匹配。 -
编辑
/etc/gitlab/gitlab.rb并将角色设置为geo_secondary_role(有关更多信息,请参阅Geo角色):## ## Geo 次要角色 ## - 自动配置依赖标志以启用Geo ## roles(['geo_secondary_role']) -
配置PostgreSQL:
此步骤与配置主实例的方式类似。即使使用单节点也必须启用此功能。
所有Geo站点中的每种密码类型必须有匹配值。
编辑
/etc/gitlab/gitlab.rb并添加以下内容,用适合你网络配置的地址替换IP地址:## ## 次要地址 ## - 将'<secondary_site_ip>'替换为你的Geo次要站点的公共或VPC地址 ## postgresql['listen_address'] = '<secondary_site_ip>' postgresql['md5_auth_cidr_addresses'] = ['<secondary_site_ip>/32'] ## ## 数据库凭据密码(之前在主站点定义) ## - 在此处复制主站点中定义的相同值 ## postgresql['sql_replication_password'] = '<md5_hash_of_your_replication_password>' postgresql['sql_user_password'] = '<md5_hash_of_your_db_password>' gitlab_rails['db_password'] = '<your_db_password_here>'对于外部PostgreSQL实例,请参阅附加说明。
如果你将以前的主站点重新上线以作为辅助站点,那么你还必须移除 roles(['geo_primary_role']) 或 geo_primary_role['enable'] = true。
-
重新配置 GitLab 以使更改生效:
gitlab-ctl reconfigure -
重启 PostgreSQL 以使 IP 更改生效:
gitlab-ctl restart postgresql
步骤 3. 启动复制过程
以下是连接次要站点数据库与主要站点数据库的脚本。该脚本会复制数据库并创建流式复制所需的文件。
所用目录是 Linux 包安装的默认设置。如果你修改了任何默认值,请相应地配置脚本(替换所有目录和路径)。
请务必在次要站点上运行此脚本,因为它会在执行 pg_basebackup 之前删除所有 PostgreSQL 的数据。
-
通过 SSH 登录至你的 GitLab 次要站点,并以 root 身份登录:
sudo -i -
选择一个数据库友好名称,用作次要站点的复制槽名称。例如,如果你的域名为
secondary.geo.example.com,则使用secondary_example作为槽名称(如下方命令所示)。 -
执行以下命令启动备份/恢复并开始复制:
每个 Geo 次要站点都必须拥有自己唯一的复制槽名称。两个次要站点共用同一个槽名称会破坏 PostgreSQL 复制。
复制槽名称只能包含小写字母、数字和下划线字符。
当系统提示时,输入你在第一步中为
gitlab_replicator用户设置的明文密码。gitlab-ctl replicate-geo-database \ --slot-name=<secondary_site_name> \ --host=<primary_site_ip> \ --sslmode=verify-ca如果你生成了自定义 PostgreSQL 证书,需要使用
--sslmode=verify-full(或完全省略sslmode参数),以利用证书 CN/SAN 中完整主机名的额外验证来增强安全性。否则,使用自动生成的证书搭配verify-full会失败,因为其通用PostgreSQLCN 与本命令中的--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禁用备份步骤。
- 如果你的主要站点只有单个节点,可将主节点主机用作
复制过程现已完成。
复制过程仅将从主要站点数据库复制数据至次要站点数据库。要完成次要站点的配置,请在主要站点添加次要站点。
PgBouncer 支持(可选)
PgBouncer 可与 GitLab Geo 配合使用,以池化 PostgreSQL 连接,即使在单实例安装中也能提升性能。
如果您在高度可用的配置中使用 GitLab,该配置包含一个支持 Geo 主站点 的节点集群,以及另外两个支持 Geo 次级站点 的节点集群,则应使用 PgBouncer。您需要两个 PgBouncer 节点:一个用于主数据库,另一个用于跟踪数据库。更多信息,请参阅 相关文档。
更改复制密码
当更改复制密码时,您必须在所有 Geo 站点(主站点和所有次级站点)上更新它,并使用相同的密码值(#数据库密码一致性要求)。若未保持密码同步,会导致复制中断。
当使用由 Linux 包管理器安装的 PostgreSQL 实例时,若要更改 复制用户 的密码:
在 GitLab Geo 主站点 上:
-
复制用户的默认值为
gitlab_replicator,但如果您已在/etc/gitlab/gitlab.rb的postgresql['sql_replication_user']设置中自定义了复制用户,请根据您的用户调整以下说明。生成所需密码的 MD5 哈希:
sudo gitlab-ctl pg-password-md5 gitlab_replicator # 输入密码:<your_replication_password_here> # 确认密码:<your_replication_password_here> # 950233c0dfc2f39c64cf30457c3b7f1e编辑
/etc/gitlab/gitlab.rb:# 填写通过 `gitlab-ctl pg-password-md5 gitlab_replicator` 生成的哈希值 postgresql['sql_replication_password'] = '<md5_hash_of_your_replication_password>' -
保存文件并重新配置 GitLab,以更改 PostgreSQL 中复制用户的密码:
sudo gitlab-ctl reconfigure -
重启 PostgreSQL 以使复制密码更改生效:
sudo gitlab-ctl restart postgresql
在任意 次级 站点上更新密码之前,次级站点的 PostgreSQL 日志 会报告以下错误消息:
FATAL: 无法连接到主服务器:FATAL: 密码验证失败,用户 "gitlab_replicator"
在所有 GitLab Geo 次级站点 上:
-
从配置角度来看,第一步并非必需,因为在 GitLab Geo 次级站点 上不会使用经过哈希处理的
'sql_replication_password'。但是,如果 次级站点 需要被提升为 GitLab Geo 主站点,请确保在 次级站点 配置中匹配'sql_replication_password'。编辑
/etc/gitlab/gitlab.rb:# 填写通过 `gitlab-ctl pg-password-md5 gitlab_replicator` 在 Geo 主站点生成的哈希值 postgresql['sql_replication_password'] = '<md5_hash_of_your_replication_password>' -
在初始复制设置期间,
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 不支持 Linux 包安装方式在 次级 站点实现高可用(HA)配置。
借助 Patroni,此支持现已可行。要将现有 PostgreSQL 迁移至 Patroni:
- 确保已在次级站点搭建 Consul 集群(类似在 主站点 搭建的方式)。
- 配置永久复制槽(#step-1-configure-patroni-permanent-replication-slot-on-the-primary-site)。
- 配置内部负载均衡器(#step-2-configure-the-internal-load-balancer-on-the-primary-site)。
- 配置 PgBouncer 节点(#step-3-configure-pgbouncer-nodes-on-the-secondary-site)。
- 在该单节点机器上 配置备用集群(#step-4-configure-a-standby-cluster-on-the-secondary-site)。
最终您会得到一个仅含单个节点的 备用集群。这允许您通过遵循上述相同步骤添加更多 Patroni 节点。
Patroni 支持
Patroni 是 Geo 的官方复制管理解决方案。Patroni 可用于在 Geo 主要站点和次要站点上构建高可用集群。
在次要站点使用 Patroni 是可选的,且你不必在每个 Geo 站点中使用相同数量的节点。
有关如何在主要站点设置 Patroni 的说明,请参阅相关文档。
配置 Geo 次要站点的 Patroni 集群
在 Geo 次要站点中,主 PostgreSQL 数据库是主要站点 PostgreSQL 数据库的只读副本。
一个生产就绪且安全的设置至少需要:
- 3 个 Consul 节点(主要和次要站点)
- 2 个 Patroni 节点(主要和次要站点)
- 1 个 PgBouncer 节点(主要和次要站点)
- 1 个内部负载均衡器(仅限主要站点)
内部负载均衡器提供了一个单一端点,用于在新领导者被选举时连接到 Patroni 集群的领导者。启用从次要站点进行的级联复制需要负载均衡器。
务必使用密码凭证和其他数据库最佳实践。
步骤 1:在主站点配置 Patroni 永久复制槽
在主数据库上设置持久化复制槽,确保从主数据库到次级节点的 Patroni 集群持续数据复制。
若要在次级站点通过 Patroni 配置数据库复制,你必须在主站点的 Patroni 集群上配置永久复制槽,并确保使用密码认证。
在主站点运行 Patroni 实例的每个节点上(从 Patroni Leader 实例开始):
-
通过 SSH 连接到你的 Patroni 实例并以 root 身份登录:
sudo -i -
选择退出自动 PostgreSQL 升级,避免升级 GitLab 时发生意外停机。了解在使用 Geo 升级 PostgreSQL 时的已知 注意事项。对于较大环境而言,必须谨慎规划与执行 PostgreSQL 升级。因此,今后请确保 PostgreSQL 升级纳入常规维护流程。
-
编辑
/etc/gitlab/gitlab.rb并添加以下内容:每种密码类型必须在所有 Geo 站点中具有匹配值。
roles(['patroni_role']) consul['services'] = %w(postgresql) consul['configuration'] = { retry_join: %w[CONSUL_PRIMARY1_IP CONSUL_PRIMARY2_IP CONSUL_PRIMARY3_IP] } # 你需要为每个次级站点添加一个条目,名称需符合 PostgreSQL slot_name 约束: # # 配置语法为:'唯一槽名' => { 'type' => 'physical' }, # 我们不支持为逻辑复制类型设置永久复制槽 patroni['replication_slots'] = { 'geo_secondary' => { 'type' => 'physical' } } patroni['use_pg_rewind'] = true patroni['postgresql']['max_wal_senders'] = 8 # 使用双倍数量的 patroni/预留槽(3 个 patroni + 1 个为 Geo 次级预留的槽) patroni['postgresql']['max_replication_slots'] = 8 # 使用双倍数量的 patroni/预留槽(3 个 patroni + 1 个为 Geo 次级预留的槽) patroni['username'] = 'PATRONI_API_USERNAME' patroni['password'] = 'PATRONI_API_PASSWORD' patroni['replication_password'] = 'PLAIN_TEXT_POSTGRESQL_REPLICATION_PASSWORD' # 将所有 patroni 节点添加到允许列表中 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 ] # 我们列出所有次级实例,因为它们都可能成为备用 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' # 你可在此处改用公共地址或 VPC 地址-
重新配置 GitLab 以使更改生效:
gitlab-ctl reconfigure
-
-
通过 SSH 连接到你的单节点实例并以 root 身份登录:
sudo -i -
选择退出自动 PostgreSQL 升级,避免升级 GitLab 时发生意外停机。了解在使用 Geo 升级 PostgreSQL 时的已知 注意事项。对于较大环境而言,必须谨慎规划与执行 PostgreSQL 升级。因此,今后请确保 PostgreSQL 升级纳入常规维护流程。
-
编辑
/etc/gitlab/gitlab.rb并添加以下内容:postgresql['max_wal_senders'] = 2 # 每个次级站点使用 2(1 个临时槽用于初始 Patroni 复制 + 1 个为 Geo 次级预留的槽) postgresql['max_replication_slots'] = 2 # 每个次级站点使用 2(1 个临时槽用于初始 Patroni 复制 + 1 个为 Geo 次级预留的槽) -
重新配置 GitLab:
gitlab-ctl reconfigure -
重启 PostgreSQL 服务以使新更改生效:
gitlab-ctl restart postgresql -
启动数据库控制台:
gitlab-psql -
在主站点配置永久复制槽
select pg_create_physical_replication_slot('geo_secondary') -
可选:如果主节点没有PgBouncer,但从节点有:
在主站点配置
pgbouncer用户,并为包含在Linux软件包中的PgBouncer添加必要的pg_shadow_lookup函数。从服务器上的PgBouncer仍应能够连接到从站点的PostgreSQL节点。--- 创建新用户'pgbouncer' CREATE USER pgbouncer; --- 设置/更改密码并授予复制权限 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;
步骤 2. 在主站点上配置内部负载均衡器
为了避免在主站点选举新Leader时重新配置备用站点的Standby 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 *:5432
mode tcp
option tcplog
default_backend postgresql
backend postgresql
mode tcp
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节点。当有多个PgBouncer服务节点时,需要一个内部负载均衡器(TCP)。该内部负载均衡器提供了一个单一端点来连接到PgBouncer集群。更多信息,请参阅相关文档。
在每个运行PgBouncer实例的备用站点节点上:
-
通过SSH进入你的PgBouncer节点并以root身份登录:
sudo -i -
编辑
/etc/gitlab/gitlab.rb并添加以下内容:# 禁用除PgBouncer和Consul代理之外的所有组件 roles(['pgbouncer_role']) # PgBouncer配置 pgbouncer['admin_users'] = %w(pgbouncer gitlab-consul) pgbouncer['users'] = { 'gitlab-consul': { # 使用以下命令生成:`gitlab-ctl pg-password-md5 gitlab-consul` password: 'GITLAB_CONSUL_PASSWORD_HASH' }, 'pgbouncer': { # 使用以下命令生成:`gitlab-ctl pg-password-md5 pgbouncer` password: 'PGBOUNCER_PASSWORD_HASH' } } # Consul配置 consul['watchers'] = %w(postgresql) consul['configuration'] = { retry_join: %w[CONSUL_SECONDARY1_IP CONSUL_SECONDARY2_IP CONSUL_SECONDARY3_IP] } consul['monitoring_service_discovery'] = true -
重新配置GitLab以使更改生效:
gitlab-ctl reconfigure -
创建
.pgpass文件以便Consul能够重载PgBouncer。当被询问时输入PLAIN_TEXT_PGBOUNCER_PASSWORD两次:gitlab-ctl write-pgpass --host 127.0.0.1 --database pgbouncer --user pgbouncer --hostuser gitlab-consul -
重载PgBouncer服务:
gitlab-ctl hup pgbouncer
第4步:在辅助站点上配置备用集群
如果您要将具有单个PostgreSQL实例的辅助站点转换为Patroni集群,则必须从PostgreSQL实例开始。它将成为Patroni备用主节点实例,之后如果需要,您可以切换到另一个副本。
对于辅助站点上运行Patroni实例的每个节点:
-
通过SSH连接到您的Patroni节点并以root身份登录:
sudo -i -
选择退出自动PostgreSQL升级,以避免升级GitLab时出现意外停机。请注意在使用Geo升级PostgreSQL时的已知注意事项。尤其是对于较大的环境,PostgreSQL升级必须有计划和意识地执行。因此,请确保PostgreSQL升级成为常规维护活动的一部分。
-
编辑
/etc/gitlab/gitlab.rb并添加以下内容:每种密码类型必须在所有Geo站点中具有匹配值。
roles(['consul_role', 'patroni_role']) consul['enable'] = true consul['configuration'] = { retry_join: %w[CONSUL_SECONDARY1_IP CONSUL_SECONDARY2_IP CONSUL_SECONDARY3_IP] } consul['services'] = %w(postgresql) postgresql['md5_auth_cidr_addresses'] = [ 'PATRONI_SECONDARY1_IP/32', 'PATRONI_SECONDARY2_IP/32', 'PATRONI_SECONDARY3_IP/32', 'PATRONI_SECONDARY_PGBOUNCER/32', # 根据文档需要访问数据库的其他任何实例 ] # 将patroni节点添加到允许列表 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' # 或您之前设置的唯一复制槽名称 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 # 对于一个副本至少三个,每增加一个副本再加两个 patroni['postgresql']['max_replication_slots'] = 5 # 对于一个副本至少三个,每增加一个副本再加两个 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' # 您可以在此处改用公共或VPC地址 # GitLab Rails配置是`gitlab-ctl geo-replication-pause`所必需的 gitlab_rails['db_password'] = '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集群领导者配置的前端端口。不要使用PgBouncer前端端口。
-
重新配置GitLab以使更改生效。此步骤用于引导PostgreSQL用户和设置。
- 如果这是新安装的Patroni:
gitlab-ctl reconfigure - 如果您正在之前已有工作Patroni集群的站点上配置备用集群:
- 停止所有由Patroni管理的节点上的Patroni,包括级联副本:
gitlab-ctl stop patroni - 在主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 - 启动主Patroni节点上的Patroni以启动从主数据库的复制过程:
gitlab-ctl start patroni - 检查Patroni集群的状态:
验证:
gitlab-ctl patroni members- 当前Patroni节点出现在输出中。
- 角色为“Standby Leader”。角色可能初始显示为“Replica”。
- 停止所有由Patroni管理的节点上的Patroni,包括级联副本:
- 如果这是新安装的Patroni:
-
状态是
Running。初始时状态可能显示为Creating replica。等待节点角色稳定为 `Standby Leader` 且状态为 `Running`。这可能需要几分钟。-
当主 Patroni 节点的角色是
Standby Leader且状态为Running时,在备用集群的其他 Patroni 节点上启动 Patroni:gitlab-ctl start patroni其他 Patroni 节点应自动以副本身份加入新的备用集群,并开始从主 Patroni 节点复制数据。
-
-
验证集群状态:
gitlab-ctl patroni members确保所有 Patroni 节点都处于
Running状态。应该有一个Standby Leader节点和多个Replica节点。
将单个跟踪数据库节点迁移到 Patroni
在引入 Patroni 之前,Geo 不支持在次要站点上通过 Linux 软件包安装高可用(HA)配置。
借助 Patroni,现在可以支持高可用配置了。不过,Patroni 中的一些限制阻止在同一台机器上管理两个不同的集群。您应按照相同的说明来为新跟踪数据库设置 Patroni 集群,这些说明描述了如何为 Geo 次要站点配置 Patroni 集群。
次要节点会回填新跟踪数据库,无需数据同步。
为跟踪 PostgreSQL 数据库配置 Patroni 集群
次要 Geo 站点使用单独的 PostgreSQL 安装作为跟踪数据库,以跟踪复制状态并自动从潜在的复制问题中恢复。
如果您想在单个节点上运行 Geo 跟踪数据库,请参阅在 Geo 次要站点上配置 Geo 跟踪数据库。
Linux 软件包不支持以高可用配置运行 Geo 跟踪数据库。特别是,故障转移无法正常工作。请参阅功能请求问题。
如果您想以高可用配置运行 Geo 跟踪数据库,可以将次要站点连接到外部 PostgreSQL 数据库,例如云托管的数据库,或手动配置的 Patroni 集群(不由 GitLab Linux 软件包管理)。请遵循带有外部 PostgreSQL 实例的 Geo。
故障排除
阅读故障排除文档。