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

---
stage: GitLab Delivery
group: 自托管
info: 要确定负责此页面所属阶段/组的专职技术 writers,请参阅 https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
title: '参考架构:支持最高100次请求每秒(RPS)或5000用户'
---

  • 层级:Premium, Ultimate
  • 提供方式:GitLab 自托管
本页介绍 GitLab 参考架构,旨在应对峰值负载为 100 次请求每秒(RPS)——基于真实数据的典型峰值负载,涵盖最多 5000 名手动及自动化用户。 完整参考架构列表,请参见 [可用参考架构](_index.md#available-reference-architectures)。

部署此架构前,建议先通读 主文档,特别是其中的 开始前准备选择合适的架构 章节。

> - **目标负载**:API:100 RPS,Web:10 RPS,Git(拉取):10 RPS,Git(推送):2 RPS > - **高可用性**:是([Praefect](#configure-praefect-postgresql) 需第三方 PostgreSQL 解决方案实现 HA) > - **云原生混合替代方案**:[是](#cloud-native-hybrid-reference-architecture-with-helm-charts-alternative) > - **不确定该用哪种参考架构?** [前往指南了解更多信息](_index.md#deciding-which-architecture-to-start-with) | 服务 | 节点数 | 配置 | GCP 示例<sup>1</sup> | AWS 示例<sup>1</sup> | Azure 示例<sup>1</sup> | |------------------------------------------|--------|------------------|----------------------|----------------------|------------------------| | 外部负载均衡器<sup>4</sup> | 1 | 4 vCPU,3.6 GB 内存 | `n1-highcpu-4` | `c5n.xlarge` | `F4s v2` | | Consul<sup>2</sup> | 3 | 2 vCPU,1.8 GB 内存 | `n1-highcpu-2` | `c5.large` | `F2s v2` | | PostgreSQL<sup>2</sup> | 3 | 4 vCPU,15 GB 内存 | `n1-standard-4` | `m5.xlarge` | `D4s v3` | | PgBouncer<sup>2</sup> | 3 | 2 vCPU,1.8 GB 内存 | `n1-highcpu-2` | `c5.large` | `F2s v2` | | 内部负载均衡器<sup>4</sup> | 1 | 4 vCPU,3.6 GB 内存 | `n1-highcpu-4` | `c5n.xlarge` | `F4s v2` | | Redis/Sentinel<sup>3</sup> | 3 | 2 vCPU,7.5 GB 内存 | `n1-standard-2` | `m5.large` | `D2s v3` | | Gitaly<sup>6</sup><sup>7</sup> | 3 | 8 vCPU,30 GB 内存 | `n1-standard-8` | `m5.2xlarge` | `D8s v3` | | Praefect<sup>6</sup> | 3 | 2 vCPU,1.8 GB 内存 | `n1-highcpu-2` | `c5.large` | `F2s v2` | | Praefect PostgreSQL<sup>2</sup> | 1+ | 2 vCPU,1.8 GB 内存 | `n1-highcpu-2` | `c5.large` | `F2s v2` | | Sidekiq<sup>8</sup> | 2 | 4 vCPU,15 GB 内存 | `n1-standard-4` | `m5.xlarge` | `D2s v3` | | GitLab Rails<sup>8</sup> | 3 | 16 vCPU,14.4 GB 内存 | `n1-highcpu-16` | `c5.4xlarge` | `F16s v2` | | 监控节点 | 1 | 2 vCPU,1.8 GB 内存 | `n1-highcpu-2` | `c5.large` | `F2s v2` | | 对象存储<sup>5</sup> | - | - | - | - | - | **脚注** <!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix --> <!-- markdownlint-disable MD029 --> 1. 机器类型示例仅为说明用途。这些类型用于 [验证与测试结果](_index.md#validation-and-test-results),但不作为强制默认值。切换至满足要求的其他机器类型(含可用 ARM 变体)均受支持。更多信息见 [支持的机器类型](_index.md#supported-machine-types)。 2. 可选运行于可靠的第三方外部 PaaS PostgreSQL 解决方案。详见 [提供自有 PostgreSQL 实例](#provide-your-own-postgresql-instance)。 3. 可选运行于可靠的第三方外部 PaaS Redis 解决方案。详见 [提供自有 Redis 实例](#provide-your-own-redis-instance)。 4. 建议搭配可靠第三方负载均衡器或服务(LB PaaS)以提供高可用能力。此外,规格需根据所选负载均衡器及其他因素(如网络带宽)调整。详见 [负载均衡器](_index.md#load-balancers)。 5. 应运行于可靠的云服务商或自托管解决方案。详见 [配置对象存储](#configure-the-object-storage)。 6. Gitaly 集群(Praefect)具备容错优势,但设置与管理复杂度更高。

请查看现有的部署 Gitaly 集群(Praefect)前的技术限制和注意事项。如果您想要分片的 Gitaly,请使用前表中列出的相同规格给 Gitaly。 7. Gitaly 的规格基于健康状态下使用模式和仓库大小的高百分位数。
但是,如果您有大型单体仓库(大于几 GB)或额外工作负载,这些会显著影响 Git 和 Gitaly 的性能,可能需要进一步调整。 8. 可以放置在自动伸缩组(ASGs)中,因为该组件不存储任何stateful 数据
不过,通常更推荐云原生混合架构,因为像migrationsMailroom这样的某些组件只能在一个节点上运行,而 Kubernetes 能更好地处理这种情况。

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

@startuml 5k
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** x2" 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** x3" as redis_nodes #FF6347
}

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

要求

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

测试方法

100 RPS / 5000用户的参考架构旨在适应大多数常见工作流程。GitLab定期针对以下端点吞吐量目标执行冒烟测试和性能测试:

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

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

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

性能注意事项

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

在这些情况下,请参阅扩展环境以获取更多信息。如果您认为这些注意事项适用于您,请联系我们以获得所需的额外指导。

负载均衡器配置

我们的测试环境使用:

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

设置组件

要设置GitLab及其组件以支持最多100 RPS或5000用户:

  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/Sentinel 1
  • 10.6.0.12:Consul/Sentinel 2
  • 10.6.0.13:Consul/Sentinel 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.20:内部负载均衡器
  • 10.6.0.61:Redis主节点
  • 10.6.0.62:Redis副本1
  • 10.6.0.63:Redis副本2
  • 10.6.0.51:Gitaly 1
  • 10.6.0.52: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.71:Sidekiq 1
  • 10.6.0.72:Sidekiq 2
  • 10.6.0.41:GitLab应用1
  • 10.6.0.42:GitLab应用2
  • 10.6.0.43:GitLab应用3
  • 10.6.0.81:Prometheus

配置外部负载均衡器

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

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

就绪检查

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

端口

需要使用的基本端口如下表所示。

| 负载均衡器端口 | 后端端口 | 协议 |\n| ————– | ——– | ——————– |\n| 80 | 80 | HTTP (1) |\n| 443 | 443 | TCP 或 HTTPS (1) (2) |\n| 22 | 22 | TCP |\n\n- (1): Web终端 支持要求您的负载均衡器正确处理WebSocket连接。当使用HTTP或HTTPS代理时,这意味着您的负载均衡器必须配置为传递 ConnectionUpgrade 逐跳头信息。有关更多详情,请参阅 web终端集成指南。\n- (2): 当对端口443使用HTTPS协议时,您必须在负载均衡器上添加SSL证书。如果您希望在GitLab应用服务器终止SSL,请改用TCP协议。\n\n如果您正在使用支持自定义域名的GitLab Pages,则需要一些额外的端口配置。\nGitLab Pages需要一个单独的虚拟IP地址。配置DNS将 /etc/gitlab/gitlab.rb 中的 pages_external_url 指向新的虚拟IP地址。有关更多信息,请参阅 GitLab Pages文档。\n\n| 负载均衡器端口 | 后端端口 | 协议 |\n| ————– | ———- | —– |\n| 80 | 可变 (1) | HTTP |\n| 443 | 可变 (1) | TCP (2) |\n\n- (1): GitLab Pages的后端端口取决于 gitlab_pages[\'external_http\']gitlab_pages[\'external_https\'] 设置。有关更多详情,请参阅 GitLab Pages文档。\n- (2): GitLab Pages的端口443应始终使用TCP协议。用户可以使用自定义SSL配置自定义域名,如果SSL在负载均衡器处终止,这将无法实现。\n\n#### 替代SSH端口\n\n有些组织有禁止开放SSH端口22的政策。在这种情况下,配置一个替代SSH主机名可能很有帮助,允许用户使用端口443进行SSH。与之前记录的其他GitLab HTTP配置相比,替代SSH主机名将需要一个新虚拟IP地址。\n\n为替代SSH主机名(如 altssh.gitlab.example.com)配置DNS。\n\n| 负载均衡器端口 | 后端端口 | 协议 |\n| ————– | ——– | —- |\n| 443 | 22 | TCP |\n\n### SSL\n\n下一个问题是您将如何在环境中处理SSL。\n有几种不同的选项:\n\n- 应用节点终止SSL。\n- 负载均衡器终止SSL且后端无SSL,并且负载均衡器和应用节点之间的通信不安全。\n- 负载均衡器终止SSL且后端有SSL,并且负载均衡器和应用节点之间的通信是安全的。\n\n#### 应用节点终止SSL\n\n将您的负载均衡器配置为以 TCP 而非 HTTP(S) 协议传递端口443上的连接。这将原样传递到应用节点的NGINX服务。NGINX将拥有SSL证书并在端口443上监听。\n\n有关管理SSL证书和配置NGINX的详细信息,请参阅 HTTPS文档。\n\n#### 负载均衡器终止SSL且后端无SSL\n\n将您的负载均衡器配置为使用 HTTP(S) 而非 TCP 协议。然后负载均衡器将负责管理SSL证书并终止SSL。\n\n由于负载均衡器和GitLab之间的通信不安全,因此需要进行一些额外配置。有关详情,请参阅 代理SSL文档。\n\n#### 负载均衡器终止SSL且后端有SSL\n\n将您的负载均衡器配置为使用 HTTP(S) 而非 TCP 协议。负载均衡器将负责管理最终用户可见的SSL证书。\n\n在此场景中,负载均衡器和NGINX之间的流量也将是安全的。由于连接在整个过程中都是安全的,因此不需要为代理SSL添加配置。但是,必须在GitLab中添加配置以配置SSL证书。有关管理SSL证书和配置NGINX的详细信息,请参阅 HTTPS文档。\n\n

配置内部负载均衡器

在多节点 GitLab 配置中,如果配置了诸如连接到 PgBouncerGitaly 集群(Praefect) 等选择性的内部组件,您将需要一台内部负载均衡器来路由流量。

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

以下 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. 实现高可用所需的节点数量可能因服务而异,也可能与 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,但 不要 提供 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 用户配置
    # 请按照“必需信息”部分说明设置真实值
    #
    # 用生成的 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 用户配置

由 Patroni 管理故障转移的 PostgreSQL 默认使用 pg_rewind 处理冲突。与其他故障转移处理方式类似,这有极小的可能导致数据丢失风险。更多信息请参见各种 Patroni 复制方法

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

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

高级配置选项

被支持且如果需要可以添加。

PostgreSQL 后续配置

通过 SSH 连接到主站点的任意一个 Patroni 节点:

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

    gitlab-ctl patroni members

    输出应类似于以下内容:

    | 集群         | 成员                              | 主机      | 角色   | 状态   | 时间线 | 滞后量(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           | *            |

如果任何节点的“状态”列未显示 “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> 替换为您之前设置的密码哈希值(参考此处):
# 禁用除 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'
pgbouncer_exporter['listen_address'] = '0.0.0.0:9188'
  1. 从您配置的第一个 Linux 包节点复制 /etc/gitlab/gitlab-secrets.json 文件,并将其添加或替换到此服务器上的同名文件。如果您正在配置第一个 Linux 包节点,则可以跳过此步骤。

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

  3. 创建一个 .pgpass 文件,以便 Consul 能够重新加载 PgBouncer。当提示时,两次输入 PgBouncer 密码:

gitlab-ctl write-pgpass --host 127.0.0.1 --database pgbouncer --user pgbouncer --hostuser gitlab-consul
  1. 确保每个节点都与当前的主节点通信:
gitlab-ctl pgb-console # 您将被提示输入 PGBOUNCER_PASSWORD

如果在输入密码后出现 psql: ERROR: Auth failed 错误,请确保您之前使用正确的格式生成了 MD5 密码哈希。正确的格式是将密码和用户名连接起来:PASSWORDUSERNAME。例如,Sup3rS3cr3tpgbouncer 就是生成 pgbouncer 用户 MD5 密码哈希所需的文本。

  1. 控制台提示符可用后,运行以下查询:
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)
  1. 验证 GitLab 服务是否正在运行:
sudo gitlab-ctl status

输出应类似于以下内容:

run: consul: (pid 31530) 77150s; run: log: (pid 31106) 77182s
run: logrotate: (pid 32613) 3357s; run: log: (pid 30107) 77500s
run: node-exporter: (pid 31550) 77149s; run: log: (pid 30138) 77493s
run: pgbouncer: (pid 32033) 75593s; run: log: (pid 31117) 77175s
run: pgbouncer-exporter: (pid 31558) 77148s; run: log: (pid 31498) 77156s

配置 Redis

在可扩展环境中使用 Redis 可以通过 主节点(Primary)x 副本(Replica) 拓扑结构实现,并搭配 Redis Sentinel 服务来监控和自动执行故障转移流程。

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

Redis 主要是单线程的,增加 CPU 核心并不能显著提升性能。更多详情请参阅 扩容文档

若与 Sentinel 一起使用,Redis 需要身份验证。更多信息请参见 Redis 安全文档。我们建议结合 Redis 密码和严格的防火墙规则来保障 Redis 服务安全。在配置 GitLab 时,强烈建议先阅读 Redis Sentinel 文档 以充分理解其拓扑结构和架构。

Redis 部署需满足以下要求:

  1. 所有 Redis 节点必须能够相互通信,并通过 Redis(6379)和 Sentinel(26379)端口接受传入连接(除非修改了默认端口)。
  2. 托管 GitLab 应用的服务器必须能够访问 Redis 节点。
  3. 使用防火墙等措施保护节点免受外部网络(互联网)的访问。

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

  • 10.6.0.61:Redis 主节点
  • 10.6.0.62:Redis 副本 1
  • 10.6.0.63:Redis 副本 2

提供自己的 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绑定地址和法定人数
    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'
    redis['master_password'] = 'REDIS_PRIMARY_PASSWORD'
    
    ## 所有Redis节点必须一致
    redis['master_name'] = 'gitlab-redis'
    
    ## 此主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,使更改生效。

配置副本 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'
    redis['master_password'] = 'REDIS_PRIMARY_PASSWORD'
    
    ## 所有 Redis 节点必须相同
    redis['master_name'] = 'gitlab-redis'
    
    # 主 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),
    }
    
    # 设置 exporter 监听的网路地址
    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 Cluster (Praefect) 是 GitLab 提供并推荐的用于存储 Git 仓库的容错解决方案。在此配置中,每个 Git 仓库都会存储在集群中的每个 Gitaly 节点上,其中一个被指定为主节点,若主节点宕机则会自动进行故障转移。

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

Gitaly Cluster (Praefect) 提供了容错的优势,但也带来了额外的设置和管理复杂度。 在部署 Gitaly Cluster (Praefect) 前,请先查看现有的技术限制和注意事项

关于以下方面的指导:

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

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

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

配置 Praefect PostgreSQL

Praefect 作为 Gitaly Cluster (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 configuration
    # 请按照“必需信息”部分所述设置真实值
    #
    # 将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 configuration
  5. 从你配置的第一个Linux包节点复制/etc/gitlab/gitlab-secrets.json文件,并在本服务器的同名文件中添加或替换。如果这是你要配置的第一个Linux包节点,则可以跳过此步骤。

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

  7. 遵循后续配置

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

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

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

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

使用第三方设置时,可以将Praefect的数据库与主Github数据库放在同一台服务器上以方便使用,除非你使用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 的连接都通过它进行。本节详细介绍如何配置它。

Praefect 必须部署在奇数个节点(至少 3 个)上。这是为了确保节点能够作为仲裁组的一部分参与投票。

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

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

Gitaly 集群(Praefect)节点在 Praefect 中通过 virtual storage 进行配置。每个存储包含构成集群的每个 Gitaly 节点的详细信息。每个存储也被赋予一个名称,该名称在配置的多个区域中使用。在本指南中,存储的名称是 default。此外,本指南针对新安装,如果将现有环境升级以使用 Gitaly 集群(Praefect),则可能需要使用不同的名称。有关更多信息,请参阅 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 用于监控的监听网络地址
    }
# 设置GitLab组件将使用的Prometheus地址
prometheus_listen_addr: '0.0.0.0:9652',
}

# 设置用于监控的节点导出器(node exporter)将监听的网路地址
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 规格基于健康状态下使用模式及仓库大小的高百分位数据但是,如果您有 大型单体仓库(大于数 GB)或 额外工作负载,这些因素会显著影响环境性能,可能需要进一步调整。 如果认为这适用于您的情况,请根据需要联系我们来获取额外指导。

Gitaly 对 Gitaly 存储有特定的 磁盘要求

Gitaly 服务器不得暴露于公共互联网,因为默认情况下 Gitaly 的网络流量未加密。强烈建议使用防火墙来限制对 Gitaly 服务器的访问。另一个选项是 使用 TLS

配置 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. 下载并安装 您选择的 Linux 包。务必仅添加 GitLab 包仓库并为所选操作系统安装 GitLab,但不要提供 EXTERNAL_URL 值。

  2. 编辑 Gitaly 服务器节点的 /etc/gitlab/gitlab.rb 文件以配置存储路径、启用网络监听器并配置令牌:

    # 避免在 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 Pack-objects 缓存
          # 建议启用以提高性能,但可能显著增加磁盘 I/O
          # 参见 https://docs.gitlab.com/ee/administration/gitaly/configure_gitaly.html#pack-objects-cache 了解详情
          enabled: true,
       },
    }
    
    #
    # END 用户配置
  3. 向每个相应服务器的 /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服务器上。

