双节点 GitLab 异地灾备 Geo 搭建
后知后觉 暂无评论

双单节点搭建 Geo 异地灾备,先确保两个环境网络互通,内外网皆可,如果专线或者网络带宽小于 50Mbps,原则上不建议使用 Geo 架构。

环境一览

以异地灾备标准化环境为例:

角色地址别名
10.21.128.10beijing
10.21.125.10nanjing

环境检查

主节点校验

在执行操作前先检查主节点环境,提前进行数据校验:

## 耗时会很久,需要等待执行完毕后再进行后续操作
sudo gitlab-rake gitlab:git:fsck
sudo gitlab-rake gitlab:uploads:check

检查组件版本

因为一些同步的操作涉及系统底层组件,因此对一些系统依赖有版本要求:

小贴士:需要注意的是,Geo 为付费功能,需要授权才能使用,仅 PremiumUltimate 授权才能开启此功能。

密码关系表

内网环境可直接套用下面的模板,公网环境需按情况修改,后续会有详细说明。

用户明文密码密文密码
gitlabQpPQfKg3kd5FQ6qN2gV4peb12779c06f02a1e0cc1d3923dd91224
gitlab_replicator81mkAG9h7GOf6WJaEBdCm4d847ba79053bc8296775e4c0504b8e9

Geo Setup

主节点配置

1.进入根用户环境进行操作

sudo -i

2.配置节点跳过数据库自动升级,以防在升级 GitLab 版本时出现意外导致数据库版本不匹配,配置此项后需要定期进行 PostgreSQL 的版本升级和维护工作。

sudo touch /etc/gitlab/disable-postgresql-upgrade

3.修改主节点配置 /etc/gitlab/gitlab.rb 配置一个独一无二的节点名,例如添加:

gitlab_rails['geo_node_name'] = 'beijing'
小贴士:如果是异地灾备的情况下推荐用地域名称来作为节点唯一标识。如果是同地区灾备,可以选择以主从为节点唯一标识。

4.重新生成配置

sudo gitlab-ctl reconfigure

5.然后将节点身份配置为主节点(系统默认使用配置中的 external_url 项值)

sudo gitlab-ctl set-geo-primary-node

6.创建 Rails 数据库访问角色和密码

小贴士:命令生成的规则是密码用户拼接然后做 MD5 加密,可以使用下面的命令手动生成:

echo -n "{PASSWORD}{USERNAME}" | md5sum | awk '{print $1}'

也可以使用下面的 Python 脚本生成

import hashlib

def generate_md5_hash(password, username):
  """Generates the MD5 hash for PostgreSQL authentication."""
  combined_string = password + username
  md5_hash = hashlib.md5(combined_string.encode()).hexdigest()
  return md5_hash

password = 'password'
username = "gitlab"
md5_hash = generate_md5_hash(password, username)
print(md5_hash)

7.然后以同样的操作创建数据库流复制角色和密码

8.在 /etc/gitlab/gitlab.rb 中,设定主节点角色

roles ['geo_primary_role']

9.配置 PostgreSQL 监听网络接口

10.在数据库监听地址生效前,禁用节点数据库自动迁移功能

## Disable automatic database migrations
gitlab_rails['auto_migrate'] = false

11.应用上述所有改动并重启数据库服务

sudo gitlab-ctl reconfigure
sudo gitlab-ctl restart postgresql

12.成功后将节点数据库自动迁移功能重新启用(默认就是开启状态,因此注释掉即可)

gitlab_rails['auto_migrate'] = true

重新生成配置

sudo gitlab-ctl reconfigure

至此数据库已经可以接受来自远程的连接请求

13.检查数据库是否监听了正确的公网/私网地址

sudo ss -lntp | grep ':5432'

14.上述配置完成后会自动生成一个用于数据库连接的证书对,证书将用于数据传输过程加密,以应对 MitM 攻击,将证书下发至所有从节点

从节点配置

1.进入根用户环境进行操作

sudo -i

2.同样配置数据库升级规则

sudo touch /etc/gitlab/disable-postgresql-upgrade

3.为避免有程序占用数据库,需要停止 Application 服务和 Sidekiq 服务

sudo gitlab-ctl stop puma
sudo gitlab-ctl stop sidekiq

4.检查主从节点数据库端口 TCP 是否可达

sudo gitlab-rake gitlab:tcp_check[10.21.128.10,5432]

如果端口不可达,虚拟机实例检查防火墙配置,云服务器检查安全组配置。

5.将主节点的证书安装至从节点上,用于传输层加密

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

6.验证主从节点数据库是否可读,替换 <primary_site_ip> 为主节点地址

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>

回车后输入 gitlab_replicator 用户的密码,如果一切正常,那么会展示出主节点的数据库结构

7.修改从节点配置 /etc/gitlab/gitlab.rb 并配置从节点角色

roles ['geo_secondary_role']

8.继续配置数据库相关配置

gitlab_rails['db_password'] = 'QpPQfKg3kd5FQ6qN2gV4p'
postgresql['listen_address'] = '10.21.125.10'
postgresql['md5_auth_cidr_addresses'] = ['127.0.0.1/32','10.21.128.10/32','10.21.125.10/32']
postgresql['sql_replication_password'] = '4d847ba79053bc8296775e4c0504b8e9'
postgresql['sql_user_password'] = 'eb12779c06f02a1e0cc1d3923dd91224'

9.然后重新生成配置并重启数据库服务:

sudo gitlab-ctl reconfigure
sudo gitlab-ctl restart postgresql

同步主从数据库

1.确保上述步骤一切正常后,进入从节点并使用根用户进行操作

sudo -i

2.选择一个数据库友好的名称创建复制槽用于数据库同步,和上面的命令建议一致,如果是异地灾备,可以使用地域名称命名复制槽

