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

参考架构:最多500次请求每秒(RPS)或25,000用户

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

本页描述了针对峰值负载为500次请求每秒(RPS)的GitLab参考架构——基于真实数据,典型峰值负载可达25,000名手动和自动化用户的水平。

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

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

  • 目标负载:API:500 RPS,Web:50 RPS,Git(拉取):50 RPS,Git(推送):10 RPS
  • 高可用性:是(Praefect 需要第三方PostgreSQL解决方案来实现HA)
  • 云原生混合替代方案
  • 不确定该使用哪个参考架构? 前往此指南获取更多信息
服务 节点数 配置 GCP 示例1 AWS 示例1 Azure 示例1
外部负载均衡器4 1 8 vCPU,7.2 GB 内存 n1-highcpu-8 c5n.2xlarge F8s v2
Consul2 3 2 vCPU,1.8 GB 内存 n1-highcpu-2 c5.large F2s v2
PostgreSQL2 3 16 vCPU,60 GB 内存 n1-standard-16 m5.4xlarge D16s v3
PgBouncer2 3 2 vCPU,1.8 GB 内存 n1-highcpu-2 c5.large F2s v2
内部负载均衡器4 1 8 vCPU,7.2 GB 内存 n1-highcpu-8 c5n.2xlarge F8s 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 32 vCPU,120 GB 内存 n1-standard-32 m5.8xlarge D32s 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 5 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)一起运行。

此外,规格大小取决于所选的负载均衡器以及其他因素(如网络带宽)。有关更多信息,请参阅 负载均衡器

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

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

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

  4. 可以放置在自动伸缩组(ASGs)中,因为该组件不存储任何 有状态数据。不过,通常更倾向于 云原生混合架构,因为某些组件(如 迁移Mailroom)只能在一个节点上运行,这在 Kubernetes 中处理得更好。

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

@startuml 25k
skinparam linetype ortho

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

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

要求

在开始之前,请参阅要求,了解参考架构。

测试方法

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

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

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

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

性能注意事项

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

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

负载均衡器配置

我们的测试环境使用:

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

设置组件

要将GitLab及其组件设置为支持最多500 RPS或25,000用户:

  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.151:Prometheus

配置外部负载均衡器

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

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

就绪检查

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

端口

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

| LB Port | Backend Port | Protocol |\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,则需要一些额外的端口配置。GitLab Pages需要一个单独的虚拟IP地址。配置DNS以将 /etc/gitlab/gitlab.rb 中的 pages_external_url 指向新的虚拟IP地址。有关更多信息,请参阅 GitLab Pages文档。\n\n| LB Port | Backend Port | Protocol |\n| ——- | ————- | ——— |\n| 80 | Varies (1) | HTTP |\n| 443 | Varies (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端口

有些组织有政策禁止开放SSH端口22。在这种情况下,配置一个备用SSH主机名可能会有所帮助,该主机名允许用户在443端口上使用SSH。与之前记录的其他GitLab HTTP配置相比,备用SSH主机名将需要一个新虚拟IP地址。\n\n为备用SSH主机名(如 altssh.gitlab.example.com)配置DNS。\n\n| LB Port | Backend Port | Protocol |\n| ——- | ———— | ——– |\n| 443 | 22 | TCP |\n\n### SSL

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

应用节点终止SSL

将您的负载均衡器配置为将443端口的连接作为 TCP 而不是 HTTP(S) 协议传递。这将把连接原样传递给应用节点的NGINX服务。NGINX将拥有SSL证书并在443端口监听。\n\n有关管理SSL证书和配置NGINX的详细信息,请参阅 HTTPS文档。\n\n#### 负载均衡器终止SSL而不进行后端SSL

将您的负载均衡器配置为使用 HTTP(S) 协议而不是 TCP。然后负载均衡器将负责管理SSL证书并终止SSL。\n\n由于负载均衡器和GitLab之间的通信不安全,需要进行一些额外的配置。有关详细信息,请参阅 代理SSL文档

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

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

在此场景中,负载均衡器与NGINX之间的流量也将是安全的。由于整个连接都是安全的,因此无需添加代理SSL的配置。但是,必须向GitLab添加配置以配置SSL证书。有关管理SSL证书和配置NGINX的详细信息,请参阅HTTPS文档

配置内部负载均衡器

内部负载均衡器用于平衡GitLab环境所需的任何内部连接,例如到PgBouncerGitaly Cluster (Praefect)的连接。

它是一个独立的节点,不同于外部负载均衡器,不应具有任何外部访问权限。

以下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),
    }
    
    # 设置exporters监听的网路地址
    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 leader。查看Consul日志 sudo gitlab-ctl tail consul 会显示 ...[INFO] consul: New leader elected: ...

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

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

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