此外,必须在所有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 需要连接到 RedisPostgreSQLGitaly 实例。同时也建议连接到 对象存储

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

如果您发现环境中 Sidekiq 作业处理缓慢且队列过长,可以根据需要添加更多节点。您还可以调整 Sidekiq 节点以运行 多个 Sidekiq 进程

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

  • 10.6.0.71: Sidekiq 1
  • 10.6.0.72: Sidekiq 2

要在每个 Sidekiq 节点上配置 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
    roles(["sidekiq_role"])
    
    # 外部 URL
    ## 这应与外部负载均衡器的 URL 匹配
    external_url 'https://gitlab.example.com'
    
    # Redis
    ## 在每个哨兵节点中必须相同
    redis['master_name'] = 'gitlab-redis'
    
    ## 与为主节点设置的 Redis 认证相同的密码。
    redis['master_password'] = '<redis_primary_password>'
    
    ## 哨兵列表,包含 `host` 和 `port`
    gitlab_rails['redis_sentinels'] = [
       {'host' => '10.6.0.11', 'port' => 26379},
       {'host' => '10.6.0.12', 'port' => 26379},
       {'host' => '10.6.0.13', '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.81/32', '127.0.0.0/8']
    gitlab_rails['prometheus_address'] = '10.6.0.81:9090'
    
    # 对象存储
    ## 这是一个在 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. 为确保数据库迁移仅在重新配置时运行,而非在升级时自动运行,请执行以下命令:
   ```shell
   sudo touch /etc/gitlab/skip-auto-reconfigure

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

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

  2. 验证 GitLab 服务是否正在运行:

    sudo gitlab-ctl status

    输出应类似如下:

    run: consul: (pid 30114) 77353s; run: log: (pid 29756) 77367s
    run: logrotate: (pid 9898) 3561s; run: log: (pid 29653) 77380s
    run: node-exporter: (pid 30134) 77353s; run: log: (pid 29706) 77372s
    run: sidekiq: (pid 30142) 77351s; run: log: (pid 29638) 77386s
```

配置 GitLab Rails

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

Rails 需要连接到 RedisPostgreSQLGitaly 实例。还建议连接到 Object Storage

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

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

  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 连接详情
    ## 必须与每个哨兵节点相同
    redis['master_name'] = 'gitlab-redis'
    
    ## 与您为 Redis 主节点设置的认证密码相同
    redis['master_password'] = '<redis_primary_password>'
    
    ## 哨兵列表,包含 `host` 和 `port`
    gitlab_rails['redis_sentinels'] = [
      {'host' => '10.6.0.11', 'port' => 26379},
      {'host' => '10.6.0.12', 'port' => 26379},
      {'host' => '10.6.0.13', 'port' => 26379}
    ]
    
    ## 启用 Prometheus 服务发现
    consul['enable'] = true
    consul['monitoring_service_discovery'] =  true
    
    # 设置导出器用于监控的监听网络地址
    node_exporter['listen_address'] = '0.0.0.0:9100'
    gitlab_workhorse['prometheus_listen_addr'] = '0.0.0.0:9229'
    sidekiq['listen_address'] = "0.0.0.0"
    puma['listen'] = '0.0.0.0'
    
    ## Consul 服务器节点的 IP
    ## 您也可以使用 FQDN 并将其与 IP 混合使用
    consul['configuration'] = {
       retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13),
    }
    
    # 将监控节点的 IP 地址添加到监控白名单,允许其抓取 NGINX 指标
    gitlab_rails['monitoring_whitelist'] = ['10.6.0.81/32', '127.0.0.0/8']
    nginx['status']['options']['allow'] = ['10.6.0.81/32', '127.0.0.0/8']
    gitlab_rails['prometheus_address'] = '10.6.0.81:9090'
    
    #############################
    ###     对象存储          ###
    #############################
    
    # 这是一个在 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'] = {