特别注意:复制槽名支持下划线,同时如果存在多个从节点,那么每个从节点需要使用单独且唯一的复制槽名,如果使用相同槽名会导致数据库同步错误,同时默认的复制槽仅允许一个,需要修改配置中 postgresql['max_replication_slots'] 的值,同时如果修改的值小于已经存在的复制槽数量,会导致数据库无法启动,需要使用命令移除多余的复制槽后再降低复制槽数量。
SELECT * FROM pg_replication_slots;
SELECT pg_drop_replication_slot('your_replication_slot_name');

3.执行命令备份数据库并开始数据库同步

gitlab-ctl replicate-geo-database \
   --slot-name=<secondary_site_name> \
   --host=<primary_site_ip> \
   --sslmode=verify-ca

回车然后输入 gitlab_replicator 用户的密码开始执行数据库同步,稍等片刻后可观察到类似输出:

pg_basebackup: initiating base backup, waiting for checkpoint to complete
pg_basebackup: checkpoint completed
pg_basebackup: write-ahead log start point: 21/32EE19F8 on timeline 1
pg_basebackup: starting background WAL receiver
      0/6983185 kB (0%), 0/1 tablespace (...lab/postgresql/data/backup_label)
  13187/6983185 kB (0%), 0/1 tablespace (.../postgresql/data/base/12973/2608)
  35290/6983185 kB (0%), 0/1 tablespace (...postgresql/data/base/16386/28634)
  44921/6983185 kB (0%), 0/1 tablespace (...postgresql/data/base/16386/22686)
  60325/6983185 kB (0%), 0/1 tablespace (...postgresql/data/base/16386/23159)
  78220/6983185 kB (1%), 0/1 tablespace (...postgresql/data/base/16386/19989)
 112152/6983185 kB (1%), 0/1 tablespace (...postgresql/data/base/16386/29050)

等待进度走到 100% 即可。

配置从节点

1.配置密钥快速查找,添加对应配置块到 sshd_config

Match User git
  AuthorizedKeysCommand /opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell-authorized-keys-check git %u %k
  AuthorizedKeysCommandUser git
Match all

2.重启 SSH 守护进程

sudo systemctl restart sshd

3.在管理后台中操作,依次选择 Admin -> Settings -> Network -> Performance optimization 取消勾选 Use authorized_keys file to authenticate SSH keys 然后保存配置

4.将主节点的 /etc/gitlab/gitlab-secrets.json 同步所有认证密钥至从节点。

sudo rsync -av /etc/gitlab/gitlab-secrets.json root@10.21.125.10:/etc/gitlab/

5.然后配置服务并重启

sudo gitlab-ctl reconfigure
sudo gitlab-ctl restart

6.将主节点的 /etc/ssh/ssh_host_*_key* 同步至从节点。然后重启 SSH 服务:

sudo ls -l /etc/ssh/ssh_host_*_key*
sudo rsync -av /etc/ssh/ssh_host_*_key* root@10.21.125.10:/etc/ssh/
sudo systemctl restart sshd

添加从节点

继续修改从节点配置 /etc/gitlab/gitlab.rb,添加从节点名称:

gitlab_rails['geo_node_name'] = 'nanjing'

然后重新生成配置

sudo gitlab-ctl reconfigure

浏览器访问主节点域名,并进入管理员配置,选择添加 Geo Sites,如图所示:

adding_a_secondary

Namegitlab_rails['geo_node_name']
External URLexternal_url
Internal URL可选项,默认置空即可

同步范围默认全同步,然后保存配置即可。

登录所有的从节点重启服务

sudo gitlab-ctl restart

然后执行状态检查

sudo gitlab-rake gitlab:geo:check

Geo 控制面板

配置成功后可以在 Geo 页面中访问控制台,可以看到数据同步的进度和其他信息

geo_dashboard

故障排查

如果系统开启了 SELinux,那么在执行 Geo 检查时会遇到以下错误提示:

OpenSSH configured to use AuthorizedKeysCommand ... skipped
  Reason:
  Cannot access OpenSSH configuration file
  Try fixing it:
  This is expected if you are using SELinux. You may want to check configuration manually
  For more information see:
  doc/administration/operations/fast_ssh_key_lookup.md

要么选择关闭 SELinux,要么需要手动修改文件 ACL 规则

sudo stat -c '%G:%U %A %a %n' /etc/ssh/sshd_config
sudo setfacl -m u:git:r /etc/ssh/sshd_config

访问协议受限

需要注意的是,在 Geo 内部使用 HTTP(S) 协议进行数据同步,因此不能禁用 HTTP 访问协议,具体可以访问主节点,在管理员区域中,依次展开 Settings -> General -> Visibility and access controls -> Enabled Git access protocols -> Both SSH and HTTP(S),简而言之,在启用 Geo 后,无法实现仅允许 ssh 协议访问 GitLab 的功能。

灾难演练和恢复

当主节点出现问题时,需要手动将从节点提升为主,操作步骤可参考灾难恢复

补充

18.0 版本已知问题

升级后会看到日志中存在大量类似报错

2025-05-16_13:48:04.55854 {"time":"2025-05-16T21:48:04.558473168+08:00","level":"ERROR","msg":"Program aborted","error":"protojson.Unmarshal: proto: (line 1:50): unknown field \"gitops\""}

参考官方 issue,修改配置文件 /var/opt/gitlab/gitlab-kas/gitlab-kas-config.yml,将 gitops 项手动删除,此错误将在后续版本中修复,如果存储空间尚可满足需求下可以暂时忽略此问题。


附录

参考链接

如果遇到问题或者对文章内容存疑,请在下方留言,博主看到后将及时回复,谢谢!
回复 / 查看「历史评论
回答31+25=