Help us learn about your current experience with the documentation. Take the survey.

为两个单节点站点设置 Geo

  • Tier: Premium, Ultimate
  • Offering: GitLab Self-Managed

本指南提供了如何使用两个 Linux 包实例部署双单节点站点 GitLab Geo 的简洁说明,无需配置外部服务。本指南也适用于基于 Docker 的安装。

先决条件:

  • 您至少有两个独立运行的 GitLab 站点。 创建站点请参考 GitLab 参考架构文档
    • 一个 GitLab 站点作为 Geo 主站点。您可以为每个 Geo 站点使用不同规模的参考架构。如果已有正在运行的 GitLab 实例,可直接用作主站点。
    • 第二个 GitLab 站点作为 Geo 从站点。Geo 支持多个从站点。
  • Geo 主站点至少需要 GitLab Premium 许可证。 所有站点只需一个许可证。
  • 确认所有站点均满足 运行 Geo 的要求

为 Linux 包 (Omnibus) 设置 Geo

先决条件:

配置主站点

对于基于 Docker 的安装:

可直接将下方设置应用到 GitLab 容器的 /etc/gitlab/gitlab.rb 文件,或在其 Docker Compose 文件中添加到 GITLAB_OMNIBUS_CONFIG 环境变量。

使用 Docker Compose 时,请使用 docker-compose -f <docker-compose-file-name>.yml up 而非 gitlab-ctl reconfigure 应用配置更改。

  1. 通过 SSH 登录 GitLab 主站点并以 root 身份登录:

    sudo -i
  2. 选择退出 PostgreSQL 自动升级 以避免升级 GitLab 时意外停机。请注意已知的 使用 Geo 升级 PostgreSQL 的注意事项。尤其对于大型环境,PostgreSQL 升级必须经过规划和有意识地执行。因此,请确保 PostgreSQL 升级成为常规维护活动的一部分。

  3. /etc/gitlab/gitlab.rb 中添加唯一的 Geo 站点名称:

    ##
    ## Geo 站点的唯一标识符。参见
    ## https://docs.gitlab.com/ee/administration/geo_sites.html#common-settings
    ##
    gitlab_rails['geo_node_name'] = '<此处填写站点名称>'
  4. 应用更改,重新配置主站点:

    gitlab-ctl reconfigure
  5. 将站点定义为主 Geo 站点:

    gitlab-ctl set-geo-primary-node

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

  6. gitlab 数据库用户创建密码并更新 Rails 使用新密码。

    gitlab_rails['db_password']postgresql['sql_user_password'] 设置的值必须匹配。 但只有 postgresql['sql_user_password'] 值应为 MD5 加密密码。 相关变更正在 重新思考我们在手册中处理 PostgreSQL 密码的方式 中讨论。

    1. 生成所需密码的 MD5 哈希值:

      gitlab-ctl pg-password-md5 gitlab
      # 输入密码: <此处填写数据库密码>
      # 确认密码: <此处填写数据库密码>
      # fca0b89a972d69f00eb3ec98a5838484
    2. 编辑 /etc/gitlab/gitlab.rb

      # 填入 `gitlab-ctl pg-password-md5 gitlab` 生成的哈希值
      postgresql['sql_user_password'] = '<数据库密码的 MD5 哈希值>'
      
      # 所有运行 Puma 或 Sidekiq 的节点都需要按以下方式指定数据库密码。
      # 如果是高可用性设置,所有应用节点都必须包含此配置。
      gitlab_rails['db_password'] = '<此处填写数据库密码>'
  7. 为数据库复制用户定义密码。 使用 /etc/gitlab/gitlab.rbpostgresql['sql_replication_user'] 设置定义的用户名。 默认值为 gitlab_replicator

    1. 生成所需密码的 MD5 哈希值:

      gitlab-ctl pg-password-md5 gitlab_replicator
      
      # 输入密码: <此处填写复制密码>
      # 确认密码: <此处填写复制密码>
      # 950233c0dfc2f39c64cf30457c3b7f1e
    2. 编辑 /etc/gitlab/gitlab.rb

      # 填入 `gitlab-ctl pg-password-md5 gitlab_replicator` 生成的哈希值
      postgresql['sql_replication_password'] = '<复制密码的 MD5 哈希值>'
    3. 可选。如果使用非 Linux 包管理的外部数据库,必须 手动创建 gitlab_replicator 用户并定义密码:

      --- 创建新用户 'replicator'
      CREATE USER gitlab_replicator;
      
      --- 设置/更改密码并授予复制权限
      ALTER USER gitlab_replicator WITH REPLICATION ENCRYPTED PASSWORD '<复制密码>';
  8. /etc/gitlab/gitlab.rb 中将角色设置为 geo_primary_role

    ## Geo 主站点角色
    roles(['geo_primary_role'])
  9. 配置 PostgreSQL 监听网络接口:

    1. 查询 Geo 站点地址,SSH 登录 Geo 站点并执行:

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

      大多数情况下,使用以下地址配置 GitLab Geo:

      配置项 地址
      postgresql['listen_address'] 主站点公有或 VPC 私有地址。
      postgresql['md5_auth_cidr_addresses'] 主从站点公有或 VPC 私有地址。

      如果使用 Google Cloud Platform、SoftLayer 或其他提供虚拟私有云 (VPC) 的供应商, 可将主从站点私有地址(对应 Google Cloud Platform 的"内部地址")用于 postgresql['md5_auth_cidr_addresses']postgresql['listen_address']

      如果需要使用 0.0.0.0* 作为 listen_address,还必须将 127.0.0.1/32 添加到 postgresql['md5_auth_cidr_addresses'] 设置,以允许 Rails 通过 127.0.0.1 连接。更多信息请参见 issue 5258

      根据您的网络配置,建议地址可能不正确。如果主从站点通过局域网 或连接可用区的虚拟网络(如 Amazon VPCGoogle VPC)连接, 应使用从站点私有地址作为 postgresql['md5_auth_cidr_addresses']

    2. /etc/gitlab/gitlab.rb 中添加以下行。请确保将 IP 地址 替换为适合您网络配置的地址:

      ##
      ## 主站点地址
      ## - 将 '<primary_node_ip>' 替换为 Geo 主站点的公有或 VPC 地址
      ##
      postgresql['listen_address'] = '<主站点 IP>'
      
      ##
      # 允许来自主从站点 IP 的 PostgreSQL 客户端认证。这些 IP 可以是
      # CIDR 格式的公有或 VPC 地址,例如 ['198.51.100.1/32', '198.51.100.2/32']
      ##
      postgresql['md5_auth_cidr_addresses'] = ['<主站点 IP>/32', '<从站点 IP>/32']
  10. 临时禁用自动数据库迁移,直到 PostgreSQL 重启并监听私有地址。 在 /etc/gitlab/gitlab.rb 中将 gitlab_rails['auto_migrate'] 设为 false:

    ## 禁用自动数据库迁移
    gitlab_rails['auto_migrate'] = false
  11. 应用这些更改,重新配置 GitLab 并重启 PostgreSQL:

    gitlab-ctl reconfigure
    gitlab-ctl restart postgresql
  12. 重新启用迁移,编辑 /etc/gitlab/gitlab.rb 并将 gitlab_rails['auto_migrate'] 改为 true

    gitlab_rails['auto_migrate'] = true

    保存文件并重新配置 GitLab:

    gitlab-ctl reconfigure

    PostgreSQL 服务器现已配置为接受远程连接

  13. 运行 netstat -plnt | grep 5432 确保 PostgreSQL 在主站点私有地址的 5432 端口监听。

  14. GitLab 重新配置时自动生成了证书。该证书 自动用于保护 PostgreSQL 流量免受窃听。 为防范主动(“中间人”)攻击, 请将证书复制到从站点:

    1. 在主站点复制 server.crt

      cat ~gitlab-psql/data/server.crt
    2. 保存输出以备配置从站点时使用。 证书不是敏感数据。

    证书使用通用 PostgreSQL 名称创建。 为防止主机名不匹配错误,复制数据库时必须使用 verify-ca 模式。