```markdown
```ruby
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>'
}

## 取消注释并编辑以下选项(如果您已设置NFS)
##
## 如果NFS数据挂载不可用,阻止GitLab启动
##
#high_availability['mountpoint'] = '/var/opt/gitlab/git-data'
##
## 通过NFS确保服务器间UID和GID一致以实现权限管理
##
#user['uid'] = 9000
#user['gid'] = 9000
#web_server['uid'] = 9001
#web_server['gid'] = 9001
#registry['uid'] = 9002
#registry['gid'] = 9002
  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. 运行sudo gitlab-rake gitlab:gitaly:check以确认节点可与Gitaly连接。

  8. 查看日志以查看请求:

    sudo gitlab-ctl tail gitaly
  9. 验证GitLab服务是否正在运行:

    sudo gitlab-ctl status

    输出应类似于以下内容:

    run: consul: (pid 4890) 8647s; run: log: (pid 29962) 79128s
    run: gitlab-exporter: (pid 4902) 8647s; run: log: (pid 29913) 79134s
    run: gitlab-workhorse: (pid 4904) 8646s; run: log: (pid 29713) 79155s
    run: logrotate: (pid 12425) 1446s; run: log: (pid 29798) 79146s
    run: nginx: (pid 4925) 8646s; run: log: (pid 29726) 79152s
    run: node-exporter: (pid 4931) 8645s; run: log: (pid 29855) 79140s
    run: puma: (pid 4936) 8645s; run: log: (pid 29656) 79161s

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


