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

参考架构:支持最高 1000 RPS 或 50,000 用户

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

本页描述了 GitLab 参考架构,旨在针对每秒 1000 次请求(RPS)的峰值负载,基于真实数据,典型峰值负载可达 50,000 个用户(包括手动和自动化用户)。

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

在部署此架构之前,建议先阅读主要文档,特别是其中的开始前准备决定使用哪种架构部分。

  • 目标负载: API: 1000 RPS, Web: 100 RPS, Git (拉取): 100 RPS, Git (推送): 20 RPS
  • 高可用性: 是 (Praefect 需要第三方 PostgreSQL 解决方案来实现高可用)
  • 云原生混合替代方案:
  • 不确定该使用哪个参考架构? 前往此指南获取更多信息
服务 节点数 配置 GCP 示例1 AWS 示例1 Azure 示例1
外部负载均衡器4 1 16 vCPU, 14.4 GB 内存 n1-highcpu-16 c5.4xlarge F16s v2
Consul2 3 2 vCPU, 1.8 GB 内存 n1-highcpu-2 c5.large F2s v2
PostgreSQL2 3 32 vCPU, 120 GB 内存 n1-standard-32 m5.8xlarge D32s v3
PgBouncer2 3 2 vCPU, 1.8 GB 内存 n1-highcpu-2 c5.large F2s v2
内部负载均衡器4 1 16 vCPU, 14.4 GB 内存 n1-highcpu-16 c5.4xlarge F16s 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 64 vCPU, 240 GB 内存 n1-standard-64 m5.16xlarge D64s v3
Praefect6 3 4 vCPU, 3.6 GB 内存 n1-highcpu-4 c5.xlarge F4s 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 12 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 的规格基于良好健康状态下的使用模式和仓库大小的高百分位数。但是,如果您有大型单体仓库(大于几吉字节)或其他工作负载,这些会显著影响 Git 和 Gitaly 的性能,可能还需要进一步调整。

  8. 可以放置在自动伸缩组(ASGs)中,因为该组件不存储任何有状态数据。不过,通常更倾向于采用云原生混合架构,因为像迁移邮件室这样的某些组件只能在一个节点上运行,而 Kubernetes 能更好地处理这种情况。

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

@startuml 50k
skinparam linetype ortho

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

together {
  collections "**GitLab Rails** x12" 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

要求

开始前,请参阅 参考架构的要求

测试方法

支持每秒1000次请求(RPS)/5万名用户的参考架构设计用于适配大多数常见工作流。GitLab定期针对以下端点吞吐量目标进行冒烟测试和性能测试:

端点类型 目标吞吐量
API 1000 RPS
Web 100 RPS
Git(拉取) 100 RPS
Git(推送) 20 RPS

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

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

性能考量

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

在这些情况下,请参阅 扩展环境 获取更多信息。如果您认为这些考量适用于您的情况,请联系我们获取必要的额外指导。

负载均衡器配置

我们的测试环境使用:

  • Linux包环境:HAProxy
  • 云原生混合环境:NGINX Ingress云服务商等效方案

配置组件

要将GitLab及其组件配置为支持最高1000 RPS或5万名用户:

  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.114:GitLab应用4
  • 10.6.0.115:GitLab应用5
  • 10.6.0.116:GitLab应用6
  • 10.6.0.117:GitLab应用7
  • 10.6.0.118:GitLab应用8
  • 10.6.0.119:GitLab应用9
  • 10.6.0.120:GitLab应用10
  • 10.6.0.121:GitLab应用11
  • 10.6.0.122:GitLab应用12
  • 10.6.0.151:Prometheus

配置外部负载均衡器

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

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

就绪检查

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

端口

基本端口如下表所示。

LB 端口 后端端口 协议
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 文档

LB 端口 后端端口 协议
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。

LB 端口 后端端口 协议
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 个或更多奇数节点上。这是为了确保节点可以作为仲裁(quorum)的一部分进行投票。

以下 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),
    }
    
    # 设置 exporter 将监听的网路地址
    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. 达到高可用性所需的节点数量可能因服务而异,也可能与 Linux 软件包不同。
  6. 但是,如果希望通过读副本实现 数据库负载均衡 以进一步提高性能,建议遵循参考架构的节点计数。