配置从服务器

  1. 通过 SSH 登录 GitLab 从站点并以 root 身份登录:

    sudo -i
  2. 选择退出 PostgreSQL 自动升级 以避免升级 GitLab 时意外停机。请注意已知的 使用 Geo 升级 PostgreSQL 的注意事项。尤其对于大型环境,PostgreSQL 升级必须经过规划和有意识地执行。因此,请确保 PostgreSQL 升级成为常规维护活动的一部分。

  3. 为防止站点配置前执行任何命令,停止应用服务器和 Sidekiq:

    gitlab-ctl stop puma
    gitlab-ctl stop sidekiq
  4. 检查到主站点 PostgreSQL 服务器的 TCP 连接

    gitlab-rake gitlab:tcp_check[<主站点 IP>,5432]

    此步骤失败可能因为使用了错误的 IP 地址,或防火墙 阻止了站点访问。请检查 IP 地址,特别注意 公有地址和私有地址的区别。 如果存在防火墙,请确保从站点允许连接到 主站点的 5432 端口。

  5. 在从站点创建名为 server.crt 的文件,并添加配置主站点时复制的证书副本。

    editor server.crt
  6. 在从站点设置 PostgreSQL TLS 验证,安装 server.crt

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

    PostgreSQL 现在验证 TLS 连接时仅识别此确切证书。 证书可被拥有私钥访问权限的人复制,而私钥仅存在于主站点。

  7. 测试 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 <主站点 IP>
    docker exec -it <容器名称> su - gitlab-psql -c '/opt/gitlab/embedded/bin/psql \
        --list \
        -U gitlab_replicator \
        -d "dbname=gitlabhq_production sslmode=verify-ca" \
        -W \
        -h <主站点 IP>'

    提示时输入为 gitlab_replicator 用户设置的明文密码。 如果一切正常,您将看到主站点数据库列表。

  8. 编辑 /etc/gitlab/gitlab.rb 并将角色设置为 geo_secondary_role

    ##
    ## Geo 从站点角色
    ## - 自动配置依赖标志以启用 Geo
    ##
    roles(['geo_secondary_role'])

    更多信息请参见 Geo 角色

  9. 配置 PostgreSQL,编辑 /etc/gitlab/gitlab.rb 并添加以下内容:

    ##
    ## 从站点地址
    ## - 将 '<secondary_site_ip>' 替换为 Geo 从站点的公有或 VPC 地址
    ##
    postgresql['listen_address'] = '<从站点 IP>'
    postgresql['md5_auth_cidr_addresses'] = ['<从站点 IP>/32']
    
    ##
    ## 数据库凭证密码(先前在主站点定义)
    ## - 此处复制主站点定义的相同值
    ##
    postgresql['sql_replication_password'] = '<复制密码的 MD5 哈希值>'
    postgresql['sql_user_password'] = '<数据库密码的 MD5 哈希值>'
    gitlab_rails['db_password'] = '<此处填写数据库密码>'

    请确保将 IP 地址替换为适合您网络配置的地址。

  10. 应用更改,重新配置 GitLab:

    gitlab-ctl reconfigure
  11. 应用 IP 地址更改,重启 PostgreSQL:

    gitlab-ctl restart postgresql