### GitLab Rails 后配置

1. 确保所有迁移已运行:

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

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

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

配置 Prometheus

Linux 包可用于配置运行 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

  5. 验证 GitLab 服务是否正在运行:

    sudo gitlab-ctl status

    输出应类似于以下内容:

    run: consul: (pid 31637) 17337s; run: log: (pid 29748) 78432s
    run: logrotate: (pid 31809) 2936s; run: log: (pid 29581) 78462s
    run: nginx: (pid 31665) 17335s; run: log: (pid 29556) 78468s
    run: prometheus: (pid 31672) 17335s; run: log: (pid 29633) 78456s

配置对象存储

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

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

当可用时,以下示例中使用合并形式。

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

启用增量日志

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

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

配置高级搜索

您可以借助 Elasticsearch 并 启用高级搜索,以在整个 GitLab 实例中进行更快、更高级的代码搜索。

Elasticsearch 集群的设计和要求取决于您的具体数据。关于如何在与实例一起设置 Elasticsearch 集群的最佳实践建议,请阅读如何 选择最佳集群配置

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

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

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

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

参考 Helm 图表 高级配置 文档,了解包含如何在 Kubernetes 与后端组件间同步哪些 GitLab 密钥在内的设置说明。

这是一个高级设置。在 Kubernetes 中运行服务众所周知非常复杂。此设置仅建议您具备扎实的 Kubernetes 工作知识和经验。本节剩余内容基于这一前提。

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