### 使用Linux包的独立PostgreSQL

对于带有复制和高可用性的PostgreSQL集群,推荐的Linux包配置要求如下:

- 至少三个PostgreSQL节点。
- 至少三个Consul服务器节点。
- 至少三个PgBouncer节点,用于跟踪和处理主数据库的读写操作。
  - 一个[内部负载均衡器](#configure-the-internal-load-balancer)(TCP),用于在PgBouncer节点之间平衡请求。
- 已启用[数据库负载均衡](../postgresql/database_load_balancing.md)。

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

以下IP将用作示例:

- `10.6.0.21`:PostgreSQL主节点
- `10.6.0.22`:PostgreSQL从节点1
- `10.6.0.23`:PostgreSQL从节点2

首先,确保在[安装](../../install/package/_index.md#supported-platforms)Linux包**在每个节点上**。请务必仅添加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['enable'] = true
    consul['services'] = %w(postgresql)
    ## 启用 Prometheus 的服务发现
    consul['monitoring_service_discovery'] =  true
    
    # START user configuration
    # 请按照“所需信息”部分说明设置真实值
    #
    # 用生成的 md5 值替换 PGBOUNCER_PASSWORD_HASH
    postgresql['pgbouncer_user_password'] = '<pgbouncer_password_hash>'
    # 用生成的 md5 值替换 POSTGRESQL_REPLICATION_PASSWORD_HASH
    postgresql['sql_replication_password'] = '<postgresql_replication_password_hash>'
    # 用生成的 md5 值替换 POSTGRESQL_PASSWORD_HASH
    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>'
       }
    }
    
    # 设置 exporter 监听的网路地址以供监控
    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

    输出应类似如下:

    | Cluster       | Member                            |  Host     | Role   | State   | TL  | Lag in MB | Pending restart |
    |---------------|-----------------------------------|-----------|--------|---------|-----|-----------|-----------------|
    | 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 是可行的,采用 主节点 x 副本节点 拓扑结构,搭配 Redis哨兵 服务来监控并自动启动故障转移流程。

每个Redis集群必须部署在奇数个(至少3个)节点上。这是为了确保Redis哨兵能够参与投票形成仲裁。若通过外部方式(例如云服务商服务)配置Redis,此规则不适用。

Redis主要是单线程的,增加CPU核心并不能显著提升性能。对于这种规模的架构,强烈建议按照指定要求将缓存和持久化实例分开部署,以在此规模下实现最佳性能。更多信息请参阅 扩容文档

若与哨兵一同使用,Redis需要身份验证。详见 Redis安全 文档。我们建议结合Redis密码和严格的防火墙规则来保护Redis服务。在用GitLab配置Redis前,强烈建议阅读 Redis哨兵 文档,以全面理解其拓扑结构和架构。

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缓存和持久化实例,遵循以下指引:

更多信息请见 推荐的云服务商和服务

配置Redis缓存集群

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

主节点和副本节点的Redis都需要在 redis['password'] 中定义相同的密码。在任何故障转移过程中,哨兵可重新配置节点并将其状态从主节点切换为副本节点(反之亦然)。

