双单节点搭建 Geo 异地灾备,先确保两个环境网络互通,内外网皆可,如果专线或者网络带宽小于 50Mbps,原则上不建议使用 Geo 架构。
环境一览
以异地灾备标准化环境为例:
角色 | 地址 | 别名 |
---|---|---|
主 | 10.21.128.10 | beijing |
从 | 10.21.125.10 | nanjing |
环境检查
主节点校验
在执行操作前先检查主节点环境,提前进行数据校验:
## 耗时会很久,需要等待执行完毕后再进行后续操作
sudo gitlab-rake gitlab:git:fsck
sudo gitlab-rake gitlab:uploads:check
检查组件版本
因为一些同步的操作涉及系统底层组件,因此对一些系统依赖有版本要求:
- OpenSSH 6.9+(CentOS 7.4 及以上版本/Ubuntu 16.04 及以上版本,不过强烈推荐使用最新或次新的 LTS 版本)
- glibc (原则上需要保持主从节点的操作系统版本完全一致,如果不一致需要手动检查 glibc 版本兼容性)
- PostgreSQL (须保证主从节点的数据库版本一致,如果有节点是从旧版本升级而来,可能需要手动执行命令先升级数据库版本)
- Git 2.9+
- Git-lfs 2.4.2+
- GitLab (主从节点版本必须完全一致)
- Repository storage (仓库存储位置也必须保持一致)
小贴士:需要注意的是,Geo 为付费功能,需要授权才能使用,仅Premium
和Ultimate
授权才能开启此功能。
密码关系表
内网环境可直接套用下面的模板,公网环境需按情况修改,后续会有详细说明。
用户 | 明文密码 | 密文密码 |
---|---|---|
gitlab | QpPQfKg3kd5FQ6qN2gV4p | eb12779c06f02a1e0cc1d3923dd91224 |
gitlab_replicator | 81mkAG9h7GOf6WJaEBdCm | 4d847ba79053bc8296775e4c0504b8e9 |
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 数据库访问角色和密码
先用命令生成密码加密串
sudo gitlab-ctl pg-password-md5 gitlab
然后修改配置文件
/etc/gitlab/gitlab.rb
,添加postgresql['sql_user_password'] = 'eb12779c06f02a1e0cc1d3923dd91224' gitlab_rails['db_password'] = 'QpPQfKg3kd5FQ6qN2gV4p'
小贴士:命令生成的规则是密码用户拼接然后做 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.然后以同样的操作创建数据库流复制角色和密码
【必做项】先用命令生成密码加密串,如果不使用默认的
gitlab_replicator
用户,则需要手动修改配置中postgresql['sql_replication_user']
项,非必要情况下不建议修改默认用户名。sudo gitlab-ctl pg-password-md5 gitlab_replicator
【必做项】然后修改配置文件
/etc/gitlab/gitlab.rb
,添加postgresql['sql_replication_password'] = '4d847ba79053bc8296775e4c0504b8e9'
【可选项】如果使用外置或托管数据库,需要手动创建复制角色并配置密码
CREATE USER gitlab_replicator; ALTER USER gitlab_replicator WITH REPLICATION ENCRYPTED PASSWORD '<replication_password>';
8.在 /etc/gitlab/gitlab.rb
中,设定主节点角色
roles ['geo_primary_role']
9.配置 PostgreSQL 监听网络接口
- 确定网络连通情况,如果是内网互通则使用内网地址,如果是外网互通则使用外网地址
添加下述配置至配置文件
/etc/gitlab/gitlab.rb
,确保 IP 地址替换为网络配置的地址## 需要将本地环回、本机 VPC 地址、从节点 VPC 地址都加入白名单,如果多从也按需添加即可 postgresql['listen_address'] = '10.21.128.10' postgresql['md5_auth_cidr_addresses'] = ['127.0.0.1/32','10.21.128.10/32','10.21.125.10/32']
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 攻击,将证书下发至所有从节点
检查证书是否正常生成,并存在于主节点
cat ~gitlab-psql/data/server.crt
复制上述命令输出的证书内容或将文件传输到从节点
sudo scp ~gitlab-psql/data/server.crt root@10.21.125.10:/root/
从节点配置
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,如图所示:

项 | 值 |
---|---|
Name | gitlab_rails['geo_node_name'] |
External URL | external_url |
Internal URL | 可选项,默认置空即可 |
同步范围默认全同步,然后保存配置即可。
登录所有的从节点重启服务
sudo gitlab-ctl restart
然后执行状态检查
sudo gitlab-rake gitlab:geo:check
Geo 控制面板
配置成功后可以在 Geo 页面中访问控制台,可以看到数据同步的进度和其他信息

故障排查
如果系统开启了 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
项手动删除,此错误将在后续版本中修复,如果存储空间尚可满足需求下可以暂时忽略此问题。
附录
参考链接
本文由 柒 创作,采用 知识共享署名4.0
国际许可协议进行许可。
转载本站文章前请注明出处,文章作者保留所有权限。
最后编辑时间: 2025-06-04 12:29 PM