sudo gitlab-ctl status

输出应类似于以下内容:

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

配置PostgreSQL

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

提供您自己的PostgreSQL实例

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

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

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

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

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

使用Linux包的独立PostgreSQL

推荐用于具有复制和高可用性的PostgreSQL集群的Linux包配置要求:

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

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

以下IP作为示例:

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

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

PostgreSQL 节点

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

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

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

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

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

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

    # 禁用除 Patroni、PgBouncer 和 Consul 外的所有组件
    roles(['patroni_role', 'pgbouncer_role'])
    
    # PostgreSQL 配置
    postgresql['listen_address'] = '0.0.0.0'
    
    # 将 `max_replication_slots` 设置为数据库节点数量的两倍。
    # 当 Patroni 初始化复制时,每个节点会额外使用一个槽位。
    patroni['postgresql']['max_replication_slots'] = 6
    
    # 将 `max_wal_senders` 设置为集群中复制槽数量加一。
    # 这用于防止复制占用所有可用的数据库连接。
    patroni['postgresql']['max_wal_senders'] = 7
    
    # 防止升级时自动运行数据库迁移
    gitlab_rails['auto_migrate'] = false
    
    # 配置 Consul 代理
    consul['services'] = %w(postgresql)
    ## 启用 Prometheus 的服务发现
    consul['monitoring_service_discovery'] =  true
    
    # START user configuration
    # 请按照“必需信息”部分的说明设置真实值
    #
    # 用生成的 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>'
       }
    }
    
    # 设置导出器监听的网络地址以供监控
    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> 替换为您之前设置的密码哈希(此处):

    # 禁用除 Pgbouncer 和 Consul agent 外的所有组件
    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 agent
    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
    
    # 设置 exporters 监听的网路地址
    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 Sentinel 服务来监控并自动启动故障转移流程。

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

Redis 主要为单线程,增加 CPU 核心数量并不能显著提升性能。对于这种规模的架构,强烈建议按照指定方式设置独立的缓存实例和持久化实例,以达到最佳性能。有关更多信息,请参阅缩放文档

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

Redis 设置的要求如下:

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

在本节中,您将逐步指导如何配置两个外部 Redis 集群以用于 GitLab。以下 IP 地址将用作示例:

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

提供自己的 Redis 实例

您可以可选地使用第三方外部服务来提供 Redis 缓存和持久化实例,具体指导如下:

  • 应使用信誉良好的提供商或解决方案。Google MemorystoreAWS ElastiCache 已知可以正常工作。
  • Redis 集群模式不被支持,但带有高可用性的 Redis 单机版是被支持的。
  • 您必须根据您的设置配置 Redis 逐出模式

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

配置 Redis 缓存集群

在本节中,我们将安装并设置新的 Redis 缓存实例。

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

配置主Redis缓存节点

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

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

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

    # 指定服务器角色为'redis_sentinel_role' 'redis_master_role'
    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.51'
    
    # 定义端口使Redis能够监听TCP请求,允许其他机器连接。
    redis['port'] = 6379
    
    # 主Redis服务器的Sentinel端口,取消注释可修改默认值。
    # 默认为`6379`。
    # redis['master_port'] = 6379
    
    # 为Redis设置密码认证(所有节点使用相同密码)。
    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.51:6379',
         'redis.password' => 'redis-password-goes-here',
    }
    
    # 防止升级时自动运行数据库迁移
    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_master_node 替换为 redis_replica_node

    # 指定服务器角色为'redis_sentinel_role'并启用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.52'
    
    # 定义端口以便Redis可以监听TCP请求,从而允许其他机器连接它。
    redis['port'] = 6379
    
    ## 主Redis服务器的端口(用于Sentinel),取消注释可修改为非默认值。默认值为`6379`。
    #redis['master_port'] = 6379
    
    # 为Redis及其副本设置密码认证(所有节点使用相同密码)。
    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
  4. 从您配置的第一个Linux软件包节点复制 /etc/gitlab/gitlab-secrets.json 文件,并将此服务器上同名文件添加或替换。如果这是您正在配置的第一个Linux软件包节点,则可以跳过此步骤。

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

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

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