配置主Redis缓存节点

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

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

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

    # 指定服务器角色为'redis_sentinel_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的IP地址,其他机器可以通过该IP访问。
    # 你也可以将bind设置为'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服务器。

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

  3. 编辑/etc/gitlab/gitlab.rb,通过将redis_master_node替换为redis_replica_node,添加与前一部分主节点相同的内容:

    # 指定服务器角色为'redis_replica_role',启用Sentinel和Consul代理
    roles(['roles_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),
    }
    
    # 设置exporters监听的网路地址
    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节点都需要在redis['password']中定义相同的密码。在任何故障转移期间,Sentinel可以重新配置节点并将其状态从主节点切换为副本节点(反之亦然)。

配置主Redis持久节点

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

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

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

    # 指定服务器角色为包含 Sentinel 的 'redis_master_role' 并启用 Consul 代理
    roles ['redis_sentinel_role', 'redis_master_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.61'
    
    # 定义一个端口,使 Redis 能够监听 TCP 请求,从而允许其他机器连接到它。
    redis['port'] = 6379
    
    ## Sentinel 所需的主 Redis 服务器端口,取消注释可更改为非默认值。默认值为 `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),
    }
    
    # 设置导出器将监听的网路地址
    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 以使更改生效。

配置副本Redis持久节点

  1. 通过SSH连接到副本Redis持久服务器。

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

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

    # 指定服务器角色为'redis_sentinel_role',启用Sentinel和Consul代理
    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 仓库。在此配置中,每个 Git 仓库都存储在集群中的每个 Gitaly 节点上,其中一个被指定为主节点,若主节点宕机则会自动进行故障转移。

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)的路由器和事务管理器,需要专属数据库服务器来存储 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 user配置
    # 请按照“必需信息”部分说明设置真实值
    #
    # 将PRAEFECT_POSTGRESQL_PASSWORD_HASH替换为生成的md5值
    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 user配置
  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 Cluster 的路由器和事务管理器,所有到 Gitaly 的连接都通过它。本节详细说明如何配置它。

Praefect 必须以 3 个或更多奇数节点的方式部署。这是为了确保节点能够参与投票并形成法定人数(quorum)。

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

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

Gitaly Cluster (Praefect) 节点通过 virtual storage 在 Praefect 中进行配置。每个存储包含构成集群的每个 Gitaly 节点的详细信息。每个存储还会被赋予一个名称,该名称在配置的多个地方使用。在本指南中,存储的名称将为 default。此外,本指南针对新安装场景,若要将现有环境升级至使用 Gitaly Cluster (Praefect),可能需要使用不同的名称。更多信息请参阅 Gitaly Cluster (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 服务器上 gitlab_rails['repositories_storages'] 中的存储名称('praefect')以及 Gitaly 节点上 gitaly['configuration'][:storage] 中的名称('gitaly-1')匹配
       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 用于监控的监听网络地址
    }
prometheus_listen_addr: '0.0.0.0:9652',\n   }\n\n   # 设置节点导出器监听的网络地址以进行监控\n   node_exporter[\'listen_address\'] = \'0.0.0.0:9100\'\n\n   ## Consul服务器节点的IP地址\n   ## 您也可以使用FQDN,并与IP地址混合使用\n   consul[\'configuration\'] = {\n      retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),\n   }\n   #\n   # END 用户配置\n   ```\n\n1. 从您配置的第一个Linux包节点复制`/etc/gitlab/gitlab-secrets.json`文件,并将其添加或替换到本服务器的同名文件中。如果这是您正在配置的第一个Linux包节点,则可以跳过此步骤。\n\n1. Praefect需要运行一些数据库迁移,类似于主GitLab应用程序。为此,您应该**只选择一个Praefect节点来运行迁移**,即所谓的_部署节点(Deploy Node)_。该节点必须首先按以下方式配置,然后再配置其他节点:\n\n   1. 在`/etc/gitlab/gitlab.rb`文件中,将`praefect[\'auto_migrate\']`设置值从`false`更改为`true`\n\n   1. 为确保数据库迁移仅在重新配置期间运行,而非在升级时自动运行,请执行:\n\n   ```shell\n   sudo touch /etc/gitlab/skip-auto-reconfigure\n   ```\n\n   1. [重新配置GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation),使更改生效并运行Praefect数据库迁移。\n\n1. 在所有其他Praefect节点上,[重新配置GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation),使更改生效。\n```

### 配置Gitaly

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

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

