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

参考架构:支持最高200 RPS或10,000用户

  • 层级:Premium, Ultimate
  • 提供方式:GitLab 自托管

本页描述了GitLab参考架构,旨在针对基于真实数据的每秒200次请求(RPS)峰值负载,以及最多10,000名手动和自动化用户的典型峰值负载。

有关完整参考架构列表,请参见 可用参考架构

在部署此架构之前,建议先阅读主文档 [_index.md],特别是 开始前准备决定使用哪种架构 部分。

  • 目标负载:API:200 RPS,Web:20 RPS,Git(拉取):20 RPS,Git(推送):4 RPS
  • 高可用性:是(Praefect 需要第三方 PostgreSQL 解决方案以实现高可用)
  • 云原生混合替代方案
  • 不确定该使用哪个参考架构? 前往此指南获取更多信息
服务 节点数 配置 GCP 示例1 AWS 示例1 Azure 示例1
外部负载均衡器4 1 4 vCPU,3.6 GB 内存 n1-highcpu-4 c5n.xlarge F4s v2
Consul2 3 2 vCPU,1.8 GB 内存 n1-highcpu-2 c5.large F2s v2
PostgreSQL2 3 8 vCPU,30 GB 内存 n1-standard-8 m5.2xlarge D8s v3
PgBouncer2 3 2 vCPU,1.8 GB 内存 n1-highcpu-2 c5.large F2s v2
内部负载均衡器4 1 4 vCPU,3.6 GB 内存 n1-highcpu-4 c5n.xlarge F4s v2
Redis/Sentinel - 缓存3 3 4 vCPU,15 GB 内存 n1-standard-4 m5.xlarge D4s v3
Redis/Sentinel - 持久化3 3 4 vCPU,15 GB 内存 n1-standard-4 m5.xlarge D4s v3
Gitaly67 3 16 vCPU,60 GB 内存 n1-standard-16 m5.4xlarge D16s v3
Praefect6 3 2 vCPU,1.8 GB 内存 n1-highcpu-2 c5.large F2s v2
Praefect PostgreSQL2 1+ 2 vCPU,1.8 GB 内存 n1-highcpu-2 c5.large F2s v2
Sidekiq8 4 4 vCPU,15 GB 内存 n1-standard-4 m5.xlarge D4s v3
GitLab Rails8 3 32 vCPU,28.8 GB 内存 n1-highcpu-32 c5.9xlarge F32s v2
监控节点 1 4 vCPU,3.6 GB 内存 n1-highcpu-4 c5.xlarge F4s v2
对象存储5 - - - - -

脚注

  1. 机器类型示例仅为说明用途。这些类型用于 验证和测试结果,但不作为规定性的默认值。切换到其他符合要求的机器类型(包括可用的ARM变体)是支持的。更多详情请参见 支持的机器类型

  2. 可选择运行在信誉良好的第三方外部PaaS PostgreSQL解决方案上。有关更多信息,请参见 提供您自己的PostgreSQL实例推荐的云服务商及服务

  3. 可选择运行在信誉良好的第三方外部PaaS Redis解决方案上。有关更多信息,请参见 提供您自己的Redis实例推荐的云服务商及服务

    • Redis主要是单线程的,增加CPU核心并不能显著提升性能。对于此规模架构,强烈建议按照指定配置单独设置缓存和持久化实例以获得最佳性能。
  4. 建议搭配信誉良好的第三方负载均衡器或服务(LB PaaS)运行,以提供高可用性能力。 规模大小取决于所选负载均衡器及网络带宽等额外因素。更多信息请参阅负载均衡器

  5. 应在信誉良好的云服务商或自管解决方案上运行。有关更多信息,请参见配置对象存储

  6. Gitaly 集群(Praefect)具备容错优势,但设置与管理复杂度更高。 部署 Gitaly 集群(Praefect)前,请先查阅现有技术限制与注意事项。若需分片式 Gitaly,可沿用前表中为 Gitaly 列出的相同规格。

  7. Gitaly 规格基于健康状态下使用模式与仓库规模的较高百分位数值。 但若有大型单体仓库(超过数 GB)或额外工作负载,会显著影响 Git 与 Gitaly 性能,可能还需额外调优。

  8. 可将其置于自动伸缩组(ASGs)内,因该组件不存储任何状态数据。 不过通常更推荐采用云原生混合架构,因迁移(如migrations)与 Mailroom 等组件仅能在单节点运行,Kubernetes 对此支持更佳。

对于所有涉及实例配置的 PaaS 方案,建议在三个不同可用区各部署三台节点,以契合弹性云架构实践。

@startuml 10k
skinparam linetype ortho

card "**External Load Balancer**" as elb #6a9be7
card "**Internal Load Balancer**" as ilb #9370DB

together {
  collections "**GitLab Rails** x3" as gitlab #32CD32
  collections "**Sidekiq** x4" as sidekiq #ff8dd1
}

together {
  card "**Prometheus**" as monitor #7FFFD4
  collections "**Consul** x3" as consul #e76a9b
}