集群拓扑

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

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

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

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

服务 节点数 配置 GCP 示例1 AWS 示例1
Consul2 3 2 vCPU, 1.8 GB 内存 n1-highcpu-2 c5.large
PostgreSQL2 3 4 vCPU, 15 GB 内存 n1-standard-4 m5.xlarge
PgBouncer3 3 2 vCPU, 1.8 GB 内存 n1-highcpu-2 c5.large
内部负载均衡器4 1 4 vCPU, 3.6 GB 内存 n1-highcpu-4 c5n.xlarge
Redis/Sentinel3 3 2 vCPU, 7.5 GB 内存 n1-standard-2 m5.large
Gitaly67 3 8 vCPU, 30 GB 内存 n1-standard-8 m5.2xlarge
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实例

  4. 建议使用信誉良好的第三方负载均衡器或服务(LB PaaS)运行。
    此外,规格大小取决于所选的负载均衡器和网络带宽等其他因素。更多信息请参阅 负载均衡器

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

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

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

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

@startuml 5k
skinparam linetype ortho

card "通过 Helm 图表实现的 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_nodes #FF6347
}

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 工作进程
  • 4 个 vCPU
  • 5 GB 内存(请求)
  • 7 GB 内存(限制)

对于 100 RPS 或 5000 用户,我们建议总 Puma 工作进程数约为 36,因此建议至少运行 9 个 Webservice Pod。

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

NGINX

还建议将 NGINX 控制器 Pod 作为 DaemonSet 部署在 Webservice 节点上。这允许控制器根据所服务的 Webservice Pod 动态扩展,并利用更大机器类型通常具有的更高网络带宽。

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

Sidekiq

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

  • 1 个 Sidekiq 工作进程
  • 900m vCPU
  • 2 GB 内存(请求)
  • 4 GB 内存(限制)

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

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

支持

支持节点池旨在容纳所有不需要在 Webservice 和 Sidekiq 节点池中运行的辅助部署。

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

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

示例配置文件

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

下一步

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

您可能需要根据需求配置额外的可选功能。更多信息请参见 安装 GitLab 后的步骤

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