复制数据库

将从站点的数据库连接到 主站点的数据库。 您可以使用以下脚本复制数据库 并创建流复制所需的文件。

脚本使用默认的 Linux 包目录。 如果更改了默认值,请将脚本中的目录和路径名 替换为您自己的名称。

仅在从站点运行复制脚本。 脚本在运行 pg_basebackup 前会删除所有 PostgreSQL 数据, 可能导致数据丢失。

复制数据库:

  1. 通过 SSH 登录 GitLab 从站点并以 root 身份登录:

    sudo -i
  2. 为从站点选择一个数据库友好的名称作为复制槽名称。 例如,如果您的域是 secondary.geo.example.com,则使用 secondary_example 作为槽名称。 复制槽名称只能包含小写字母、数字和下划线。

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

    每个 Geo 从站点必须有唯一的复制槽名称。 两个从站点使用相同槽名称会破坏 PostgreSQL 复制。

    gitlab-ctl replicate-geo-database \
       --slot-name=<从站点名称> \
       --host=<主站点 IP> \
       --sslmode=verify-ca

    提示时输入为 gitlab_replicator 设置的明文密码。

复制过程完成。

配置新的从站点

初始复制完成后,继续在从站点配置以下项目。

快速查找授权的 SSH 密钥

按照文档配置快速查找授权的 SSH 密钥