card "Gitaly Cluster" as gitaly_cluster {
  collections "**Praefect** x3" as praefect #FF8C00
  collections "**Gitaly** x3" as gitaly #FF8C00
  card "**Praefect PostgreSQL***\n//Non fault-tolerant//" as praefect_postgres #FF8C00

  praefect -[#FF8C00]-> gitaly
  praefect -[#FF8C00]> praefect_postgres
}

card "Database" as database {
  collections "**PGBouncer** x3" as pgbouncer #4EA7FF
  card "**PostgreSQL** //Primary//" as postgres_primary #4EA7FF
  collections "**PostgreSQL** //Secondary// x2" as postgres_secondary #4EA7FF

  pgbouncer -[#4EA7FF]-> postgres_primary
  postgres_primary .[#4EA7FF]> postgres_secondary
}

card "redis" as redis {
  collections "**Redis Persistent** x3" as redis_persistent #FF6347
  collections "**Redis Cache** x3" as redis_cache #FF6347

  redis_cache -[hidden]-> redis_persistent
}

cloud "**Object Storage**" as object_storage #white

elb -[#6a9be7]-> gitlab
elb -[#6a9be7,norank]--> monitor

gitlab -[#32CD32,norank]--> ilb
gitlab -[#32CD32]r-> object_storage
gitlab -[#32CD32]----> redis
gitlab .[#32CD32]----> database
gitlab -[hidden]-> monitor
gitlab -[hidden]-> consul

sidekiq -[#ff8dd1,norank]--> ilb
sidekiq -[#ff8dd1]r-> object_storage
sidekiq -[#ff8dd1]----> redis
sidekiq .[#ff8dd1]----> database
sidekiq -[hidden]-> monitor
sidekiq -[hidden]-> consul

ilb -[#9370DB]--> gitaly_cluster
ilb -[#9370DB]--> database
ilb -[hidden]--> redis
ilb -[hidden]u-> consul
ilb -[hidden]u-> monitor

consul .[#e76a9b]u-> gitlab
consul .[#e76a9b]u-> sidekiq
consul .[#e76a9b]r-> monitor
consul .[#e76a9b]-> database
consul .[#e76a9b]-> gitaly_cluster
consul .[#e76a9b,norank]--> redis

monitor .[#7FFFD4]u-> gitlab
monitor .[#7FFFD4]u-> sidekiq
monitor .[#7FFFD4]> consul
monitor .[#7FFFD4]-> database
monitor .[#7FFFD4]-> gitaly_cluster
monitor .[#7FFFD4,norank]--> redis
monitor .[#7FFFD4]> ilb
monitor .[#7FFFD4,norank]u--> elb

@enduml

要求

在继续之前,请查看参考架构的要求

测试方法

支持 200 RPS / 10000 用户的参考架构旨在满足大多数常见工作流程。GitLab 定期针对以下端点吞吐量目标进行冒烟测试和性能测试:

端点类型 目标吞吐量
API 200 RPS
Web 20 RPS
Git (Pull) 20 RPS
Git (Push) 4 RPS

这些目标基于实际客户数据,反映了指定用户数量的总环境负载,包括 CI 管道和其他工作负载。

有关我们的测试方法的更多信息,请参阅验证和测试结果 部分。

性能考虑因素

如果您的环境存在以下情况,可能需要进行额外的调整:

在这些情况下,请参阅扩展环境 了解更多信息。如果您认为这些考虑因素适用于您,请联系我们获取所需的额外指导。

负载均衡器配置

我们的测试环境使用:

  • Linux 包环境的 HAProxy
  • 云原生混合环境的云提供商等效方案(搭配 NGINX Ingress)

设置组件

要将 GitLab 及其组件设置为支持最多 200 RPS 或 10000 用户:

  1. 配置外部负载均衡器,以处理 GitLab 应用服务节点的负载均衡。
  2. 配置内部负载均衡器,以处理 GitLab 应用内部连接的负载均衡。
  3. 配置 Consul,用于服务发现和健康检查。
  4. 配置 PostgreSQL,即 GitLab 的数据库。
  5. 配置 PgBouncer,用于数据库连接池和管理。
  6. 配置 Redis,它存储会话数据、临时缓存信息和后台任务队列。
  7. 配置 Gitaly 集群(Praefect),提供对 Git 仓库的访问。
  8. 配置 Sidekiq,用于后台任务处理。
  9. 配置主 GitLab Rails 应用程序,运行 Puma、Workhorse、GitLab Shell,并处理所有前端请求(包括 UI、API 和通过 HTTP/SSH 的 Git 访问)。
  10. 配置 Prometheus,监控您的 GitLab 环境。
  11. 配置对象存储,用于共享数据对象。
  12. 配置高级搜索(可选),在整个 GitLab 实例中进行更快、更高级的代码搜索。

服务器启动于同一 10.6.0.0/24 私有网络范围内,并可在此类地址上自由互连。

以下列表包含各服务器的说明及其分配的 IP:

  • 10.6.0.10:外部负载均衡器
  • 10.6.0.11:Consul 节点 1
  • 10.6.0.12:Consul 节点 2
  • 10.6.0.13:Consul 节点 3
  • 10.6.0.21:PostgreSQL 主节点
  • 10.6.0.22:PostgreSQL 从节点 1
  • 10.6.0.23:PostgreSQL 从节点 2
  • 10.6.0.31:PgBouncer 1
  • 10.6.0.32:PgBouncer 2
  • 10.6.0.33:PgBouncer 3
  • 10.6.0.40:内部负载均衡器
  • 10.6.0.51:Redis - 缓存主节点
  • 10.6.0.52:Redis - 缓存从节点 1
  • 10.6.0.53:Redis - 缓存从节点 2
  • 10.6.0.61:Redis - 持久化主节点
  • 10.6.0.62:Redis - 持久化从节点 1
  • 10.6.0.63:Redis - 持久化从节点 2
  • 10.6.0.91:Gitaly 1
  • 10.6.0.92:Gitaly 2
  • 10.6.0.93:Gitaly 3
  • 10.6.0.131:Praefect 1
  • 10.6.0.132:Praefect 2
  • 10.6.0.133:Praefect 3
  • 10.6.0.141:Praefect PostgreSQL 1(非高可用)
  • 10.6.0.101:Sidekiq 1
  • 10.6.0.102:Sidekiq 2
  • 10.6.0.103:Sidekiq 3
  • 10.6.0.104:Sidekiq 4
  • 10.6.0.111:GitLab 应用 1
  • 10.6.0.112:GitLab 应用 2
  • 10.6.0.113:GitLab 应用 3
  • 10.6.0.151:Prometheus

配置外部负载均衡器

在多节点 GitLab 配置中,您需要一个外部负载均衡器将流量路由到应用服务器。

关于使用哪种负载均衡器或其具体配置的详细信息超出了 GitLab 文档的范围,但可参阅负载均衡器 了解通用要求的更多信息。本节将重点介绍如何为您选择的负载均衡器配置具体细节。

就绪检查

确保外部负载均衡器仅将流量路由到带有内置监控端点的正常服务。所有就绪检查都需要在被检查节点上进行额外配置,否则外部负载均衡器将无法连接。

端口

基本使用的端口如下表所示:

负载均衡器端口 后端端口 协议
80 80 HTTP (1)
443 443 TCP 或 HTTPS (1) (2)
22 22 TCP
  • (1): Web终端支持要求您的负载均衡器正确处理WebSocket连接。当使用HTTP或HTTPS代理时,这意味着您的负载均衡器必须配置为传递ConnectionUpgrade逐跳头信息。有关更多详情,请参阅web终端集成指南
  • (2): 当对443端口使用HTTPS协议时,您必须在负载均衡器上添加SSL证书。如果您希望在GitLab应用服务器终止SSL,则使用TCP协议。

如果您使用具有自定义域支持的GitLab Pages,则需要一些额外的端口配置。 GitLab Pages需要一个单独的虚拟IP地址。配置DNS以将/etc/gitlab/gitlab.rb中的pages_external_url指向新的虚拟IP地址。有关更多信息,请参阅GitLab Pages文档

负载均衡器端口 后端端口 协议
80 可变 (1) HTTP
443 可变 (1) TCP (2)
  • (1): GitLab Pages的后端端口取决于gitlab_pages['external_http']gitlab_pages['external_https']设置。有关更多详情,请参阅GitLab Pages文档
  • (2): GitLab Pages的443端口应始终使用TCP协议。用户可以使用自定义SSL配置自定义域名,如果SSL在负载均衡器处终止,这将是不可能的。

替代SSH端口

有些组织有禁止开放SSH端口22的政策。在这种情况下,配置替代SSH主机名可能有助于用户使用443端口的SSH。与之前记录的其他GitLab HTTP配置相比,替代SSH主机名将需要一个新的虚拟IP地址。

为替代SSH主机名(如altssh.gitlab.example.com)配置DNS。

负载均衡器端口 后端端口 协议
443 22 TCP

SSL

下一个问题是您如何在环境中处理SSL。 有以下几种不同的选项:

应用节点终止SSL

将负载均衡器配置为通过TCP而不是HTTP(S)协议传递443端口的连接。这将把未修改的连接传递给应用节点的NGINX服务。NGINX将拥有SSL证书并在443端口监听。

有关管理SSL证书和配置NGINX的详细信息,请参阅HTTPS文档

负载均衡器终止SSL且后端不使用SSL

将负载均衡器配置为使用HTTP(S)协议而不是TCP。然后负载均衡器将负责管理SSL证书并终止SSL。

由于负载均衡器和GitLab之间的通信不安全,因此需要进行一些额外的配置。有关详细信息,请参阅代理SSL文档

负载均衡器终止SSL并使用后端SSL

将负载均衡器配置为使用’HTTP(S)‘协议而非’TCP’。负载均衡器将负责管理最终用户可见的SSL证书。

在此场景下,负载均衡器与NGINX间的流量也会是安全的。由于连接全程加密,无需额外添加代理SSL配置。但需在GitLab中添加配置以启用SSL证书功能。有关管理SSL证书及配置NGINX的详情,请参阅HTTPS文档

配置内部负载均衡器

在多节点GitLab架构中,若配置了如连接至PgBouncerGitaly Cluster (Praefect)等内部组件,则需部署内部负载均衡器来路由这些组件的流量。

选择何种负载均衡器及其具体配置细节超出GitLab文档范围,可参考Load Balancers了解通用需求。本节聚焦于为您所选负载均衡器配置的具体事项。

以下IP地址作为示例:

  • 10.6.0.40: 内部负载均衡器

通过HAProxy实现的方式如下:

global
    log /dev/log local0
    log localhost local1 notice
    log stdout format raw local0

defaults
    log global
    default-server inter 10s fall 3 rise 2
    balance leastconn

frontend internal-pgbouncer-tcp-in
    bind *:6432
    mode tcp
    option tcplog

    default_backend pgbouncer

frontend internal-praefect-tcp-in
    bind *:2305
    mode tcp
    option tcplog
    option clitcpka

    default_backend praefect

backend pgbouncer
    mode tcp
    option tcp-check

    server pgbouncer1 10.6.0.31:6432 check
    server pgbouncer2 10.6.0.32:6432 check
    server pgbouncer3 10.6.0.33:6432 check

backend praefect
    mode tcp
    option tcp-check
    option srvtcpka

    server praefect1 10.6.0.131:2305 check
    server praefect2 10.6.0.132:2305 check
    server praefect3 10.6.0.133:2305 check

请查阅您所用负载均衡器的官方文档获取更多指引。

配置 Consul

接下来,我们设置 Consul 服务器。

Consul 必须部署在至少 3 个且数量为奇数的节点上。这是为了确保节点能作为法定人数的一部分进行投票。

以下 IP 将用作示例:

  • 10.6.0.11:Consul 1
  • 10.6.0.12:Consul 2
  • 10.6.0.13:Consul 3

要配置 Consul:

  1. 通过 SSH 登录到将要托管 Consul 的服务器。

  2. 下载并安装 您选择的 Linux 包。请确保仅添加 GitLab 软件包仓库,并为所选操作系统安装 GitLab。选择与当前安装相同的版本和类型(社区版或企业版)。

  3. 编辑 /etc/gitlab/gitlab.rb 并添加以下内容:

    roles(['consul_role'])
    
    ## 启用 Prometheus 的服务发现功能
    consul['monitoring_service_discovery'] =  true
    
    ## Consul 服务节点的 IP 地址
    ## 您也可以使用 FQDN,并与 IP 混合使用
    consul['configuration'] = {
       server: true,
       retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
    }
    
    # 设置导出器监听的网路地址
    node_exporter['listen_address'] = '0.0.0.0:9100'
    
    # 防止升级时自动运行数据库迁移
    gitlab_rails['auto_migrate'] = false
  4. 从您配置的第一个 Linux 包节点复制 /etc/gitlab/gitlab-secrets.json 文件,并将同名文件添加或替换到此服务器上。如果这是您正在配置的第一个 Linux 包节点,则可以跳过此步骤。

  5. 重新配置 GitLab,使更改生效。

  6. 对所有其他 Consul 节点重复上述步骤,并确保设置了正确的 IP。

当第三个 Consul 服务器配置完成后,会选举出一个 Consul 领导者。查看 Consul 日志 sudo gitlab-ctl tail consul 会显示 ...[INFO] consul: New leader elected: ...

您可以列出当前的 Consul 成员(服务器、客户端):

sudo /opt/gitlab/embedded/bin/consul members

您可以验证 GitLab 服务是否正在运行:

sudo gitlab-ctl status

输出应类似于以下内容:

run: consul: (pid 30074) 76834s; run: log: (pid 29740) 76844s
run: logrotate: (pid 30925) 3041s; run: log: (pid 29649) 76861s
run: node-exporter: (pid 30093) 76833s; run: log: (pid 29663) 76855s

配置 PostgreSQL

在本节中,我们将指导您配置用于 GitLab 的高可用 PostgreSQL 集群。

提供自己的 PostgreSQL 实例

您可以选择使用 第三方外部 PostgreSQL 服务

为此应使用信誉良好的提供商或解决方案。Google Cloud SQLAmazon RDS 已知可正常工作。然而,Amazon Aurora 在默认启用负载均衡的情况下与 14.4.0 不兼容

有关更多信息,请参阅 推荐云提供商和服务

如果您使用第三方外部服务:

  1. HA Linux 包的 PostgreSQL 安装包含 PostgreSQL、PgBouncer 和 Consul。使用第三方外部服务时,这些组件不再需要。
  2. 根据 数据库要求文档 设置 PostgreSQL。
  3. 创建一个名为 gitlab 的用户,并设置您选择的密码。gitlab 用户需要有创建 gitlabhq_production 数据库的权限。
  4. 使用适当的详细信息配置 GitLab 应用程序服务器。此步骤将在 配置 GitLab Rails 应用程序 中介绍。
  5. 实现 HA 所需的节点数量可能因服务而异,也可能与 Linux 包不同。
  6. 但是,如果希望通过读副本实现 数据库负载均衡 以进一步提高性能,建议遵循参考架构的节点数量。

使用Linux包的独立PostgreSQL

推荐用于具备复制与故障转移功能的PostgreSQL集群的Linux包配置需满足以下条件:

  • 至少三个PostgreSQL节点。
  • 至少三个Consul服务器节点。
  • 至少三个PgBouncer节点,用于跟踪和处理主数据库的读写操作。
  • 启用数据库负载均衡

需在每个PostgreSQL节点上配置本地PgBouncer服务。该服务与跟踪主节点的核心PgBouncer集群相互独立。

以下IP地址将作为示例:

  • 10.6.0.21:PostgreSQL主节点
  • 10.6.0.22:PostgreSQL从节点1
  • 10.6.0.23:PostgreSQL从节点2

首先,确保在每个节点安装Linux GitLab包。请仅添加GitLab包仓库并为所选操作系统安装GitLab,但不要提供EXTERNAL_URL值。

PostgreSQL 节点

  1. 通过 SSH 登录到其中一个 PostgreSQL 节点。

  2. 为 PostgreSQL 用户名/密码对生成密码哈希。这假设你将使用默认的用户名 gitlab(推荐)。该命令会请求一个密码并确认。使用此命令输出的值在下一步中作为 <postgresql_password_hash> 的值:

    sudo gitlab-ctl pg-password-md5 gitlab
  3. 为 PgBouncer 用户名/密码对生成密码哈希。这假设你将使用默认的用户名 pgbouncer(推荐)。该命令会请求一个密码并确认。使用此命令输出的值在下一步中作为 <pgbouncer_password_hash> 的值:

    sudo gitlab-ctl pg-password-md5 pgbouncer
  4. 为 PostgreSQL 复制用户名/密码对生成密码哈希。这假设你将使用默认的用户名 gitlab_replicator(推荐)。该命令会请求一个密码并确认。使用此命令输出的值在下一步中作为 <postgresql_replication_password_hash> 的值:

    sudo gitlab-ctl pg-password-md5 gitlab_replicator
  5. 为 Consul 数据库用户名/密码对生成密码哈希。这假设你将使用默认的用户名 gitlab-consul(推荐)。该命令会请求一个密码并确认。使用此命令输出的值在下一步中作为 <consul_password_hash> 的值:

    sudo gitlab-ctl pg-password-md5 gitlab-consul
  6. 在每台数据库节点上,编辑 /etc/gitlab/gitlab.rb,替换 # START user configuration 部分中注明的值:

    # 禁用除 Patroni、PgBouncer 和 Consul 外的所有组件
    roles(['patroni_role', 'pgbouncer_role'])
    
    # PostgreSQL 配置
    postgresql['listen_address'] = '0.0.0.0'
    
    # 将 `max_replication_slots` 设置为数据库节点数量的两倍。
    # Patroni 在启动复制时会为每个节点额外使用一个槽位。
    patroni['postgresql']['max_replication_slots'] = 6
    
    # 将 `max_wal_senders` 设置为集群中复制槽数量加一。
    # 这用于防止复制耗尽所有可用的数据库连接。
    patroni['postgresql']['max_wal_senders'] = 7
    
    # 防止数据库迁移在升级时自动运行
    gitlab_rails['auto_migrate'] = false
    
    # 配置 Consul 代理
    consul['services'] = %w(postgresql)
    ## 启用 Prometheus 的服务发现
    consul['monitoring_service_discovery'] =  true
    
    # START user configuration
    # 请按照“必需信息”部分所述设置真实值
    #
    # 将 PGBOUNCER_PASSWORD_HASH 替换为生成的 md5 值
    postgresql['pgbouncer_user_password'] = '<pgbouncer_password_hash>'
    # 将 POSTGRESQL_REPLICATION_PASSWORD_HASH 替换为生成的 md5 值
    postgresql['sql_replication_password'] = '<postgresql_replication_password_hash>'
    # 将 POSTGRESQL_PASSWORD_HASH 替换为生成的 md5 值
    postgresql['sql_user_password'] = '<postgresql_password_hash>'
    
    # 为 Patroni API 设置基本身份验证(所有节点使用相同的用户名/密码)。
    patroni['username'] = '<patroni_api_username>'
    patroni['password'] = '<patroni_api_password>'
    
    # 将 10.6.0.0/24 替换为网络地址
    postgresql['trust_auth_cidr_addresses'] = %w(10.6.0.0/24 127.0.0.1/32)
    
    # 本地 PgBouncer 服务用于数据库负载均衡
    pgbouncer['databases'] = {
       gitlabhq_production: {
          host: "127.0.0.1",
          user: "pgbouncer",
          password: '<pgbouncer_password_hash>'
       }
    }
    
    # 设置导出器监听的网络地址以供监控
    node_exporter['listen_address'] = '0.0.0.0:9100'
    postgres_exporter['listen_address'] = '0.0.0.0:9187'
    
    ## Consul 服务器节点的 IP 地址
    ## 你也可以使用 FQDN 并将其与 IP 混合使用
    consul['configuration'] = {
       retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
    }
    #
    # END user configuration

由 Patroni 管理故障转移的 PostgreSQL 默认使用 pg_rewind 处理冲突。与大多数故障转移处理方法一样,这有很小的可能导致数据丢失。更多信息,请参阅各种 Patroni 复制方法

  1. 从你配置的第一个 Linux 包节点复制 /etc/gitlab/gitlab-secrets.json 文件,并将同名文件添加或替换到此服务器上。如果这是你要配置的第一个 Linux 包节点,则可以跳过此步骤。

  2. 重新配置 GitLab 以使更改生效。

支持高级配置选项,如果需要可以添加。

PostgreSQL 后续配置

通过 SSH 登录到主站点的任意一个 Patroni 节点:

  1. 检查领导者(leader)和集群的状态:

    gitlab-ctl patroni members

    输出应类似于以下内容:

    | 集群       | 成员                            | 主机     | 角色   | 状态   | TL  | 滞后量(MB) | 待重启 |
    |------------|---------------------------------|----------|--------|---------|-----|--------------|--------|
    | postgresql-ha | <PostgreSQL 主节点主机名>      | 10.6.0.21 | Leader | running | 175 |              | *      |
    | postgresql-ha | <PostgreSQL 从节点1主机名>      | 10.6.0.22 |        | running | 175 | 0            | *      |
    | postgresql-ha | <PostgreSQL 从节点2主机名>      | 10.6.0.23 |        | running | 175 | 0            | *      |

如果任何节点的“State”列显示的不是“running”,请在继续操作前查看 PostgreSQL 复制与故障转移故障排查章节

配置 PgBouncer

既然 PostgreSQL 服务器都已设置完毕,让我们配置 PgBouncer 来跟踪和处理对主数据库的读写操作。

PgBouncer 是单线程的,增加 CPU 核心并不能带来显著的性能提升。 有关更多信息,请参阅 扩展文档

以下 IP 将用作示例:

  • 10.6.0.31:PgBouncer 1
  • 10.6.0.32:PgBouncer 2
  • 10.6.0.33:PgBouncer 3
  1. 在每个 PgBouncer 节点上,编辑 /etc/gitlab/gitlab.rb,并将 <consul_password_hash><pgbouncer_password_hash> 替换为你之前设置的密码哈希(参见 #postgresql-nodes):

    # 禁用所有组件,仅启用 PgBouncer 和 Consul 代理
    roles(['pgbouncer_role'])
    
    # 配置 PgBouncer
    pgbouncer['admin_users'] = %w(pgbouncer gitlab-consul)
    pgbouncer['users'] = {
       'gitlab-consul': {
          password: '<consul_password_hash>'
       },
       'pgbouncer': {
          password: '<pgbouncer_password_hash>'
       }
    }
    
    # 配置 Consul 代理
    consul['watchers'] = %w(postgresql)
    consul['configuration'] = {
    retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13)
    }
    
    # 为 Prometheus 启用服务发现
    consul['monitoring_service_discovery'] = true
    
    # 设置导出器监听的网路地址
    node_exporter['listen_address'] = '0.0.0.0:9100'
  2. 从你配置的第一个 Linux 包节点复制 /etc/gitlab/gitlab-secrets.json 文件,并在此服务器上添加或替换同名文件。如果你正在配置的是第一个 Linux 包节点,则可以跳过此步骤。

  3. 重新配置 GitLab,使更改生效。

    如果出现 execute[generate databases.ini] 错误,这是因为一个已知的 问题。 在下一步之后运行第二次 reconfigure 时,该问题将被解决。

  4. 创建 .pgpass 文件,以便 Consul 能够重新加载 PgBouncer。当被询问时,输入 PgBouncer 密码两次:

    gitlab-ctl write-pgpass --host 127.0.0.1 --database pgbouncer --user pgbouncer --hostuser gitlab-consul
  5. 再次 重新配置 GitLab,以解决前一步骤中可能出现的任何潜在错误。

  6. 确保每个节点都连接到当前的主库:

    gitlab-ctl pgb-console # 你会被提示输入 PGBOUNCER_PASSWORD
  7. 当控制台提示符可用后,运行以下查询:

    show databases ; show clients ;

    输出应类似于以下内容:

            name         |  host       | port |      database       | force_user | pool_size | reserve_pool | pool_mode | max_connections | current_connections
    ---------------------+-------------+------+---------------------+------------+-----------+--------------+-----------+-----------------+---------------------
     gitlabhq_production | MASTER_HOST | 5432 | gitlabhq_production |            |        20 |            0 |           |               0 |                   0
     pgbouncer           |             | 6432 | pgbouncer           | pgbouncer  |         2 |            0 | statement |               0 |                   0
    (2 rows)
    
     type |   user    |      database       |  state  |   addr         | port  | local_addr | local_port |    connect_time     |    request_time     |    ptr    | link | remote_pid | tls
    ------+-----------+---------------------+---------+----------------+-------+------------+------------+---------------------+---------------------+-----------+------+------------+-----
     C    | pgbouncer | pgbouncer           | active  | 127.0.0.1      | 56846 | 127.0.0.1  |       6432 | 2017-08-21 18:09:59 | 2017-08-21 18:10:48 | 0x22b3880 |      |          0 |
    (2 rows)

配置 Redis

在可扩展环境中使用 Redis 是可能的,采用主(Primary)x 从(Replica)拓扑结构,并搭配 Redis Sentinel 服务来监控和自动执行故障转移流程。

Redis 集群必须以奇数个节点(至少 3 个)进行部署。这是为了确保 Redis Sentinel 能够参与投票形成仲裁(quorum)。当通过外部方式(如云服务提供商的服务)配置 Redis 时,此要求不适用。

Redis 主要为单线程,增加 CPU 核心数量不会带来显著性能提升。对于这种规模的架构,强烈建议按照指定要求分别设置缓存(Cache)和持久化(Persistent)实例,以达到最佳性能。更多信息请参阅「环境扩容」文档。

如果与 Sentinel 配合使用,Redis 需要身份验证。有关详细信息,请参阅 Redis 安全 文档。我们建议结合 Redis 密码和严格的防火墙规则来保护您的 Redis 服务。 在将 Redis 与 GitLab 配置之前,强烈建议您阅读 Redis Sentinel 文档,以全面了解其拓扑结构和架构。

Redis 安装需满足以下要求:

  1. 所有 Redis 节点必须能够相互通信,并接受来自 Redis(6379)和 Sentinel(26379)端口的入站连接(除非您更改了默认端口)。
  2. 承载 GitLab 应用程序的服务器必须能够访问 Redis 节点。
  3. 使用防火墙等选项,防止节点被外部网络(互联网)访问。

在本节中,我们将指导您配置两个用于 GitLab 的外部 Redis 集群。以下是示例使用的 IP 地址:

  • 10.6.0.51:Redis - 缓存 主节点
  • 10.6.0.52:Redis - 缓存 从节点 1
  • 10.6.0.53:Redis - 缓存 从节点 2
  • 10.6.0.61:Redis - 持久化 主节点
  • 10.6.0.62:Redis - 持久化 从节点 1
  • 10.6.0.63:Redis - 持久化 从节点 2

提供自己的 Redis 实例

您可以选用第三方外部服务作为 Redis 缓存和持久化实例(参考「外部复制与故障转移」文档),需遵循以下指引:

  • 应使用信誉良好的提供商或解决方案。已知 Google Memorystore 和 AWS ElastiCache 可正常工作。
  • Redis 集群模式不被支持,但带有高可用(HA)功能的 Redis 单机版是被支持的。
  • 您必须根据您的配置设置 Redis 的驱逐策略。

更多信息,请参阅「推荐云服务商与服务」。

配置 Redis 缓存集群

本节将指导您安装和设置新的 Redis 缓存实例。

主节点和从节点的 Redis 节点都需要在 redis['password'] 中定义相同的密码。在任何故障转移期间,Sentinel 可以重新配置节点,将其状态从主节点变为从节点(反之亦然)。

配置主Redis缓存节点

  1. 通过SSH连接到Redis服务器。

  2. 下载并安装您选择的Linux软件包。请确保仅添加GitLab软件包仓库,并为您的操作系统安装GitLab。选择与当前安装相同的版本和类型(社区版或企业版)。

  3. 编辑 /etc/gitlab/gitlab.rb 并添加以下内容:

    # 指定服务器角色为'redis_master_role',包含Sentinel和Consul代理
    roles ['redis_sentinel_role', 'redis_master_role', 'consul_role']
    
    # 设置Redis Sentinel服务的IP绑定地址和Quorum数量
    sentinel['bind'] = '0.0.0.0'
    sentinel['quorum'] = 2
    
    # 指向本地IP地址,其他机器可以通过该地址访问。
    # 您也可以将绑定设置为'0.0.0.0'以监听所有接口。
    # 如果必须绑定到可外部访问的IP,
    # 请务必添加额外的防火墙规则以防止未经授权的访问。
    redis['bind'] = '10.6.0.51'
    
    # 定义端口,使Redis能够监听TCP请求,从而允许其他机器连接到它。
    redis['port'] = 6379
    
    ## 主Redis服务器的端口,用于Sentinel,取消注释可更改为非默认值。默认值为`6379`。
    #redis['master_port'] = 6379
    
    # 为Redis和副本设置密码认证(所有节点使用相同密码)。
    redis['password'] = 'REDIS_PRIMARY_PASSWORD_OF_FIRST_CLUSTER'
    redis['master_password'] = 'REDIS_PRIMARY_PASSWORD_OF_FIRST_CLUSTER'
    
    ## 所有Redis节点必须相同
    redis['master_name'] = 'gitlab-redis-cache'
    
    ## 此主Redis节点的IP地址。
    redis['master_ip'] = '10.6.0.51'
    
    # 将Redis缓存实例设置为LRU
    # 可用RAM的90%(以MB为单位)
    redis['maxmemory'] = '13500mb'
    redis['maxmemory_policy'] = "allkeys-lru"
    redis['maxmemory_samples'] = 5
    
    ## 启用Prometheus的服务发现功能
    consul['monitoring_service_discovery'] =  true
    
    ## Consul服务器节点的IP地址
    ## 您也可以使用FQDN,并与IP混合使用
    consul['configuration'] = {
       retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
    }
    
    # 设置导出器监听的网路地址
    node_exporter['listen_address'] = '0.0.0.0:9100'
    redis_exporter['listen_address'] = '0.0.0.0:9121'
    redis_exporter['flags'] = {
         'redis.addr' => 'redis://10.6.0.51:6379',
         'redis.password' => 'redis-password-goes-here',
    }
    
    # 防止在升级时自动运行数据库迁移
    gitlab_rails['auto_migrate'] = false
  4. 复制 /etc/gitlab/gitlab-secrets.json 文件(来自您配置的第一个Linux软件包节点),并将其替换为此服务器上同名的文件。如果这是您正在配置的第一个Linux软件包节点,则可以跳过此步骤。

  5. 重新配置GitLab 以使更改生效。

#### 配置副本 Redis 缓存节点

1. 通过 SSH 登录到 **副本** Redis 服务器。
1. [下载并安装](../../install/package/_index.md#supported-platforms) 你选择的 Linux 软件包。请确保仅添加 GitLab 软件包仓库,并为所选操作系统安装 GitLab。选择与当前安装相同的版本和类型(社区版或企业版)。
1. 编辑 `/etc/gitlab/gitlab.rb` 并添加与前一部分中主节点相同的内容,将 `redis_master_node` 替换为 `redis_replica_node`
   ```ruby
   # 指定服务器角色为 'redis_sentinel_role' 和 'redis_replica_role'
   roles ['redis_sentinel_role', 'redis_replica_role', 'consul_role']

   # 为 Redis Sentinel 服务设置 IP 绑定地址和 Quorum 数量
   sentinel['bind'] = '0.0.0.0'
   sentinel['quorum'] = 2

   # 指向本地 IP 地址,其他机器可通过该地址访问。
   # 你也可以将 bind 设置为 '0.0.0.0' 以监听所有接口。
   # 如果必须绑定到可外部访问的 IP,请确保添加额外的防火墙规则以防止未经授权的访问。
   redis['bind'] = '10.6.0.52'

   # 定义端口,使 Redis 能够监听 TCP 请求,从而允许其他机器连接。
   redis['port'] = 6379

   ## 主 Redis 服务器的端口(用于 Sentinel),取消注释可修改默认值。默认为 `6379`。
   #redis['master_port'] = 6379

   # 为 Redis 和副本设置密码认证(所有节点使用相同密码)。
   redis['password'] = 'REDIS_PRIMARY_PASSWORD_OF_FIRST_CLUSTER'
   redis['master_password'] = 'REDIS_PRIMARY_PASSWORD_OF_FIRST_CLUSTER'

   ## 所有 Redis 节点必须相同
   redis['master_name'] = 'gitlab-redis-cache'

   ## 主 Redis 节点的 IP 地址。
   redis['master_ip'] = '10.6.0.51'

   # 将 Redis 缓存实例设置为 LRU
   # 可用 RAM 的 90%(单位:MB)
   redis['maxmemory'] = '13500mb'
   redis['maxmemory_policy'] = "allkeys-lru"
   redis['maxmemory_samples'] = 5

   ## 启用 Prometheus 的服务发现功能
   consul['monitoring_service_discovery'] =  true

   ## Consul 服务器节点的 IP 地址
   ## 你也可以使用 FQDN,并与 IP 混合使用
   consul['configuration'] = {
      retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
   }

   # 设置 exporter 监听的网路地址
   node_exporter['listen_address'] = '0.0.0.0:9100'
   redis_exporter['listen_address'] = '0.0.0.0:9121'
   redis_exporter['flags'] = {
        'redis.addr' => 'redis://10.6.0.52:6379',
        'redis.password' => 'redis-password-goes-here',
   }

   # 防止升级时自动运行数据库迁移
   gitlab_rails['auto_migrate'] = false
  1. 从你配置的第一个 Linux 软件包节点复制 /etc/gitlab/gitlab-secrets.json 文件,并将此服务器上同名的文件添加或替换。如果这是你要配置的第一个 Linux 软件包节点,则可以跳过此步骤。

  2. 重新配置 GitLab,使更改生效。

  3. 对所有其他副本节点重复上述步骤,并确保正确设置 IP 地址。

支持高级配置选项,如有需要可添加。

配置 Redis 持久集群

本节我们将安装和设置新的 Redis 持久实例。

主节点和副本 Redis 节点都需要在 redis['password'] 中定义相同的密码。在任何故障转移期间,Sentinel 可以重新配置节点,将其状态从主节点更改为副本(反之亦然)。


#### 配置主Redis持久节点

1. 通过SSH连接到**主**Redis服务器。
1. [下载并安装](../../install/package/_index.md#supported-platforms)您选择的Linux软件包。请确保仅添加GitLab软件包仓库,并为您的操作系统安装GitLab。选择与当前安装相同的版本和类型(社区版或企业版)。
1. 编辑 `/etc/gitlab/gitlab.rb` 并添加以下内容:

   ```ruby
   # 指定服务器角色为带有Sentinel和Consul代理的'redis_master_role'
   roles ['redis_sentinel_role', 'redis_master_role', 'consul_role']

   # 为Redis Sentinel服务设置IP绑定地址和法定人数
   sentinel['bind'] = '0.0.0.0'
   sentinel['quorum'] = 2

   # 指向本地IP地址,其他机器可以访问该地址。
   # 您也可以将bind设置为'0.0.0.0'以监听所有接口。
   # 如果必须绑定到可外部访问的IP,
   # 请务必添加额外的防火墙规则以防止未经授权的访问。
   redis['bind'] = '10.6.0.61'

   # 定义一个端口,使Redis能够监听TCP请求,从而允许其他机器连接到它。
   redis['port'] = 6379

   ## 主Redis服务器用于Sentinel的端口,取消注释可修改为非默认值。默认值为`6379`。
   #redis['master_port'] = 6379

   # 为Redis和副本设置密码认证(所有节点使用相同密码)。
   redis['password'] = 'REDIS_PRIMARY_PASSWORD_OF_SECOND_CLUSTER'
   redis['master_password'] = 'REDIS_PRIMARY_PASSWORD_OF_SECOND_CLUSTER'

   ## 所有Redis节点必须相同
   redis['master_name'] = 'gitlab-redis-persistent'

   ## 此主Redis节点的IP地址。
   redis['master_ip'] = '10.6.0.61'

   ## 启用Prometheus的服务发现
   consul['monitoring_service_discovery'] =  true

   ## Consul服务器节点的IP地址
   ## 您也可以使用FQDN,并与IP混合使用
   consul['configuration'] = {
      retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
   }

   # 设置exporters将监听的网路地址
   node_exporter['listen_address'] = '0.0.0.0:9100'
   redis_exporter['listen_address'] = '0.0.0.0:9121'

   # 防止在升级时自动运行数据库迁移
   gitlab_rails['auto_migrate'] = false
  1. 从您配置的第一个Linux软件包节点复制 /etc/gitlab/gitlab-secrets.json 文件,并将其添加或替换为此服务器上同名的文件。如果这是您正在配置的第一个Linux软件包节点,则可以跳过此步骤。

  2. 重新配置GitLab,使更改生效。

配置副本Redis持久节点

  1. 通过SSH登录到副本Redis持久服务器。

  2. 下载并安装您选择的Linux包。确保仅添加GitLab软件包仓库并为所选操作系统安装GitLab。选择与当前安装相同的版本和类型(社区版或企业版)。

  3. 编辑/etc/gitlab/gitlab.rb并添加以下内容:

    # 指定服务器角色为'redis_sentinel_role'和'redis_replica_role'
    roles ['redis_sentinel_role', 'redis_replica_role', 'consul_role']
    
    # 设置Redis Sentinel服务的IP绑定地址和Quorum数量
    sentinel['bind'] = '0.0.0.0'
    sentinel['quorum'] = 2
    
    # 指向本地IP地址,其他机器可通过该地址访问。
    # 您也可以将bind设置为'0.0.0.0'以监听所有接口。
    # 如果必须绑定到外部可访问的IP,请确保添加额外的防火墙规则以防止未经授权的访问。
    redis['bind'] = '10.6.0.62'
    
    # 定义端口,使Redis能够监听TCP请求,允许其他机器连接。
    redis['port'] = 6379
    
    ## 主Redis服务器的端口(用于Sentinel),取消注释可修改为非默认值。默认值为`6379`。
    #redis['master_port'] = 6379
    
    # 与主节点设置的相同Redis认证密码。
    redis['password'] = 'REDIS_PRIMARY_PASSWORD_OF_SECOND_CLUSTER'
    redis['master_password'] = 'REDIS_PRIMARY_PASSWORD_OF_SECOND_CLUSTER'
    
    ## 所有Redis节点必须一致
    redis['master_name'] = 'gitlab-redis-persistent'
    
    # 主Redis节点的IP地址。
    redis['master_ip'] = '10.6.0.61'
    
    ## 启用Prometheus的服务发现功能
    consul['monitoring_service_discovery'] =  true
    
    ## Consul服务器节点的IP地址
    ## 您也可以使用FQDN,并与IP混合使用
    consul['configuration'] = {
       retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
    }
    
    # 设置exporters监听的网路地址
    node_exporter['listen_address'] = '0.0.0.0:9100'
    redis_exporter['listen_address'] = '0.0.0.0:9121'
    
    # 防止在升级时自动运行数据库迁移
    gitlab_rails['auto_migrate'] = false
  4. 从您配置的第一个Linux包节点复制/etc/gitlab/gitlab-secrets.json文件,并将此服务器上同名的文件添加或替换。如果这是您正在配置的第一个Linux包节点,则可以跳过此步骤。

  5. 重新配置GitLab以使更改生效。

  6. 对所有其他副本节点重复上述步骤,并确保正确设置IP地址。

高级配置选项受支持,如有需要可添加。

配置 Gitaly 集群(Praefect)

Gitaly 集群(Praefect) 是 GitLab 提供并推荐的容错解决方案,用于存储 Git 仓库。在这种配置中,集群中的每个 Gitaly 节点都存储每个 Git 仓库,其中一个被指定为主节点,如果主节点宕机,会自动进行故障转移。

Gitaly 规格基于健康状态下的使用模式和仓库大小的较高百分位数
但是,如果您有 大型单体仓库(大于几 GB)或 额外工作负载,这些可能会显著影响环境的性能,可能需要进一步调整
如果您认为这适用于您,请根据需要联系我们来获取额外的指导。

Gitaly 集群(Praefect)提供了容错的好处,但也带来了设置和管理上的额外复杂性。在部署 Gitaly 集群(Praefect)之前,请查看现有的 技术限制和注意事项

关于指导:

推荐的集群设置包含以下组件:

  • 3 个 Gitaly 节点:Git 仓库的复制存储。
  • 3 个 Praefect 节点:Gitaly 集群(Praefect)的路由器和事务管理器。
  • 1 个 Praefect PostgreSQL 节点:Praefect 的数据库服务器。需要一个第三方解决方案来使 Praefect 数据库连接具有高可用性。
  • 1 个负载均衡器:Praefect 需要负载均衡器。内部负载均衡器 用于此目的。

本节详细说明了如何按顺序配置推荐的标准设置。有关更高级的设置,请参阅 独立 Gitaly 集群(Praefect)文档

配置 Praefect PostgreSQL

Praefect 是 Gitaly 集群(Praefect)的路由器和事务管理器,需要自己的数据库服务器来存储集群状态数据。

如果您希望拥有高可用性设置,Praefect 需要一个第三方 PostgreSQL 数据库。内置解决方案正在 开发中

使用Linux包的Praefect非高可用独立PostgreSQL

以下IP将用作示例:

  • 10.6.0.141: Praefect PostgreSQL

首先,请确保在Praefect PostgreSQL节点上安装 Linux包。务必仅添加GitLab软件包仓库并安装适用于您所选操作系统的GitLab,但不要提供EXTERNAL_URL值。

  1. 通过SSH连接到Praefect PostgreSQL节点。

  2. 为Praefect PostgreSQL用户创建一个强密码。记下此密码作为<praefect_postgresql_password>

  3. 为Praefect PostgreSQL用户名/密码对生成密码哈希。这假设您将使用默认用户名praefect(推荐)。该命令将请求密码<praefect_postgresql_password>并进行确认。使用此命令输出的值作为下一步中<praefect_postgresql_password_hash>的值:

    sudo gitlab-ctl pg-password-md5 praefect
  4. 编辑/etc/gitlab/gitlab.rb,替换# START user configuration部分中注明的值:

    # 禁用除PostgreSQL和Consul之外的所有组件
    roles(['postgres_role', 'consul_role'])
    
    # PostgreSQL配置
    postgresql['listen_address'] = '0.0.0.0'
    
    # 防止数据库迁移在升级时自动运行
    gitlab_rails['auto_migrate'] = false
    
    # 配置Consul代理
    ## 启用Prometheus的服务发现
    consul['monitoring_service_discovery'] =  true
    
    # START 用户配置
    # 请按照“必需信息”部分所述设置真实值
    #
    # 用生成的md5值替换PRAEFECT_POSTGRESQL_PASSWORD_HASH
    postgresql['sql_user_password'] = "<praefect_postgresql_password_hash>"
    
    # 用网络地址替换XXX.XXX.XXX.XXX/YY
    postgresql['trust_auth_cidr_addresses'] = %w(10.6.0.0/24 127.0.0.1/32)
    
    # 设置导出器监听监控的网络地址
    node_exporter['listen_address'] = '0.0.0.0:9100'
    postgres_exporter['listen_address'] = '0.0.0.0:9187'
    
    ## Consul服务节点的IP
    ## 您也可以使用FQDN,并与IP混合使用
    consul['configuration'] = {
       retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
    }
    #
    # END 用户配置
  5. 从您配置的第一个Linux包节点复制/etc/gitlab/gitlab-secrets.json文件,并在本服务器上添加或替换同名文件。如果这是您正在配置的第一个Linux包节点,则可以跳过此步骤。

  6. 重新配置GitLab,使更改生效。

  7. 按照后续配置进行操作。

Praefect高可用第三方PostgreSQL解决方案

如前所述,如果目标是实现完全的高可用性,建议为Praefect的数据库使用第三方PostgreSQL解决方案。

有许多第三方PostgreSQL HA解决方案。选定的解决方案必须满足以下条件才能与Praefect配合使用:

  • 所有连接的静态IP,故障转移时不改变。
  • 必须支持LISTEN SQL功能。

使用第三方设置时,可以将Praefect的数据库与主GitLab数据库放在同一服务器上(除非使用Geo,否则作为便利措施),此时主数据库设置的规格无需更改,因为影响应该很小。

应为此使用信誉良好的提供商或解决方案。Google Cloud SQLAmazon RDS 已知可正常工作。但是,Amazon Aurora 在启用负载均衡(默认情况下从14.4.0版本起)的情况下不兼容

有关更多信息,请参阅推荐的云提供商和服务

数据库设置完成后,请按照后续配置进行操作。

Praefect PostgreSQL 配置后步骤

在设置好Praefect PostgreSQL服务器后,您必须配置Praefect使用的用户和数据库。

我们建议将用户命名为praefect,数据库名为praefect_production,这些可以在PostgreSQL中以标准方式配置。
该用户的密码与您之前配置的<praefect_postgresql_password>相同。

以下是Linux包安装PostgreSQL时的操作流程:

  1. 通过SSH连接到Praefect PostgreSQL节点。

  2. 使用管理员权限连接到PostgreSQL服务器。
    这里应使用gitlab-psql用户(因Linux包默认添加此用户)。
    使用数据库template1是因为它在所有PostgreSQL服务器上默认创建。

    /opt/gitlab/embedded/bin/psql -U gitlab-psql -d template1 -h POSTGRESQL_SERVER_ADDRESS
  3. 创建新用户praefect,替换<praefect_postgresql_password>

    CREATE ROLE praefect WITH LOGIN CREATEDB PASSWORD '<praefect_postgresql_password>';
  4. 再次连接到PostgreSQL服务器,这次以praefect用户身份:

    /opt/gitlab/embedded/bin/psql -U praefect -d template1 -h POSTGRESQL_SERVER_ADDRESS
  5. 创建新数据库praefect_production

    CREATE DATABASE praefect_production WITH ENCODING=UTF8;

配置 Praefect

Praefect 是 Gitaly 集群(Praefect)的路由器和事务管理器,所有到 Gitaly 的连接都需经过它。本节详细说明如何配置它。

Consul 必须以奇数个节点(至少 3 个)部署。这是为了保证节点能参与仲裁投票。

Praefect 需要多个密钥令牌来保障集群内通信安全:

  • <praefect_external_token>:用于访问 Gitaly 集群(Praefect)托管的仓库,仅携带此令牌的 Gitaly 客户端可访问。
  • <praefect_internal_token>:用于 Gitaly 集群(Praefect)内部的复制流量。它与 praefect_external_token 不同,因为 Gitaly 客户端不应直接访问集群内部节点,否则可能导致数据丢失。
  • <praefect_postgresql_password>:之前章节定义的 Praefect PostgreSQL 密码也需在此配置中使用。

Gitaly 集群(Praefect)节点在 Praefect 中通过 virtual storage(虚拟存储) 配置。每个存储包含构成集群的各 Gitaly 节点详情。每个存储还需命名,该名称会在配置的多处使用。本指南中存储名称为 default。此外,本指南针对新安装场景,若升级现有环境至 Gitaly 集群(Praefect),可能需使用不同名称。更多详情请参考 Gitaly 集群(Praefect)文档

以下 IP 将用作示例:

  • 10.6.0.131:Praefect 1
  • 10.6.0.132:Praefect 2
  • 10.6.0.133:Praefect 3

在每个 Praefect 节点上配置:

  1. 通过 SSH 登录到 Praefect 服务器。

  2. 下载并安装 您选择的 Linux 包。确保仅添加 GitLab 包仓库并安装对应操作系统的 GitLab。

  3. 编辑 /etc/gitlab/gitlab.rb 文件配置 Praefect:

    您无法从 virtual_storages 中移除 default 条目,因为 GitLab 要求它

    # 避免在 Praefect 服务器上运行不必要的服务
    gitaly['enable'] = false
    postgresql['enable'] = false
    redis['enable'] = false
    nginx['enable'] = false
    puma['enable'] = false
    sidekiq['enable'] = false
    gitlab_workhorse['enable'] = false
    prometheus['enable'] = false
    alertmanager['enable'] = false
    gitlab_exporter['enable'] = false
    gitlab_kas['enable'] = false
    
    # Praefect 配置
    praefect['enable'] = true
    
    # 升级时防止数据库自动执行迁移
    praefect['auto_migrate'] = false
    gitlab_rails['auto_migrate'] = false
    
    # 配置 Consul 代理
    consul['enable'] = true
    ## 启用 Prometheus 服务发现
    consul['monitoring_service_discovery'] = true
    
    # START 用户配置
    # 请根据「必需信息」部分设置真实值
    #
    
    praefect['configuration'] = {
       # ...
       listen_addr: '0.0.0.0:2305',
       auth: {
          # ...
          #
          # Praefect 外部令牌
          # 集群外客户端(如 GitLab Shell)与 Praefect 集群通信需此令牌
          token: '<praefect_external_token>',
       },
       # Praefect 数据库设置
       database: {
          # ...
          host: '10.6.0.141',
          port: 5432,
          dbname: 'praefect_production',
          user: 'praefect',
          password: '<praefect_postgresql_password>',
       },
       # Praefect 虚拟存储配置
       # 存储哈希名称需匹配 GitLab 服务器 (`praefect`) 中 `gitlab_rails['repositories_storages']` 
       # 及 Gitaly 节点 (`gitaly-1`) 中 `gitaly['configuration'][:storage]` 的存储名称
       virtual_storage: [
          {
             # ...
             name: 'default',
             node: [
                {
                   storage: 'gitaly-1',
                   address: 'tcp://10.6.0.91:8075',
                   token: '<praefect_internal_token>'
                },
                {
                   storage: 'gitaly-2',
                   address: 'tcp://10.6.0.92:8075',
                   token: '<praefect_internal_token>'
                },
                {
                   storage: 'gitaly-3',
                   address: 'tcp://10.6.0.93:8075',
                   token: '<praefect_internal_token>'
                },
             ],
          },
       ],
       # 设置 Praefect 用于监控的网络监听地址

```markdown
prometheus_listen_addr: '0.0.0.0:9652',
   }

   # 设置节点导出器监听的网络地址以进行监控
   node_exporter['listen_address'] = '0.0.0.0:9100'

   ## Consul 服务节点的 IP 地址
   ## 你也可以使用 FQDN,并与 IP 混合使用
   consul['configuration'] = {
      retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
   }
   #
   # 用户配置结束
  1. 从你配置的第一个 Linux 包节点复制 /etc/gitlab/gitlab-secrets.json 文件,并将此服务器上同名的文件添加或替换。如果这是你要配置的第一个 Linux 包节点,则可以跳过此步骤。

  2. Praefect 需要运行一些数据库迁移,类似于主 GitLab 应用程序。为此,你应该选择仅在一个 Praefect 节点上运行迁移,即所谓的_部署节点_。该节点必须首先按以下方式配置:

    1. /etc/gitlab/gitlab.rb 文件中,将 praefect['auto_migrate'] 设置值从 false 更改为 true

    2. 为确保数据库迁移仅在重新配置期间运行,而不是在升级时自动运行,请执行:

    sudo touch /etc/gitlab/skip-auto-reconfigure
    1. 重新配置 GitLab,使更改生效并运行 Praefect 数据库迁移。
  3. 在所有其他 Praefect 节点上,重新配置 GitLab,使更改生效。


### 配置 Gitaly

组成集群的 [Gitaly](../gitaly/_index.md) 服务器节点有依赖于数据和负载的要求。

Gitaly 规格基于健康状态下使用模式和仓库大小的较高百分位数
但是,如果您有 大型单体仓库(大于几 GB)或 额外工作负载,这些会显著影响环境的性能,可能需要进一步调整
如果认为这适用于您,请根据需要联系我们来获取额外的指导。

Gitaly 有特定的 [磁盘要求](../gitaly/_index.md#disk-requirements) 用于 Gitaly 存储器。 Gitaly 服务器不能暴露在公共互联网上,因为默认情况下 Gitaly 的网络流量未加密。强烈建议使用防火墙来限制对 Gitaly 服务器的访问。另一个选项是 [使用 TLS](#gitaly-cluster-praefect-tls-support)。 配置 Gitaly 时需注意以下几点: - `gitaly['configuration'][:storage]` 应该配置为反映特定 Gitaly 节点的存储路径 - `auth_token` 应该与 `praefect_internal_token` 相同 以下 IP 将用作示例: - `10.6.0.91`:Gitaly 1 - `10.6.0.92`:Gitaly 2 - `10.6.0.93`:Gitaly 3 在每个节点上执行以下操作: 1. [下载并安装](../../install/package/_index.md#supported-platforms) 您选择的 Linux 包。确保仅添加 GitLab 包仓库并安装所选操作系统的 GitLab,但**不要**提供 `EXTERNAL_URL` 值。 1. 编辑 Gitaly 服务器节点的 `/etc/gitlab/gitlab.rb` 文件以配置存储路径、启用网络监听器并配置令牌: <!-- 对示例的更新需同步至: - https://gitlab.com/gitlab-org/charts/gitlab/blob/master/doc/advanced/external-gitaly/external-omnibus-gitaly.md#configure-omnibus-gitlab - https://gitlab.com/gitlab-org/gitlab/blob/master/doc/administration/gitaly/index.md#gitaly-server-configuration - 所有参考架构页面 --> ```ruby # 避免在 Gitaly 服务器上运行不必要的服务 postgresql['enable'] = false redis['enable'] = false nginx['enable'] = false puma['enable'] = false sidekiq['enable'] = false gitlab_workhorse['enable'] = false prometheus['enable'] = false alertmanager['enable'] = false gitlab_exporter['enable'] = false gitlab_kas['enable'] = false # 防止数据库迁移在升级时自动运行 gitlab_rails['auto_migrate'] = false # 配置 gitlab-shell API 回调 URL。如果没有此配置,`git push` 将失败。可以是您的“前端” GitLab URL 或内部负载均衡器。 gitlab_rails['internal_api_url'] = 'https://gitlab.example.com' # Gitaly gitaly['enable'] = true # 配置 Consul 代理 consul['enable'] = true ## 启用 Prometheus 的服务发现 consul['monitoring_service_discovery'] = true # START 用户配置 # 请按照“所需信息”部分设置真实值 # ## Consul 服务器节点的 IP ## 您也可以使用 FQDN 并将其与 IP 混合使用 consul['configuration'] = { retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13), } # 设置 node exporter 监听的地址用于监控 node_exporter['listen_address'] = '0.0.0.0:9100' gitaly['configuration'] = { # 让 Gitaly 接受所有网络接口的连接。您必须使用防火墙来限制对此地址/端口的访问。 # 如果您只想支持 TLS 连接,请注释掉以下行 listen_addr: '0.0.0.0:8075', # 设置 Gitaly 将监听的网络地址用于监控 prometheus_listen_addr: '0.0.0.0:9236', auth: { # Gitaly 认证令牌 # 应该与 praefect_internal_token 相同 token: '<praefect_internal_token>', }, pack_objects_cache: { # Gitaly Pack-objects 缓存 # 建议启用以提高性能,但可能会显著增加磁盘 I/O # 参见 https://docs.gitlab.com/ee/administration/gitaly/configure_gitaly.html#pack-objects-cache 了解更多信息 enabled: true, }, } # # END 用户配置
  1. /etc/gitlab/gitlab.rb 追加以下内容(针对各服务器分别操作):
    • 在 Gitaly 节点 1:

      gitaly['configuration'] = {
         # ...
         storage: [
            {
               name: 'gitaly-1',
               path: '/var/opt/gitlab/git-data',
            },
         ],
      }
    • 在 Gitaly 节点 2:

      gitaly['configuration'] = {
         # ...
         storage: [
            {
               name: 'gitaly-2',
               path: '/var/opt/gitlab/git-data',
            },

在Gitaly节点1上:

gitaly['configuration'] = {
   # ...
   storage: [
      {
         name: 'gitaly-1',
         path: '/var/opt/gitlab/git-data',
      },
   ],
}

在Gitaly节点2上:

gitaly['configuration'] = {
   # ...
   storage: [
      {
         name: 'gitaly-2',
         path: '/var/opt/gitlab/git-data',
      },
   ],
}

在Gitaly节点3上:

gitaly['configuration'] = {
   # ...
   storage: [
      {
         name: 'gitaly-3',
         path: '/var/opt/gitlab/git-data',
      },
   ],
}
  1. 从你配置的第一个Linux包节点复制 /etc/gitlab/gitlab-secrets.json 文件,并将此服务器上的同名文件添加或替换。如果这是你要配置的第一个Linux包节点,则可以跳过此步骤。

  2. 保存文件,然后重新配置GitLab

Gitaly 集群(Praefect)TLS 支持

Praefect 支持TLS加密。要与监听安全连接的Praefect实例通信,您必须:

  • 在GitLab配置中对应存储条目的gitaly_address中使用tls:// URL方案。
  • 自备证书,因为不会自动提供。每个Praefect服务器的证书必须安装在该Praefect服务器上。

此外,证书或其证书颁发机构必须安装在所有Gitaly服务器和所有与它通信的Praefect客户端上,遵循GitLab自定义证书配置中描述的程序(并在下方重复)。

注意以下事项:

  • 证书必须指定用于访问Praefect服务器的地址。您必须在证书中将主机名或IP地址添加为主题备用名称。
  • 您可以同时为Praefect服务器配置未加密的监听地址listen_addr和加密的监听地址tls_listen_addr。如果需要,这允许您逐步从未加密流量过渡到加密流量。若要禁用未加密监听器,请设置praefect['configuration'][:listen_addr] = nil
  • 内部负载均衡器也将访问证书,并且必须配置为允许TLS直通。有关如何配置此内容,请参阅负载均衡器文档。

要为Praefect配置TLS:

  1. 为Praefect服务器创建证书。

  2. 在Praefect服务器上,创建/etc/gitlab/ssl目录并将密钥和证书复制到那里:

    sudo mkdir -p /etc/gitlab/ssl
    sudo chmod 755 /etc/gitlab/ssl
    sudo cp key.pem cert.pem /etc/gitlab/ssl/
    sudo chmod 644 key.pem cert.pem
  3. 编辑/etc/gitlab/gitlab.rb并添加:

    praefect['configuration'] = {
       # ...
       tls_listen_addr: '0.0.0.0:3305',
       tls: {
          # ...
          certificate_path: '/etc/gitlab/ssl/cert.pem',
          key_path: '/etc/gitlab/ssl/key.pem',
       },
    }
  4. 保存文件并重新配置

  5. 在Praefect客户端(包括每个Gitaly服务器),将证书或其证书颁发机构复制到/etc/gitlab/trusted-certs

    sudo cp cert.pem /etc/gitlab/trusted-certs/
  6. 在Praefect客户端(除Gitaly服务器外),编辑/etc/gitlab/gitlab.rb中的gitlab_rails['repositories_storages']如下:

    gitlab_rails['repositories_storages'] = {
      "default" => {
        "gitaly_address" => 'tls://LOAD_BALANCER_SERVER_ADDRESS:3305',
        "gitaly_token" => 'PRAEFECT_EXTERNAL_TOKEN'
      }
    }
  7. 保存文件并重新配置GitLab

## 配置 Sidekiq

Sidekiq 需要连接到 [Redis](#configure-redis)、[PostgreSQL](#configure-postgresql) 和 [Gitaly](#configure-gitaly) 实例。同时也建议连接到 [Object Storage](#configure-the-object-storage)。

由于建议使用对象存储 而非 NFS 存储数据对象,以下示例包含了对象存储配置。

如果您发现环境中 Sidekiq 任务处理缓慢且队列过长,可相应进行扩容。更多详情请参阅 扩容文档

在配置额外的 GitLab 功能(如容器注册表、SAML 或 LDAP)时,除更新 Rails 配置外,还需更新 Sidekiq 配置。更多信息请参阅 外部 Sidekiq 文档

- `10.6.0.101`:Sidekiq 1 - `10.6.0.102`:Sidekiq 2 - `10.6.0.103`:Sidekiq 3 - `10.6.0.104`:Sidekiq 4 要在每个 Sidekiq 节点上完成配置: 1. 通过 SSH 登录到 Sidekiq 服务器。 1. 确认可访问 PostgreSQL、Gitaly 和 Redis 端口: ```shell telnet <GitLab 主机> 5432 # PostgreSQL telnet <GitLab 主机> 8075 # Gitaly telnet <GitLab 主机> 6379 # Redis
  1. 下载并安装 您选择的 Linux 安装包。请确保仅添加 GitLab 包仓库并为所选操作系统安装 GitLab。

  2. 创建或编辑 /etc/gitlab/gitlab.rb 并使用以下配置:

    # https://docs.gitlab.com/omnibus/roles/#sidekiq-roles
    roles(["sidekiq_role"])
    
    # 外部 URL
    ## 此处应与外部负载均衡器的 URL 一致
    external_url 'https://gitlab.example.com'
    
    # Redis
    ## Redis 连接详情
    ## 承载缓存数据的第一个集群
    gitlab_rails['redis_cache_instance'] = 'redis://:<REDIS_PRIMARY_PASSWORD_OF_FIRST_CLUSTER>@gitlab-redis-cache'
    
    gitlab_rails['redis_cache_sentinels'] = [
      {host: '10.6.0.51', port: 26379},
      {host: '10.6.0.52', port: 26379},
      {host: '10.6.0.53', port: 26379},
    ]
    
    ## 承载数据持久化数据的第二个集群
    redis['master_name'] = 'gitlab-redis-persistent'
    redis['master_password'] = '<REDIS_PRIMARY_PASSWORD_OF_SECOND_CLUSTER>'
    
    gitlab_rails['redis_sentinels'] = [
      {host: '10.6.0.61', port: 26379},
      {host: '10.6.0.62', port: 26379},
      {host: '10.6.0.63', port: 26379},
    ]
    
    # Gitaly 集群
    ## gitlab_rails['repositories_storages'] 为 Praefect 虚拟存储配置
    ## 地址为 Praefect 内部负载均衡器地址
    ## Token 为 praefect_external_token
    gitlab_rails['repositories_storages'] = {
      "default" => {
        "gitaly_address" => "tcp://10.6.0.40:2305", # 内部负载均衡器 IP
        "gitaly_token" => '<praefect_external_token>'
      }
    }
    
    # PostgreSQL
    gitlab_rails['db_host'] = '10.6.0.40' # 内部负载均衡器 IP
    gitlab_rails['db_port'] = 6432
    gitlab_rails['db_password'] = '<postgresql_user_password>'
    gitlab_rails['db_load_balancing'] = { 'hosts' => ['10.6.0.21', '10.6.0.22', '10.6.0.23'] } # PostgreSQL IPs
    
    ## 升级时自动阻止数据库迁移运行
    gitlab_rails['auto_migrate'] = false
    
    # Sidekiq
    sidekiq['listen_address'] = "0.0.0.0"
    
    ## 将 Sidekiq 队列进程数设置为与 CPU 核心数相同
    sidekiq['queue_groups'] = ['*'] * 4
    
    # 监控
    consul['enable'] = true
    consul['monitoring_service_discovery'] =  true
    
    consul['configuration'] = {
       retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13)
    }
    
    ## 设置导出器的监听网络地址
    node_exporter['listen_address'] = '0.0.0.0:9100'
    
    ## 将监控节点的 IP 地址加入监控白名单
    gitlab_rails['monitoring_whitelist'] = ['10.6.0.151/32', '127.0.0.0/8']
    
    # 对象存储
    ## 以下为 GCP 配置对象存储的示例
    ## 可根据需求替换为您选择的对象存储提供商配置
    gitlab_rails['object_store']['enabled'] = true
    gitlab_rails['object_store']['connection'] = {
      'provider' => 'Google',
      'google_project' => '<gcp-project-name>',
      'google_json_key_location' => '<path-to-gcp-service-account-key>'
    }
    gitlab_rails['object_store']['objects']['artifacts']['bucket'] = "<gcp-artifacts-bucket-name>"
    gitlab_rails['object_store']['objects']['external_diffs']['bucket'] = "<gcp-external-diffs-bucket-name>"
    gitlab_rails['object_store']['objects']['lfs']['bucket'] = "<gcp-lfs-bucket-name>"
    gitlab_rails['object_store']['objects']['uploads']['bucket'] = "<gcp-uploads-bucket-name>"
gitlab_rails['object_store']['objects']['packages']['bucket'] = "<gcp-packages-bucket-name>"
gitlab_rails['object_store']['objects']['dependency_proxy']['bucket'] = "<gcp-dependency-proxy-bucket-name>"
gitlab_rails['object_store']['objects']['terraform_state']['bucket'] = "<gcp-terraform-state-bucket-name>"

gitlab_rails['backup_upload_connection'] = {
  'provider' => 'Google',
  'google_project' => '<gcp-project-name>',
  'google_json_key_location' => '<path-to-gcp-service-account-key>'
}
gitlab_rails['backup_upload_remote_directory'] = "<gcp-backups-state-bucket-name>"

gitlab_rails['ci_secure_files_object_store_enabled'] = true
gitlab_rails['ci_secure_files_object_store_remote_directory'] = "gcp-ci_secure_files-bucket-name"

gitlab_rails['ci_secure_files_object_store_connection'] = {
  'provider' => 'Google',
  'google_project' => '<gcp-project-name>',
  'google_json_key_location' => '<path-to-gcp-service-account-key>'
}
  1. 将您配置的第一个 Linux 包节点上的 /etc/gitlab/gitlab-secrets.json 文件复制到本服务器上,添加或替换同名的文件。如果这是您正在配置的第一个 Linux 包节点,则可以跳过此步骤。

  2. 为确保数据库迁移仅在重新配置期间运行,而非在升级时自动运行,请执行以下命令:

    sudo touch /etc/gitlab/skip-auto-reconfigure

    只有指定的单个节点应处理迁移,具体如 GitLab Rails 后配置 部分所述。

  3. 重新配置 GitLab 以使更改生效。

```

配置 GitLab Rails

本节介绍如何配置 GitLab 应用程序(Rails)组件。

Rails 要求连接到 RedisPostgreSQLGitaly 实例。它还需要连接到 Object Storage,如推荐的那样。

因为建议使用对象存储 而不是 NFS 来存储数据对象,因此以下示例包含对象存储配置。

以下 IP 将用作示例:

  • 10.6.0.111:GitLab 应用 1
  • 10.6.0.112:GitLab 应用 2
  • 10.6.0.113:GitLab 应用 3

在每个节点上执行以下操作:

  1. 下载并安装 您选择的 Linux 包。确保仅添加 GitLab 包仓库并为所选操作系统安装 GitLab。

  2. 编辑 /etc/gitlab/gitlab.rb 并使用以下配置。为了在节点间保持链接的一致性,应用服务器上的 external_url 应指向用户访问 GitLab 时使用的对外 URL。这将是 外部负载均衡器 的 URL,该负载均衡器会将流量路由到 GitLab 应用服务器:

    external_url 'https://gitlab.example.com'
    
    # gitlab_rails['repositories_storages'] 为 Praefect 虚拟存储进行配置
    # 地址是 Praefect 的内部负载均衡器
    # Token 是 praefect_external_token
    gitlab_rails['repositories_storages'] = {
      "default" => {
        "gitaly_address" => "tcp://10.6.0.40:2305", # 内部负载均衡器 IP
        "gitaly_token" => '<praefect_external_token>'
      }
    }
    
    ## 禁用不在 GitLab 应用服务器上的组件
    roles(['application_role'])
    gitaly['enable'] = false
    sidekiq['enable'] = false
    
    ## PostgreSQL 连接详情
    # 在应用节点禁用 PostgreSQL
    postgresql['enable'] = false
    gitlab_rails['db_host'] = '10.6.0.20' # 内部负载均衡器 IP
    gitlab_rails['db_port'] = 6432
    gitlab_rails['db_password'] = '<postgresql_user_password>'
    gitlab_rails['db_load_balancing'] = { 'hosts' => ['10.6.0.21', '10.6.0.22', '10.6.0.23'] } # PostgreSQL IPs
    
    # 防止升级时自动运行数据库迁移
    gitlab_rails['auto_migrate'] = false
    
    ## Redis 连接详情
    ## 第一个集群用于缓存数据
    gitlab_rails['redis_cache_instance'] = 'redis://:<REDIS_PRIMARY_PASSWORD_OF_FIRST_CLUSTER>@gitlab-redis-cache'
    
    gitlab_rails['redis_cache_sentinels'] = [
      {host: '10.6.0.51', port: 26379},
      {host: '10.6.0.52', port: 26379},
      {host: '10.6.0.53', port: 26379},
    ]
    
    ## 第二个集群用于托管所有其他持久化数据
    redis['master_name'] = 'gitlab-redis-persistent'
    redis['master_password'] = '<REDIS_PRIMARY_PASSWORD_OF_SECOND_CLUSTER>'
    
    gitlab_rails['redis_sentinels'] = [
      {host: '10.6.0.61', port: 26379},
      {host: '10.6.0.62', port: 26379},
      {host: '10.6.0.63', port: 26379},
    ]
    
    # 设置监控所用的导出器监听的网路地址
    node_exporter['listen_address'] = '0.0.0.0:9100'
    gitlab_workhorse['prometheus_listen_addr'] = '0.0.0.0:9229'
    puma['listen'] = '0.0.0.0'
    
    # 将监控节点的 IP 地址添加到监控白名单,允许其抓取 NGINX 指标
    gitlab_rails['monitoring_whitelist'] = ['10.6.0.151/32', '127.0.0.0/8']
    nginx['status']['options']['allow'] = ['10.6.0.151/32', '127.0.0.0/8']
    
    #############################
    ###     对象存储          ###
    #############################
    
    # 这是 GCP 上配置对象存储的示例
    # 根据需要替换此配置为您选择的对象存储提供商
    gitlab_rails['object_store']['enabled'] = true
    gitlab_rails['object_store']['connection'] = {
      'provider' => 'Google',
      'google_project' => '<gcp-project-name>',
      'google_json_key_location' => '<path-to-gcp-service-account-key>'
    }
    gitlab_rails['object_store']['objects']['artifacts']['bucket'] = "<gcp-artifacts-bucket-name>"
    gitlab_rails['object_store']['objects']['external_diffs']['bucket'] = "<gcp-external-diffs-bucket-name>"
    gitlab_rails['object_store']['objects']['lfs']['bucket'] = "<gcp-lfs-bucket-name>"
    gitlab_rails['object_store']['objects']['uploads']['bucket'] = "<gcp-uploads-bucket-name>"
    gitlab_rails['object_store']['objects']['packages']['bucket'] = "<gcp-packages-bucket-name>"
    gitlab_rails['object_store']['objects']['dependency_proxy']['bucket'] = "<gcp-dependency-proxy-bucket-name>"
    gitlab_rails['object_store']['objects']['terraform_state']['bucket'] = "<gcp-terraform-state-bucket-name>"
    
    gitlab_rails['backup_upload_connection'] = {
      'provider' => 'Google',
'google_project' => '<gcp-project-name>',
     'google_json_key_location' => '<path-to-gcp-service-account-key>'
   }
   gitlab_rails['backup_upload_remote_directory'] = "<gcp-backups-state-bucket-name>"
   gitlab_rails['ci_secure_files_object_store_enabled'] = true
   gitlab_rails['ci_secure_files_object_store_remote_directory'] = "gcp-ci_secure_files-bucket-name"

   gitlab_rails['ci_secure_files_object_store_connection'] = {
      'provider' => 'Google',
      'google_project' => '<gcp-project-name>',
      'google_json_key_location' => '<path-to-gcp-service-account-key>'
   }
  1. 如果您使用带有TLS支持的Gitaly,请确保gitlab_rails['repositories_storages']条目配置为tls而不是tcp

    gitlab_rails['repositories_storages'] = {
      "default" => {
        "gitaly_address" => "tls://10.6.0.40:2305", # 内部负载均衡器IP
        "gitaly_token" => '<praefect_external_token>'
      }
    }
    1. 将证书复制到/etc/gitlab/trusted-certs

      sudo cp cert.pem /etc/gitlab/trusted-certs/
  2. 从您配置的第一个Linux包节点复制/etc/gitlab/gitlab-secrets.json文件,并将此服务器上同名的文件添加或替换。如果这是您正在配置的第一个Linux包节点,则可以跳过此步骤。

  3. 从您配置的第一个Rails节点复制SSH主机密钥(所有名称格式为/etc/ssh/ssh_host_*_key*),并将此服务器上同名的文件添加或替换。这可确保当用户访问负载均衡的Rails节点时不会抛出主机不匹配错误。如果这是您正在配置的第一个Linux包节点,则可以跳过此步骤。

  4. 为确保数据库迁移仅在重新配置期间运行,而非在升级时自动运行,请执行:

    sudo touch /etc/gitlab/skip-auto-reconfigure

    仅指定的单个节点应处理迁移,详情见GitLab Rails后配置部分。

  5. 重新配置GitLab以使更改生效。

  6. 启用增量日志记录

  7. 确认节点可与Gitaly建立连接:

    sudo gitlab-rake gitlab:gitaly:check

    然后,查看日志以查看请求:

    sudo gitlab-ctl tail gitaly
  8. 可选:从Gitaly服务器确认Gitaly能向内部API发起回调:

    • 对于GitLab 15.3及更高版本,运行sudo -u git -- /opt/gitlab/embedded/bin/gitaly check /var/opt/gitlab/gitaly/config.toml
    • 对于GitLab 15.2及更早版本,运行sudo -u git -- /opt/gitlab/embedded/bin/gitaly-hooks check /var/opt/gitlab/gitaly/config.toml

当您在external_url中指定https(如之前的示例所示)时,GitLab期望SSL证书位于/etc/gitlab/ssl/中。如果证书不存在,NGINX将无法启动。有关更多信息,请参阅HTTPS文档


### GitLab Rails 安装后配置

1. 指定一个应用节点在安装和更新期间运行数据库迁移。初始化 GitLab 数据库并确保所有迁移已执行:

   ```shell
   sudo gitlab-rake gitlab:db:configure

此操作需要将 Rails 节点配置为直接连接主数据库,绕过 PgBouncer。迁移完成后,必须将该节点重新配置为再次通过 PgBouncer。

  1. 配置快速查找数据库中授权的 SSH 密钥

配置 Prometheus

Linux 包可用于配置运行 Prometheus 的独立监控节点。

以下 IP 将用作示例:

  • 10.6.0.151:Prometheus

要配置监控节点:

  1. 通过 SSH 连接到监控节点。

  2. 下载并安装 您选择的 Linux 包。请确保仅添加 GitLab 包仓库并为所选操作系统安装 GitLab。

  3. 编辑 /etc/gitlab/gitlab.rb 并添加以下内容:

    roles(['monitoring_role', 'consul_role'])
    
    external_url 'http://gitlab.example.com'
    
    # Prometheus
    prometheus['listen_address'] = '0.0.0.0:9090'
    prometheus['monitor_kubernetes'] = false
    
    # 为 Prometheus 启用服务发现
    consul['monitoring_service_discovery'] =  true
    consul['configuration'] = {
       retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13)
    }
    
    # 配置 Prometheus 抓取未通过发现覆盖的服务
    prometheus['scrape_configs'] = [
       {
          'job_name': 'pgbouncer',
          'static_configs' => [
             'targets' => [
             "10.6.0.31:9188",
             "10.6.0.32:9188",
             "10.6.0.33:9188",
             ],
          ],
       },
       {
          'job_name': 'praefect',
          'static_configs' => [
             'targets' => [
             "10.6.0.131:9652",
             "10.6.0.132:9652",
             "10.6.0.133:9652",
             ],
          ],
       },
    ]
    
    nginx['enable'] = false
  4. 重新配置 GitLab 以使更改生效。

配置对象存储

GitLab 支持使用 对象存储 服务来存储多种类型的数据。对于数据对象,它比 NFS 更受推荐,通常在大规模部署中表现更好,因为对象存储通常更具性能、可靠性和可扩展性。有关更多信息,请参阅 推荐的云提供商和服务

在 GitLab 中有两种指定对象存储配置的方式:

以下示例中使用合并形式(若可用)。

对每种数据类型使用单独的桶是 GitLab 推荐的方法。这确保了 GitLab 存储的各种数据类型之间不会发生冲突。未来有计划 启用使用单个桶

启用增量日志

GitLab Runner 以分块形式返回作业日志,即使在使用合并对象存储时,Linux 包也会将这些日志临时缓存在磁盘上的 /var/opt/gitlab/gitlab-ci/builds 目录中(默认)。在默认配置下,此目录需要通过 NFS 在任何 GitLab Rails 和 Sidekiq 节点上共享。

虽然支持通过 NFS 共享作业日志,但可以通过启用 增量日志 来避免使用 NFS 的需求(当未部署 NFS 节点时需要)。增量日志使用 Redis 而不是磁盘空间来临时缓存作业日志。

配置高级搜索

你可以利用 Elasticsearch 并启用高级搜索(../../integration/advanced_search/elasticsearch.md),在整个 GitLab 实例中实现更快、更高级的代码搜索。

Elasticsearch 集群的设计和需求取决于你的具体数据。有关如何与实例一起设置 Elasticsearch 集群的推荐最佳实践,请阅读如何选择最优集群配置(../../integration/advanced_search/elasticsearch.md#guidance-on-choosing-optimal-cluster-configuration)。

使用 Helm Charts 的云原生混合参考架构(替代方案)

另一种方法是在 Kubernetes 中运行特定的 GitLab 组件。支持以下服务:

  • GitLab Rails
  • Sidekiq
  • NGINX
  • Toolbox
  • Migrations
  • Prometheus

混合安装结合了云原生和传统计算部署的优势。通过这种方式,无状态组件可以受益于云原生工作负载管理的好处,而有状态组件则部署在带有 Linux 包安装的计算 VM 中,以获得更高的持久性。

请参阅 Helm Charts 的高级配置文档,了解设置说明,包括如何在 Kubernetes 和后端组件之间同步哪些 GitLab 密钥。

这是一个高级设置。众所周知,在 Kubernetes 中运行服务很复杂。仅建议如果你对 Kubernetes 有扎实的工作知识和经验时采用此设置。本节的其余部分假设这一点。

Gitaly Cluster (Praefect) 不支持在 Kubernetes 中运行。有关更多详情,请参阅 epic 6127

集群拓扑

以下表格和图表详细说明了混合环境,采用与之前记录的典型环境相同的格式。

首先是运行在 Kubernetes 上的组件。这些组件跨多个节点组运行,不过只要满足最低 CPU 和内存要求,您可以根据需要调整整体组成。

组件节点组 目标节点池总计 GCP 示例 AWS 示例
Webservice 80 个 vCPU
100 GB 内存(请求)
140 GB 内存(限制)
3 × n1-standard-32 3 × c5.9xlarge
Sidekiq 12.6 个 vCPU
28 GB 内存(请求)
56 GB 内存(限制)
4 × n1-standard-4 4 × m5.xlarge
支持服务 8 个 vCPU
30 GB 内存
2 × n1-standard-4 2 × m5.xlarge
  • 对于此设置,我们定期进行测试,并推荐使用 Google Kubernetes Engine (GKE)Amazon Elastic Kubernetes Service (EKS)。其他 Kubernetes 服务也可能适用,但效果可能因情况而异。
  • 机器类型示例仅用于说明目的。这些类型在 验证和测试 中使用,但并非规定性默认值。支持切换到符合要求的其他机器类型。有关更多信息,请参阅 支持的机器类型
  • WebserviceSidekiq 的目标节点池总计仅适用于 GitLab 组件。所选 Kubernetes 提供商的系统进程需要额外的资源,给出的示例已考虑到这一点。
  • Supporting 的目标节点池总计通常是为了容纳支持 GitLab 部署的多种资源,以及根据您的需求可能希望进行的任何额外部署。与其他节点池类似,所选 Kubernetes 提供商的系统进程也需要资源,给出的示例已考虑到这一点。
  • 在生产部署中,无需将 Pod 分配给特定节点。但是,建议每个池中有多个节点分布在不同的可用区,以符合弹性云架构实践。
  • 出于效率考虑,鼓励启用自动扩展(例如 Cluster Autoscaler),但通常建议将 Webservice 和 Sidekiq Pod 的目标下限设为 75%,以确保持续性能。

接下来是在静态计算 VM 上运行的的后端组件(或适用时使用外部 PaaS 服务):

服务 节点数 配置 GCP 示例1 AWS 示例1
Consul2 3 2 个 vCPU,1.8 GB 内存 n1-highcpu-2 c5.large
PostgreSQL2 3 8 个 vCPU,30 GB 内存 n1-standard-8 m5.2xlarge
PgBouncer2 3 2 个 vCPU,1.8 GB 内存 n1-highcpu-2 c5.large
内部负载均衡器4 1 4 个 vCPU,3.6 GB 内存 n1-highcpu-4 c5n.xlarge
Redis/Sentinel - 缓存3 3 4 个 vCPU,15 GB 内存 n1-standard-4 m5.xlarge
Redis/Sentinel - 持久化3 3 4 个 vCPU,15 GB 内存 n1-standard-4 m5.xlarge
Gitaly67 3 16 个 vCPU,60 GB 内存 n1-standard-16 m5.4xlarge
Praefect6 3 2 个 vCPU,1.8 GB 内存 n1-highcpu-2 c5.large
Praefect PostgreSQL2 1+ 2 个 vCPU,1.8 GB 内存 n1-highcpu-2 c5.large
对象存储5 - - - -

脚注

  1. 机器类型示例仅用于说明目的。这些类型在 验证和测试 中使用,但并非规定性默认值。支持切换到符合要求的其他机器类型,包括可用的 ARM 变体。有关更多信息,请参阅 支持的机器类型

  2. 可以选择在信誉良好的第三方外部PaaS PostgreSQL解决方案上运行。有关更多信息,请参阅提供您自己的PostgreSQL实例推荐的云提供商和服务

  3. 可以选择在信誉良好的第三方外部PaaS Redis解决方案上运行。有关更多信息,请参阅提供您自己的Redis实例推荐的云提供商和服务

    • Redis主要是单线程的,增加CPU核心并不能显著提升性能。对于这种规模的架构,强烈建议按照指定要求部署独立的缓存和持久化实例,以达到最佳性能。
  4. 建议与能够提供高可用(HA)能力的信誉良好的第三方负载均衡器或服务(LB PaaS)一起运行。此外,规模取决于所选负载均衡器及其他因素(如网络带宽)。有关更多信息,请参阅负载均衡器

  5. 应在信誉良好的云提供商或自管理解决方案上运行。有关更多信息,请参阅配置对象存储

  6. Gitaly集群(Praefect)提供了容错的好处,但也带来了额外的设置和管理复杂性。
    部署前请先查看现有技术限制和注意事项。如果您需要分片的Gitaly,请使用之前表格中列出的相同规格作为Gitaly

  7. Gitaly规格基于良好健康状态下的使用模式和仓库大小的高百分位数。
    但是,如果您有大型单体仓库(大于数GB)或额外工作负载,这些可能会显著影响Git和Gitaly的性能,可能还需要进一步调整。

对于所有涉及配置实例的PaaS解决方案,建议实施至少三个节点分布在三个不同的可用区中,以符合弹性云架构实践。

@startuml 10k
skinparam linetype ortho

card "通过Helm Charts的Kubernetes" as kubernetes {
  card "**外部负载均衡器**" as elb #6a9be7

  together {
    collections "**Web服务**" as gitlab #32CD32
    collections "**Sidekiq**" as sidekiq #ff8dd1
  }

  card "**支持服务**" as support
}

card "**内部负载均衡器**" as ilb #9370DB
collections "**Consul** x3" as consul #e76a9b

card "Gitaly集群" as gitaly_cluster {
  collections "**Praefect** x3" as praefect #FF8C00
  collections "**Gitaly** x3" as gitaly #FF8C00
  card "**Praefect PostgreSQL***\n//非容错型//" as praefect_postgres #FF8C00

  praefect -[#FF8C00]-> gitaly
  praefect -[#FF8C00]> praefect_postgres
}

card "数据库" as database {
  collections "**PGBouncer** x3" as pgbouncer #4EA7FF
  card "**PostgreSQL(主节点)**" as postgres_primary #4EA7FF
  collections "**PostgreSQL(从节点)** x2" as postgres_secondary #4EA7FF

  pgbouncer -[#4EA7FF]-> postgres_primary
  postgres_primary .[#4EA7FF]> postgres_secondary
}

card "redis" as redis {
  collections "**Redis持久化实例** x3" as redis_persistent #FF6347
  collections "**Redis缓存实例** x3" as redis_cache #FF6347

  redis_cache -[hidden]-> redis_persistent
}

cloud "**对象存储**" as object_storage #white

elb -[#6a9be7]-> gitlab
elb -[hidden]-> sidekiq
elb -[hidden]-> support

gitlab -[#32CD32]--> ilb
gitlab -[#32CD32]r--> object_storage
gitlab -[#32CD32,norank]----> redis
gitlab -[#32CD32]----> database

sidekiq -[#ff8dd1]--> ilb
sidekiq -[#ff8dd1]r--> object_storage
sidekiq -[#ff8dd1,norank]----> redis
sidekiq .[#ff8dd1]----> database

ilb -[#9370DB]--> gitaly_cluster
ilb -[#9370DB]--> database
ilb -[hidden,norank]--> redis

consul .[#e76a9b]--> database
consul .[#e76a9b,norank]--> gitaly_cluster
consul .[#e76a9b]--> redis

@enduml

Kubernetes 组件目标

以下部分详细说明了 Kubernetes 中部署的 GitLab 组件所用到的目标。

Webservice

每个 Webservice Pod(Puma 和 Workhorse)建议运行以下配置:

  • 4 个 Puma Worker
  • 4 vCPU
  • 5 GB 内存(请求)
  • 7 GB 内存(限制)

对于 200 RPS 或 10,000 用户,我们建议总 Puma Worker 数量约为 80,因此建议至少运行 20 个 Webservice Pod。

有关 Webservice 资源使用的更多信息,请参阅 Charts 文档中的 Webservice 资源

NGINX

还建议将 NGINX 控制器 Pod 作为 DaemonSet 部署在 Webservice 节点上。这样可以让控制器根据所服务的 Webservice Pod 动态扩展,同时利用较大机器类型通常具备的更高网络带宽。

这不是强制要求。只要 NGINX 控制器 Pod 有足够资源处理 Web 流量,可按需部署。

Sidekiq

每个 Sidekiq Pod 建议运行以下配置:

  • 1 个 Sidekiq Worker
  • 900m vCPU
  • 2 GB 内存(请求)
  • 4 GB 内存(限制)

与之前记录的标准部署类似,此处使用初始目标 14 个 Sidekiq Worker。根据具体工作流程,可能需要额外 Worker。

有关 Sidekiq 资源使用的更多信息,请参阅 Charts 文档中的 Sidekiq 资源

Supporting

Supporting Node Pool 用于容纳所有无需在 Webservice 和 Sidekiq 池中运行的辅助部署。

这包括与云提供商实现相关的各种部署,以及支持 GitLab 的部署(例如 GitLab Shell)。

若要部署其他部署(如容器注册表、Pages 或监控),应尽可能在 Supporting Node Pool 中进行,而非在 Webservice 或 Sidekiq 池中。Supporting Node Pool 已设计为容纳多个额外部署。但如果您的部署不符合给定池的要求,可相应增加节点池。反之,若您的用例中池过度配置,也可相应缩减。

示例配置文件

针对 200 RPS 或 10,000 用户的参考架构配置的 GitLab Helm Charts 示例可在 Charts 项目中找到 此处

下一步

遵循本指南后,您现在应已获得一个配置好核心功能的全新 GitLab 环境。

您可能需要根据需求配置 GitLab 的其他可选功能。有关更多信息,请参阅 安装 GitLab 后的步骤

根据您的环境和需求,设置所需的其他功能可能需要额外的硬件要求或调整。有关更多信息,请参阅各个页面。