配置Redis持久化集群

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

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

配置主Redis持久节点

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

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

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

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

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

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

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

配置 Gitaly 集群(Praefect)

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

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

Gitaly 集群(Praefect)虽提供容错能力,但也增加了设置和管理的复杂度。 在部署 Gitaly 集群(Praefect)前,请先查阅现有的技术限制与注意事项

关于以下内容的指引:

推荐的集群架构包含以下组件:

  • 3 个 Gitaly 节点:负责 Git 仓库的复制存储。
  • 3 个 Praefect 节点:作为 Gitaly 集群(Praefect)的路由器与事务管理器。
  • 1 个 Praefect PostgreSQL 节点:Praefect 的数据库服务器。为实现高可用,Praefect 数据库连接需借助第三方解决方案。
  • 1 个负载均衡器:Praefect 必须搭配负载均衡器使用,此处选用内部负载均衡器

本章节将按顺序详细介绍推荐标准设置的配置方法。如需进阶配置,可参考独立 Gitaly 集群(Praefect)文档

配置 Praefect PostgreSQL

Praefect(Gitaly 集群(Praefect)的路由器与事务管理器)需要专属数据库服务器来存储集群状态数据。

若追求高可用性,Praefect 需依赖第三方 PostgreSQL 数据库。 内置的高可用方案正处于开发阶段

Praefect 非高可用(non-HA)独立PostgreSQL(使用Linux包)

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

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

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

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

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

有许多PostgreSQL高可用的第三方解决方案。选定的方案必须满足以下条件才能与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 Cluster 的路由器和事务管理器,所有对 Gitaly 的连接都会经过它。本节详细说明如何配置它。

Praefect 必须部署在 3 个或更多奇数个节点上。这是为了确保节点能够作为仲裁集的一部分进行投票。

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) 节点在 Praefect 中通过 virtual storage 进行配置。每个存储包含构成集群的每个 Gitaly 节点的详细信息。每个存储还会被赋予一个名称,该名称在配置的多个地方使用。在本指南中,存储的名称将为 default。此外,本指南针对新安装场景,若要将现有环境升级以使用 Gitaly Cluster (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 用于监控的网络地址
    }
# 设置节点导出器将抓取的Prometheus URL
prometheus_listen_addr: '0.0.0.0:9652',
}

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

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

  2. Praefect 需要运行一些数据库迁移,就像主GitLab应用程序一样。为此,你应该只选择一个Praefect节点来运行迁移,即所谓的 部署节点。该节点必须先于其他节点进行如下配置:

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

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

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


### 配置 Gitaly

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

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