快速查找是 Geo 必需的

认证由主站点处理。不要为从站点设置自定义认证。 任何需要访问 管理员 区域的更改都应在主站点进行,因为 从站点是只读副本。

手动复制 GitLab 密钥值

GitLab 在 /etc/gitlab/gitlab-secrets.json 中存储多个密钥值。 此 JSON 文件必须在所有站点节点上保持一致。 您必须手动将密钥文件复制到所有从站点,尽管 issue 3789 提议更改此行为。

  1. 通过 SSH 登录主站点的 Rails 节点,执行以下命令:

    sudo cat /etc/gitlab/gitlab-secrets.json

    这将显示您需要复制的密钥(JSON 格式)。

  2. 通过 SSH 登录每个 Geo 从站点节点并以 root 身份登录:

    sudo -i
  3. 备份任何现有密钥:

    mv /etc/gitlab/gitlab-secrets.json /etc/gitlab/gitlab-secrets.json.`date +%F`
  4. /etc/gitlab/gitlab-secrets.json 从主站点 Rails 节点复制到每个从站点节点。 您也可以在节点间复制粘贴文件内容:

    sudo editor /etc/gitlab/gitlab-secrets.json
    
    # 粘贴在主站点运行的 `cat` 命令输出
    # 保存并退出
  5. 确保文件权限正确:

    chown root:root /etc/gitlab/gitlab-secrets.json
    chmod 0600 /etc/gitlab/gitlab-secrets.json
  6. 应用更改,重新配置每个 Rails、Sidekiq 和 Gitaly 从站点节点:

    gitlab-ctl reconfigure
    gitlab-ctl restart

手动复制主站点 SSH 主机密钥

  1. 通过 SSH 登录每个从站点节点并以 root 身份登录:

    sudo -i
  2. 备份任何现有 SSH 主机密钥:

    find /etc/ssh -iname 'ssh_host_*' -exec cp {} {}.backup.`date +%F` \;
  3. 从主站点复制 OpenSSH 主机密钥。

    • 如果能以 root 身份访问主站点中处理 SSH 流量的节点(通常是主 GitLab Rails 应用节点):

      # 在从站点运行,将 `<primary_site_fqdn>` 替换为服务器的 IP 或 FQDN
      scp root@<主节点 FQDN>:/etc/ssh/ssh_host_*_key* /etc/ssh
    • 如果只能通过具有 sudo 权限的用户访问:

      # 在主站点节点运行:
      sudo tar --transform 's/.*\///g' -zcvf ~/geo-host-key.tar.gz /etc/ssh/ssh_host_*_key*
      
      # 在每个从站点节点运行:
      scp <具有 sudo 权限的用户>@<主站点 FQDN>:geo-host-key.tar.gz .
      tar zxvf ~/geo-host-key.tar.gz -C /etc/ssh
  4. 为每个从站点节点确保文件权限正确:

    chown root:root /etc/ssh/ssh_host_*_key*
    chmod 0600 /etc/ssh/ssh_host_*_key
  5. 验证密钥指纹匹配,在每个站点的主从节点上执行以下命令:

    for file in /etc/ssh/ssh_host_*_key; do ssh-keygen -lf $file; done

    您将看到类似以下输出:

    1024 SHA256:FEZX2jQa2bcsd/fn/uxBzxhKdx4Imc4raXrHwsbtP0M root@服务器主机名 (DSA)
    256 SHA256:uw98R35Uf+fYEQ/UnJD9Br4NXUFPv7JAUln5uHlgSeY root@服务器主机名 (ECDSA)
    256 SHA256:sqOUWcraZQKd89y/QQv/iynPTOGQxcOTIXU/LsoPmnM root@服务器主机名 (ED25519)
    2048 SHA256:qwa+rgir2Oy86QI+PZi/QVR+MSmrdrpsuH7YyKknC+s root@服务器主机名 (RSA)

    两个节点的输出应完全相同。

  6. 验证现有私钥对应的公钥是否正确:

    # 打印私钥指纹:
    for file in /etc/ssh/ssh_host_*_key; do ssh-keygen -lf $file; done
    
    # 打印公钥指纹:
    for file in /etc/ssh/ssh_host_*_key.pub; do ssh-keygen -lf $file; done

    公钥和私钥命令的输出应生成相同指纹。

  7. 为每个从站点节点重启 sshd

    # Debian 或 Ubuntu 安装
    sudo service ssh reload
    
    # CentOS 安装
    sudo service sshd reload
  8. 验证 SSH 仍正常工作,从新终端 SSH 登录 GitLab 从服务器。 如果无法连接,请确保权限正确。