Gitaly对Gitaly存储有特定的[磁盘要求](../gitaly/_index.md#disk-requirements)。 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['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打包对象缓存 # 建议启用以提高性能,但会显著增加磁盘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 节点 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服务器上。

此外,所有与该Praefect通信的Gitaly服务器和Praefect客户端都必须按照GitLab自定义证书配置中描述的程序(下文重复)安装证书或其证书颁发机构。

请注意以下几点:

  • 证书必须指定用于访问Praefect服务器的地址。您必须在证书中将主机名或IP地址添加为备用名称(Subject Alternative Name)。
  • 您可以同时配置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 需要连接到 RedisPostgreSQLGitaly 实例。 还建议它连接到 对象存储

由于建议使用对象存储 而非 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 服务器。

  2. 确认您可以访问 PostgreSQL、Gitaly 和 Redis 端口:

    telnet <GitLab 主机> 5432 # PostgreSQL
    telnet <GitLab 主机> 8075 # Gitaly
    telnet <GitLab 主机> 6379 # Redis
  3. 下载并安装 您选择的 Linux 包。 请确保仅添加 GitLab 软件包仓库并为您的操作系统安装 GitLab。

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

    # https://docs.gitlab.com/omnibus/roles/#sidekiq-roles
    角色(["sidekiq_role"])
    
    # 外部 URL
    ## 此处应匹配外部负载均衡器的 URL
    external_url 'https://gitlab.example.com'
    
    # Redis
    ## Redis 连接详情
    ## 第一个集群将托管缓存数据
    gitlab_rails['redis_cache_instance'] = 'redis://:<第一个集群的 REDIS_PRIMARY_PASSWORD>@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>'
    
    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 的内部负载均衡器
    # 令牌是 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.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 IP 列表
    
    ## 升级时防止数据库迁移自动运行
    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包节点,则可以跳过此步骤。
1. 从你配置的第一个Rails节点复制SSH主机密钥(所有名称格式为`/etc/ssh/ssh_host_*_key*`的文件),并将同名文件添加或替换到此服务器上。这可确保当用户访问负载均衡的Rails节点时不会抛出主机不匹配错误。如果这是你要配置的第一个Linux包节点,则可以跳过此步骤。
1. 为确保数据库迁移仅在重新配置期间运行,而不是在升级时自动运行,请执行以下操作:

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

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

  1. 重新配置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
  • 10.6.0.114:GitLab 应用 4
  • 10.6.0.115:GitLab 应用 5
  • 10.6.0.116:GitLab 应用 6
  • 10.6.0.117:GitLab 应用 7
  • 10.6.0.118:GitLab 应用 8
  • 10.6.0.119:GitLab 应用 9
  • 10.6.0.120:GitLab 应用 10
  • 10.6.0.121:GitLab 应用 11
  • 10.6.0.122:GitLab 应用 12

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

  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 虚拟存储进行配置
    # Address 是 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’] = “” gitlab_rails[‘object_store’][‘objects’][‘dependency_proxy’][‘bucket’] = “” gitlab_rails[‘object_store’][‘objects’][’terraform_state’][‘bucket’] = “

gitlab_rails[‘backup_upload_connection’] = { ‘provider’ => ‘Google’, ‘google_project’ => ‘’, ‘google_json_key_location’ => ‘’ }

gitlab_rails[‘backup_upload_remote_directory’] = “” 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’ => ‘’, ‘google_json_key_location’ => ‘’ }