Gitaly 对 Gitaly 存储有特定的 [磁盘要求](../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 用于监控的监听地址 node_exporter['listen_address'] = '0.0.0.0:9100' gitaly['configuration'] = { # 使 Gitaly 接受所有网络接口的连接。您必须使用防火墙限制对此地址/端口的访问。 # 如果您只想支持 TLS 连接,请注释掉以下行 listen_addr: '0.0.0.0:8075', # 设置 Gitaly 用于监控的监听地址 prometheus_listen_addr: '0.0.0.0:9236', auth: { # Gitaly 认证令牌 # 应与 praefect_internal_token 相同 token: '<praefect_internal_token>', }, pack_objects_cache: { # Gitaly Pack-objects 缓存 # 建议启用以提高性能,但会显著增加磁盘 I/O # 参见 https://docs.gitlab.com/ee/administration/gitaly/configure_gitaly.html#pack-objects-cache 了解更多信息 enabled: true, }, } # # END 用户配置
  1. 向每个相应服务器的 /etc/gitlab/gitlab.rb 追加以下内容:
    • 在 Gitaly 节点 1 上:

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

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

在 Gitaly 节点 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 地址添加为主题备用名称(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
    roles(["sidekiq_role"])
    
    # 外部 URL
    ## 此处应与外部负载均衡器的 URL 一致
    external_url 'https://gitlab.example.com'
    
    # Redis
    ## Redis 连接详情
    ## 第一个集群(用于缓存数据)
    gitlab_rails['redis_cache_instance'] = 'redis://:<第一个集群的 REDIS_PRIMARY 密码>@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 密码>'
    
    gitlab_rails['redis_sentinels'] = [
      {host: '10.6.0.61', port: 26379},
      {host: '10.6.0.62', port: 26379},
      {host: '10.6.0.63', port: 26379},
    ]
    
    # Gitaly 集群
    ## gitlab_rails['repositories_storages'] 为 Praefect 虚拟存储配置
    ## 地址为 Praefect 内部负载均衡器
    ## Token 为 praefect_external_token
    gitlab_rails['repositories_storages'] = {
      "default" => {
        "gitaly_address" => "tcp://10.6.0.40:2305", # 内部负载均衡器 IP
        "gitaly_token" => '<praefect_external_token>'
      }
    }
    
    # PostgreSQL
    gitlab_rails['db_host'] = '10.6.0.20' # 内部负载均衡器 IP
    gitlab_rails['db_port'] = 6432
    gitlab_rails['db_password'] = '<postgresql 用户密码>'
    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' => '<gcp 服务账号密钥路径>'
    }
    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,使变更生效。
```

配置 GitLab Rails

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

Rails 需要连接到 RedisPostgreSQLGitaly 实例。同时建议它也需要连接到 对象存储

建议使用对象存储 而不是 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

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

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

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

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

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

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

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

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

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

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

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

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

  6. 启用增量日志

  7. 确认节点能连接Gitaly:

    sudo gitlab-rake gitlab:gitaly:check

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

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

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

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


### GitLab Rails 安装后配置

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

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

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

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

配置Prometheus

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

以下IP将用作示例:

  • 10.6.0.151:Prometheus

要配置监控节点:

  1. 通过SSH登录到监控节点。

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

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

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

配置对象存储

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

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

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

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

启用增量日志

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

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

配置高级搜索

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

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

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

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

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

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

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

这是一个高级设置。在 Kubernetes 中运行服务众所周知非常复杂。此设置仅建议您具备扎实的 Kubernetes 工作知识和经验时采用。本节其余部分假定您已满足这一条件。

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

### Cluster topology

集群拓扑结构

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

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

| Component Node Group | Target Node Pool Totals | GCP Example     | AWS Example  |
|----------------------|-------------------------|-----------------|--------------|
| Webservice           | 140 vCPU<br/>175 GB memory (request)<br/>245 GB memory (limit) | 5 x `n1-standard-32` | 5 x `c5.9xlarge` |
| Sidekiq              | 12.6 vCPU<br/>28 GB memory (request)<br/>56 GB memory (limit) | 4 x `n1-standard-4` | 4 x `m5.xlarge`  |
| Supporting services  | 8 vCPU<br/>30 GB memory | 2 x `n1-standard-4` | 2 x `m5.xlarge`   |

- 对于此设置,我们定期进行 [测试](_index.md#validation-and-test-results),并推荐使用 [Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine) 和 [Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks/)。其他 Kubernetes 服务也可能适用,但效果可能有所不同。
- 机器类型示例仅用于说明目的。这些类型用于 [验证和测试](_index.md#validation-and-test-results),但不作为规定性默认值。支持切换到符合所列要求的其它机器类型。有关更多信息,请参阅 [支持的机器类型](_index.md#supported-machine-types)。
- [Webservice](#webservice) 和 [Sidekiq](#sidekiq) 的目标节点池总数仅为 GitLab 组件提供。所选 Kubernetes 提供商的系统进程需要额外的资源。给出的示例已考虑了这一点。
- [Supporting](#supporting) 目标节点池总数通常是为了容纳支持 GitLab 部署的多种资源,以及根据您的需求可能希望进行的任何额外部署。与其他节点池类似,所选 Kubernetes 提供商的系统进程也需要资源。给出的示例已考虑了这一点。
- 在生产部署中,不需要将 Pod 分配给特定节点。但是,建议在每个池中使用分布在不同可用区的多个节点,以符合弹性云架构实践。
- 出于效率原因,鼓励启用自动扩展功能(如 Cluster Autoscaler),但通常建议为 Webservice 和 Sidekiq Pod 设定不低于 75% 的下限,以确保持续的性能。

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

| Service                                  | Nodes | Configuration          | GCP example<sup>1</sup> | AWS example<sup>1</sup> |
|------------------------------------------|-------|------------------------|------------------|--------------|
| Consul<sup>2</sup>                       | 3     | 2 vCPU, 1.8 GB memory  | `n1-highcpu-2`   | `c5.large`   |
| PostgreSQL<sup>2</sup>                   | 3     | 16 vCPU, 60 GB memory  | `n1-standard-16` | `m5.4xlarge` |
| PgBouncer<sup>2</sup>                    | 3     | 2 vCPU, 1.8 GB memory  | `n1-highcpu-2`   | `c5.large`   |
| Internal load balancer<sup>4</sup>       | 1     | 8 vCPU, 7.2 GB memory  | `n1-highcpu-8`   | `c5.2xlarge` |
| Redis/Sentinel - Cache<sup>3</sup>       | 3     | 4 vCPU, 15 GB memory   | `n1-standard-4`  | `m5.xlarge`  |
| Redis/Sentinel - Persistent<sup>3</sup>  | 3     | 4 vCPU, 15 GB memory   | `n1-standard-4`  | `m5.xlarge`  |
| Gitaly<sup>6</sup><sup>7</sup>           | 3     | 32 vCPU, 120 GB memory | `n1-standard-32` | `m5.8xlarge` |
| Praefect<sup>6</sup>                     | 3     | 4 vCPU, 3.6 GB memory  | `n1-highcpu-4`   | `c5.xlarge`   |
| Praefect PostgreSQL<sup>2</sup>          | 1+    | 2 vCPU, 1.8 GB memory  | `n1-highcpu-2`   | `c5.large`   |
| Object storage<sup>5</sup>               | -     | -                      | -                | -            |

**Footnotes**:

**脚注**
<!-- 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)。
  1. 可以选择在信誉良好的第三方外部PaaS Redis解决方案上运行。更多信息请参见提供您自己的Redis实例
    • Redis主要是单线程的,增加CPU核心并不能带来显著的性能提升。对于这种规模的架构,强烈建议按照指定要求设置独立的缓存和持久化实例,以达到最佳性能。
  2. 可以选择在信誉良好的第三方负载均衡服务(LB PaaS)上运行。更多信息请参见推荐的云提供商和服务
  3. 应在信誉良好的云提供商或自管理解决方案上运行。更多信息请参见配置对象存储
  4. Gitaly集群(Praefect)提供了容错的好处,但也带来了额外的设置和管理复杂性。查看现有的部署Gitaly集群(Praefect)前的技术限制和注意事项。如果您想要分片的Gitaly,使用前表中列出的相同规格给Gitaly
  5. Gitaly的规格基于健康状态下使用模式和仓库大小的高百分位数。但是,如果您有大型单体仓库(大于几吉字节)或额外的工作负载,这些会显著影响Git和Gitaly的性能,可能还需要进一步的调整。

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

@startuml 25k
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 内存(限制)

对于 500 RPS 或 25,000 用户,我们建议总共约 140 个 Puma Worker,因此建议至少运行 35 个 Webservice Pod。

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

NGINX

还建议将 NGINX 控制器 Pod 作为 DaemonSet 部署在 Webservice 节点上。这是为了让控制器能够随着它们服务的 Webservice Pod 动态扩展,并利用较大机器类型通常具有的更高网络带宽。

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

Sidekiq

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

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

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

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

Supporting

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

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

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

示例配置文件

针对 500 RPS 或 25,000 用户参考架构配置的 GitLab Helm Charts 示例 可以在 Charts 项目中找到

下一步

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

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

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