添加从站点

  1. 通过 SSH 登录从站点的每个 Rails 和 Sidekiq 节点并以 root 身份登录:

    sudo -i
  2. 编辑 /etc/gitlab/gitlab.rb 并为站点添加唯一名称。

    ##
    ## Geo 站点的唯一标识符。参见
    ## https://docs.gitlab.com/ee/administration/geo_sites.html#common-settings
    ##
    gitlab_rails['geo_node_name'] = '<此处填写站点名称>'

    保存唯一名称以备后续步骤使用。

  3. 应用更改,重新配置从站点的每个 Rails 和 Sidekiq 节点。

    gitlab-ctl reconfigure
  4. 进入主节点 GitLab 实例:

    1. 在左侧边栏底部选择 管理员

    2. 选择 Geo > 站点

    3. 选择 添加站点

      添加新站点的表单,包含三个输入字段:名称、外部 URL 和内部 URL(可选)。

    4. 名称 中输入 /etc/gitlab/gitlab.rbgitlab_rails['geo_node_name'] 的值。 值必须完全匹配。

    5. 外部 URL 中输入 /etc/gitlab/gitlab.rbexternal_url 的值。 如果一个值以 / 结尾而另一个没有也没关系。否则值必须完全匹配。

    6. 可选。在 内部 URL(可选) 中输入主站点的内部 URL。

    7. 可选。选择从站点应复制的组或存储分片。要复制所有内容,请留空。参见选择性同步

    8. 选择 保存更改

  5. 通过 SSH 登录从站点的每个 Rails 和 Sidekiq 节点并重启服务:

    gitlab-ctl restart
  6. 通过运行以下命令检查 Geo 设置是否存在常见问题:

    gitlab-rake gitlab:geo:check

    如果任何检查失败,请参见故障排除文档

  7. 验证从站点是否可访问,通过 SSH 登录主站点的 Rails 或 Sidekiq 服务器并以 root 身份登录:

    gitlab-rake gitlab:geo:check

    如果任何检查失败,请检查故障排除文档

从站点添加到 Geo 管理页面并重启后, 站点会自动开始从主站点复制缺失数据, 此过程称为回填。

同时,主站点开始通知每个从站点所有变更, 以便从站点能立即处理这些通知。

确保从站点正在运行且可访问。您可以使用 与主站点相同的凭据登录从站点。

启用通过 HTTP/HTTPS 和 SSH 的 Git 访问

Geo 通过 HTTP/HTTPS 同步仓库,因此需要启用此克隆方法。 默认情况下已启用。 如果将现有站点转换为 Geo,应检查克隆方法是否已启用。

在主站点:

  1. 在左侧边栏底部选择 管理员
  2. 选择 设置 > 通用
  3. 展开 可见性和访问控制
  4. 如果使用 Git over SSH:
    1. 确保 启用的 Git 访问协议 设置为 SSH 和 HTTP(S)
    2. 在主从站点遵循数据库中快速查找授权的 SSH 密钥
  5. 如果不使用 Git over SSH,将 启用的 Git 访问协议 设置为 仅 HTTP(S)

验证从站点正常运行

您可以使用与主站点相同的凭据登录从站点。

登录后:

  1. 在左侧边栏底部选择 管理员
  2. 选择 Geo > 站点
  3. 验证站点是否正确标识为 Geo 从站点,且 Geo 已启用。

初始复制可能需要一些时间。 您可以在浏览器中通过主站点的 Geo 站点 仪表板监控每个 Geo 站点的同步过程。

显示同步状态的 Geo 站点仪表板。

相关主题