1. 如果您使用带有TLS支持的[Gitaly](#gitaly-cluster-praefect-tls-support),请确保`gitlab_rails['repositories_storages']`条目配置为`tls`而不是`tcp`:

```ruby
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/
  1. 从您配置的第一个Linux包节点复制/etc/gitlab/gitlab-secrets.json文件,并将同名文件添加或替换到此服务器上。如果这是您正在配置的第一个Linux包节点,则可以跳过此步骤。
  2. 为确保数据库迁移仅在重新配置期间运行,而非在升级时自动运行,请执行以下操作:
sudo touch /etc/gitlab/skip-auto-reconfigure

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

  1. 重新配置GitLab以使更改生效。
  2. 启用增量日志记录
  3. 确认节点可以连接到Gitaly:
sudo gitlab-rake gitlab:gitaly:check

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

sudo gitlab-ctl tail gitaly
  1. 可选地,从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 数据库并确保所有迁移已完成:

    sudo gitlab-rake gitlab:db:configure

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

  2. 配置快速查找数据库中授权的 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 的高级配置文档(https://docs.gitlab.com/charts/advanced/),了解设置说明,包括如何在 Kubernetes 和后端组件之间同步哪些 GitLab 密钥的指导。

这是一个高级设置。众所周知,在 Kubernetes 中运行服务很复杂。仅当你具备扎实的 Kubernetes 知识和经验时,才建议采用此设置。本节的其余部分基于这一假设。

Gitaly Cluster(Praefect)不支持在 Kubernetes 中运行。更多详情请参阅 epic 6127(https://gitlab.com/groups/gitlab-org/-/epics/6127)。

集群拓扑

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

首先是运行在Kubernetes中的组件。这些组件分布在多个节点组中运行,尽管您可以根据需要更改整体组成,只要满足最低CPU和内存要求即可。

组件 节点组 目标节点池总计 GCP 示例 AWS 示例
Web服务 308 vCPU
385 GB 内存(请求)
539 GB 内存(限制)
11 × n1-standard-32 11 × 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服务也可能适用,但效果可能有所不同。
  • 提供机器类型示例仅用于说明目的。这些类型用于验证和测试,但不作为规定性默认值。支持切换到符合列出要求的其他机器类型。有关更多信息,请参阅支持的机器类型
  • Web服务Sidekiq 的目标节点池总计仅为GitLab组件提供。所选Kubernetes提供商的系统进程需要额外的资源。给出的示例已考虑这一点。
  • 支持服务 的目标节点池总计通常是为了容纳支持GitLab部署的多种资源,以及根据您的需求可能希望进行的任何额外部署。与其他节点池类似,所选Kubernetes提供商的系统进程也需要资源。给出的示例已考虑这一点。
  • 在生产部署中,不需要将Pod分配给特定节点。但是,建议在每个池中使用多个跨不同可用区的节点,以符合弹性云架构实践。
  • 出于效率原因,鼓励启用自动扩展功能(如Cluster Autoscaler),但通常建议将Web服务和Sidekiq Pod的目标设置为不低于75%,以确保持续的性能。

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

服务 节点数 配置 GCP 示例1 AWS 示例1
Consul2 3 2 vCPU, 1.8 GB 内存 n1-highcpu-2 c5.large
PostgreSQL2 3 32 vCPU, 120 GB 内存 n1-standard-32 m5.8xlarge
PgBouncer2 3 2 vCPU, 1.8 GB 内存 n1-highcpu-2 c5.large
内部负载均衡器4 1 16 vCPU, 14.4 GB 内存 n1-highcpu-16 c5.4xlarge
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 64 vCPU, 240 GB 内存 n1-standard-64 m5.16xlarge
Praefect6 3 4 vCPU, 3.6 GB 内存 n1-highcpu-4 c5.xlarge
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核心并不能显著提升性能。对于这种规模的架构,强烈建议按照指定使用独立的缓存(Cache)和持久化(Persistent)实例,以实现最佳性能。
  4. 可以选择在信誉良好的第三方负载均衡服务(LB PaaS)上运行。有关更多信息,请参阅推荐云提供商和服务

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

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

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

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

@startuml 50k
skinparam linetype ortho

card "Kubernetes via Helm Charts" as kubernetes {
  card "**External Load Balancer**" as elb #6a9be7

  together {
    collections "**Webservice**" as gitlab #32CD32
    collections "**Sidekiq**" as sidekiq #ff8dd1
  }

  card "**Supporting Services**" as support
}

card "**Internal Load Balancer**" as ilb #9370DB
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 -[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 内存(限制)

对于 1000 RPS 或 50000 用户,我们建议总 Puma worker 数量约为 308,因此建议至少运行 77 个 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。根据具体工作流程,可能需要额外的工作器。

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

Supporting

Supporting Node Pool 设计用于容纳所有不在 Webservice 和 Sidekiq 池中必需的支持部署。

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

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

示例配置文件

针对 1000 RPS 或 50000 用户参考架构配置的 GitLab Helm Charts 示例 可在 Charts 项目中找到

下一步

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

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

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