参考架构:支持最高60次请求每秒(RPS)或3000名用户
- 层级:Premium, Ultimate
- 提供方式:GitLab 自托管
本页介绍针对峰值负载60次请求每秒(RPS)(基于真实数据,通常对应最多3000名手动及自动化用户的峰值负载)设计的GitLab参考架构。
该架构是内置高可用性(HA)的最小可用架构。如果需要HA但用户数或总负载较低,低用户数的支持修改部分详细说明了如何在维持HA的同时缩小此架构规模。
有关完整的参考架构列表,请参阅可用参考架构。
- 目标负载:API:60 RPS,Web:6 RPS,Git(拉取):6 RPS,Git(推送):1 RPS
- 高可用性:是,尽管Praefect需要第三方PostgreSQL解决方案
- 云原生混合替代方案:是
- 不确定使用哪个参考架构? 前往此指南获取更多信息。
| 服务 | 节点数 | 配置 | GCP 示例1 | AWS 示例1 | Azure 示例1 |
|---|---|---|---|---|---|
| 外部负载均衡器4 | 1 | 4个vCPU,3.6GB内存 | n1-highcpu-4 |
c5n.xlarge |
F4s v2 |
| Consul2 | 3 | 2个vCPU,1.8GB内存 | n1-highcpu-2 |
c5.large |
F2s v2 |
| PostgreSQL2 | 3 | 2个vCPU,7.5GB内存 | n1-standard-2 |
m5.large |
D2s v3 |
| PgBouncer2 | 3 | 2个vCPU,1.8GB内存 | n1-highcpu-2 |
c5.large |
F2s v2 |
| 内部负载均衡器4 | 1 | 4个vCPU,3.6GB内存 | n1-highcpu-4 |
c5n.xlarge |
F4s v2 |
| Redis/Sentinel3 | 3 | 2个vCPU,7.5GB内存 | n1-standard-2 |
m5.large |
D2s v3 |
| Gitaly67 | 3 | 4个vCPU,15GB内存 | n1-standard-4 |
m5.xlarge |
D4s v3 |
| Praefect6 | 3 | 2个vCPU,1.8GB内存 | n1-highcpu-2 |
c5.large |
F2s v2 |
| Praefect PostgreSQL2 | 1+ | 2个vCPU,1.8GB内存 | n1-highcpu-2 |
c5.large |
F2s v2 |
| Sidekiq8 | 2 | 4个vCPU,15GB内存 | n1-standard-4 |
m5.xlarge |
D2s v3 |
| GitLab Rails8 | 3 | 8个vCPU,7.2GB内存 | n1-highcpu-8 |
c5.2xlarge |
F8s v2 |
| 监控节点 | 1 | 2个vCPU,1.8GB内存 | n1-highcpu-2 |
c5.large |
F2s v2 |
| 对象存储5 | - | - | - | - | - |
脚注:
- 机器类型示例仅为说明用途。这些类型用于验证和测试结果,但并非规定性的默认值。支持切换到符合要求的其他机器类型,包括可用的ARM变体。更多信息请参见支持的机器类型。
- 可选择在信誉良好的第三方外部PaaS PostgreSQL解决方案上运行。更多信息请参见提供您自己的PostgreSQL实例。
- 可选择在信誉良好的第三方外部PaaS Redis解决方案上运行。更多信息请参见提供您自己的Redis实例。
- 建议与能提供HA能力的信誉良好的第三方负载均衡器或服务(LB PaaS)一起运行。规格取决于所选负载均衡器及其他因素(如网络带宽)。更多信息请参见负载均衡器。
- 应在信誉良好的云服务商或自托管解决方案上运行。更多信息请参见配置对象存储。
- Gitaly 集群(Praefect)提供了容错的好处,但也带来了额外的设置和管理复杂性。
请查看现有的部署 Gitaly 集群(Praefect)前的技术限制和注意事项。如果需要分片的 Gitaly,请使用前表中列出的相同规格给 Gitaly。
- Gitaly 的规格基于健康状态下使用模式和仓库大小的高百分位数。不过,如果您有大型单体仓库(大于几 GB)或额外工作负载,这些会显著影响 Git 和 Gitaly 的性能,可能还需要进一步调整。
- 由于该组件不存储任何stateful 数据,可以放置在自动伸缩组(ASGs)中。不过,通常更推荐云原生混合架构,因为像migrations和Mailroom这样的某些组件只能在一个节点上运行,而 Kubernetes 能更好地处理这种情况。
对于所有涉及配置实例的 PaaS 解决方案,建议至少在三台不同的可用区中实现三个节点,以符合弹性云架构实践。
@startuml 3k
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
要求
在继续之前,请查看参考架构的要求。
测试方法
60 RPS / 3000用户的参考架构旨在适应大多数常见工作流程。GitLab定期针对以下端点吞吐量目标进行冒烟测试和性能测试:
| 端点类型 | 目标吞吐量 |
|---|---|
| API | 60 RPS |
| Web | 6 RPS |
| Git (拉取) | 6 RPS |
| Git (推送) | 1 RPS |
这些目标基于实际客户数据,反映了指定用户数量的总环境负载,包括CI管道和其他工作负载。
有关我们测试方法的更多信息,请参阅验证和测试结果部分。
性能注意事项
如果您的环境存在以下情况,您可能需要进行额外调整:
在这些情况下,请参阅扩展环境以获取更多信息。如果您认为这些注意事项适用于您,请联系我们以获得所需的额外指导。
负载均衡器配置
我们的测试环境使用:
- Linux包环境的HAProxy
- 云原生混合部署的NGINX Ingress云提供商替代方案
设置组件
要将GitLab及其组件设置为支持最多60 RPS或3000用户:
- 配置外部负载均衡器,用于处理GitLab应用服务节点的负载均衡。
- 配置内部负载均衡器,用于处理GitLab应用内部连接的负载均衡。
- 配置Consul,用于服务发现和健康检查。
- 配置PostgreSQL,作为GitLab的数据库。
- 配置PgBouncer,用于数据库连接池和管理。
- 配置Redis,存储会话数据、临时缓存信息和后台任务队列。
- 配置Gitaly集群(Praefect),提供对Git仓库的访问。
- 配置Sidekiq,用于后台任务处理。
- 配置主GitLab Rails应用,运行Puma、Workhorse、GitLab Shell,并处理所有前端请求(包括UI、API以及HTTP/SSH上的Git请求)。
- 配置Prometheus,监控您的GitLab环境。
- 配置对象存储,用于共享数据对象。
- 配置高级搜索(可选),实现更快、更先进的跨实例代码搜索。
服务器启动于相同的10.6.0.0/24私有网络范围,并且可以自由地通过这些地址相互连接。
以下是各服务器及其分配IP的说明列表:
10.6.0.10:外部负载均衡器10.6.0.11:Consul/Sentinel 110.6.0.12:Consul/Sentinel 210.6.0.13:Consul/Sentinel 310.6.0.21:PostgreSQL主节点10.6.0.22:PostgreSQL从节点110.6.0.23:PostgreSQL从节点210.6.0.31:PgBouncer 110.6.0.32:PgBouncer 210.6.0.33:PgBouncer 310.6.0.20:内部负载均衡器10.6.0.61:Redis主节点10.6.0.62:Redis副本110.6.0.63:Redis副本210.6.0.51:Gitaly 110.6.0.52:Gitaly 210.6.0.93:Gitaly 310.6.0.131:Praefect 110.6.0.132:Praefect 210.6.0.133:Praefect 310.6.0.141:Praefect PostgreSQL 1(非高可用)10.6.0.71:Sidekiq 110.6.0.72:Sidekiq 210.6.0.41:GitLab应用110.6.0.42:GitLab应用210.6.0.43:GitLab应用310.6.0.81:Prometheus
配置外部负载均衡器
在多节点GitLab配置中,您需要一个外部负载均衡器将流量路由到应用服务器。
选择哪种负载均衡器或其确切配置的具体细节超出了GitLab文档的范围,但请参阅负载均衡器以了解一般要求的更多信息。本节将重点介绍为您选择的负载均衡器配置的具体内容。
就绪检查
确保外部负载均衡器仅将流量路由到具有内置监控端点的正常服务。就绪检查都需要在被检查节点上进行额外配置,否则外部负载均衡器将无法连接。
端口
以下表格显示了需要使用的基本端口。
| 负载均衡器端口 | 后端端口 | 协议 |
|---|---|---|
| 80 | 80 | HTTP (1) |
| 443 | 443 | TCP 或 HTTPS (1) (2) |
| 22 | 22 | TCP |
- (1): Web终端 支持要求您的负载均衡器正确处理WebSocket连接。当使用HTTP或HTTPS代理时,这意味着您的负载均衡器必须配置为传递
Connection和Upgrade逐跳头信息。有关更多详情,请参阅 web终端集成指南。 - (2): 当使用HTTPS协议用于端口443时,您必须在负载均衡器上添加SSL证书。如果您希望在GitLab应用服务器上终止SSL,请使用TCP协议。
如果您使用带有自定义域支持的GitLab Pages,则需要一些额外的端口配置。
GitLab Pages需要单独的虚拟IP地址。配置DNS以将 /etc/gitlab/gitlab.rb 中的 pages_external_url 指向新的虚拟IP地址。有关更多信息,请参阅 GitLab Pages文档。
| 负载均衡器端口 | 后端端口 | 协议 |
|---|---|---|
| 80 | 可变 (1) | HTTP |
| 443 | 可变 (1) | TCP (2) |
- (1): GitLab Pages的后端端口取决于
gitlab_pages['external_http']和gitlab_pages['external_https']设置。有关更多详情,请参阅 GitLab Pages文档。 - (2): GitLab Pages的端口443应始终使用TCP协议。用户可以配置带有自定义SSL的自定义域名,如果SSL在负载均衡器处终止,这是不可能实现的。
备用SSH端口
某些组织有政策禁止开放SSH端口22。在这种情况下,配置备用SSH主机名可能有助于允许用户使用端口443进行SSH操作。与之前记录的其他GitLab HTTP配置相比,备用SSH主机名将需要一个新虚拟IP地址。
为备用SSH主机名(例如 altssh.gitlab.example.com)配置DNS。
| 负载均衡器端口 | 后端端口 | 协议 |
|---|---|---|
| 443 | 22 | TCP |
SSL
下一个问题是您将如何在环境中处理SSL。有以下几种不同选项:
- 应用节点终止SSL。
- 负载均衡器终止SSL且无后端SSL,负载均衡器与应用节点之间的通信不安全。
- 负载均衡器终止SSL且有后端SSL,负载均衡器与应用节点之间的通信安全。
应用节点终止SSL
将您的负载均衡器配置为将443端口的连接作为 TCP 而不是 HTTP(S) 协议传递。这将把连接原封不动地传递给应用节点的NGINX服务。NGINX将拥有SSL证书并监听443端口。
有关管理SSL证书和配置NGINX的详细信息,请参阅 HTTPS文档。
负载均衡器终止SSL且无后端SSL
将您的负载均衡器配置为使用 HTTP(S) 协议而不是 TCP。负载均衡器将负责管理SSL证书并终止SSL。
由于负载均衡器和GitLab之间的通信不安全,需要进行一些额外的配置。有关详细信息,请参阅 代理SSL文档。
负载均衡器终止SSL且有后端SSL
将您的负载均衡器配置为使用 HTTP(S) 协议而不是 TCP。负载均衡器将负责管理终端用户可见的SSL证书。
在这种场景下,负载均衡器和NGINX之间的流量也将是安全的。由于整个连接都是安全的,因此不需要添加代理SSL的配置。但是,必须在GitLab中添加配置以配置SSL证书。有关管理SSL证书和配置NGINX的详细信息,请参阅 HTTPS文档。
配置内部负载均衡器
在多节点的 GitLab 配置中,若需配置某些内部组件(例如连接到 PgBouncer 和 Gitaly Cluster (Praefect)),则需要一个内部负载均衡器来路由这些流量的访问。
关于使用何种负载均衡器及其具体配置细节,已超出 GitLab 文档的范围,但可参考 Load Balancers 了解通用需求。本节将重点介绍如何为您选择的负载均衡器进行配置。
以下 IP 将作为示例:
10.6.0.40:内部负载均衡器
以下是使用 HAProxy 的配置方法:
global
log /dev/log local0
log localhost local1 notice
log stdout format raw local0
defaults
log global
default-server inter 10s fall 3 rise 2
balance leastconn
frontend internal-pgbouncer-tcp-in
bind *:6432
mode tcp
option tcplog
default_backend pgbouncer
frontend internal-praefect-tcp-in
bind *:2305
mode tcp
option tcplog
option clitcpka
default_backend praefect
backend pgbouncer
mode tcp
option tcp-check
server pgbouncer1 10.6.0.31:6432 check
server pgbouncer2 10.6.0.32:6432 check
server pgbouncer3 10.6.0.33:6432 check
backend praefect
mode tcp
option tcp-check
option srvtcpka
server praefect1 10.6.0.131:2305 check
server praefect2 10.6.0.132:2305 check
server praefect3 10.6.0.133:2305 check请参阅您首选的负载均衡器文档以获取进一步指导。
配置 Consul
接下来,我们设置 Consul 服务器。
Consul 必须部署在 3 个或以上奇数个节点上。这是为了确保节点能够参与投票并形成仲裁组(quorum)。
以下 IP 将作为示例:
10.6.0.11:Consul 110.6.0.12:Consul 210.6.0.13:Consul 3
要配置 Consul:
-
通过 SSH 登录到将要托管 Consul 的服务器。
-
下载并安装 您选择的 Linux 软件包。请确保仅添加 GitLab 软件包仓库,并为您的操作系统安装 GitLab。选择与当前安装相同的版本和类型(社区版或企业版)。
-
编辑
/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 -
从您配置的第一个 Linux 软件包节点复制
/etc/gitlab/gitlab-secrets.json文件,并将该文件添加或替换到此服务器上的同名文件中。如果您正在配置的是第一个 Linux 软件包节点,则可以跳过此步骤。 -
重新配置 GitLab,使更改生效。
-
对所有其他 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 SQL 和 Amazon RDS 已知可以正常工作。然而,Amazon Aurora 与默认启用的负载均衡在 14.4.0 版本中不兼容。
有关更多信息,请参阅 推荐云提供商和服务。
如果您使用第三方外部服务:
- HA Linux 包的 PostgreSQL 设置包含 PostgreSQL、PgBouncer 和 Consul。当使用第三方外部服务时,所有这些组件将不再需要。
- 根据 数据库要求文档 配置 PostgreSQL。
- 创建一个名为
gitlab的用户,并设置您选择的密码。gitlab用户需要有权限创建gitlabhq_production数据库。 - 使用适当的信息配置 GitLab 应用服务器。此步骤在 配置 GitLab Rails 应用程序 中介绍。
- 实现高可用性所需的节点数量可能因服务而异,也可能与 Linux 包不同。
- 但是,如果希望通过读取副本进行 数据库负载均衡 以进一步提高性能,建议遵循参考架构中的节点计数。
使用 Linux 包的独立 PostgreSQL
具有复制和高可用性的 PostgreSQL 集群的推荐 Linux 包配置要求:
- 至少三个 PostgreSQL 节点。
- 至少三个 Consul 服务器节点。
- 至少三个 PgBouncer 节点来跟踪和处理主数据库的读写操作。
- 一个 内部负载均衡器(TCP)用于在 PgBouncer 节点之间平衡请求。
- 启用 数据库负载均衡。
每个 PostgreSQL 节点上需配置本地 PgBouncer 服务。这与跟踪主节点的核心 PgBouncer 集群分开。
以下 IP 用作示例:
10.6.0.21:PostgreSQL 主节点10.6.0.22:PostgreSQL 从节点 110.6.0.23:PostgreSQL 从节点 2
首先,确保在每个节点上 安装 Linux GitLab 包。务必仅添加 GitLab 包仓库并为所选操作系统安装 GitLab,但不要提供 EXTERNAL_URL 值。
PostgreSQL 节点
-
通过 SSH 登录到一个 PostgreSQL 节点。
-
为 PostgreSQL 的用户名/密码对生成密码哈希。假设你使用默认用户名
gitlab(推荐)。该命令会请求密码并要求确认。使用此命令输出的值作为下一步中<postgresql_password_hash>的值:sudo gitlab-ctl pg-password-md5 gitlab -
为 PgBouncer 的用户名/密码对生成密码哈希。假设你使用默认用户名
pgbouncer(推荐)。该命令会请求密码并要求确认。使用此命令输出的值作为下一步中<pgbouncer_password_hash>的值:sudo gitlab-ctl pg-password-md5 pgbouncer -
为 PostgreSQL 复制的用户名/密码对生成密码哈希。假设你使用默认用户名
gitlab_replicator(推荐)。该命令会请求密码并要求确认。使用此命令输出的值作为下一步中<postgresql_replication_password_hash>的值:sudo gitlab-ctl pg-password-md5 gitlab_replicator -
为 Consul 数据库的用户名/密码对生成密码哈希。假设你使用默认用户名
gitlab-consul(推荐)。该命令会请求密码并要求确认。使用此命令输出的值作为下一步中<consul_password_hash>的值:sudo gitlab-ctl pg-password-md5 gitlab-consul -
在每个数据库节点上,编辑
/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>' } } # 设置导出器监听的网路地址,用于监控 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 用户配置
PostgreSQL 由 Patroni 管理其故障转移时,默认使用 pg_rewind 来处理冲突。与其他故障转移处理方式类似,这有极小的可能导致数据丢失。更多信息,请参阅各种 Patroni 复制方法。
-
从你配置的第一个 Linux 包节点复制
/etc/gitlab/gitlab-secrets.json文件,并将同名文件添加或替换到此服务器上。如果这是你要配置的第一个 Linux 包节点,则可以跳过此步骤。 -
重新配置 GitLab,使更改生效。
高级配置选项
是支持的,如果需要的话可以添加。
PostgreSQL 配置后操作
SSH 进入主站点的任意 Patroni 节点:
-
检查领导者和集群的状态:
gitlab-ctl patroni members输出应类似于以下内容:
| 集群 | 成员 | 主机 | 角色 | 状态 | TL | 延迟(MB) | 待重启 | |--------------|-----------------------------------|-----------|--------|---------|-----|------------|--------------| | postgresql-ha | <PostgreSQL 主要主机名> | 10.6.0.21 | 领导者 | 运行中 | 175 | | * | | postgresql-ha | <PostgreSQL 次要 1 主机名> | 10.6.0.22 | | 运行中 | 175 | 0 | * | | postgresql-ha | <PostgreSQL 次要 2 主机名> | 10.6.0.23 | | 运行中 | 175 | 0 | * |
如果任何节点的“状态”列未显示“运行中”,请在继续前查看 PostgreSQL 复制和故障转移故障排除部分。
配置 PgBouncer
既然 PostgreSQL 服务器都已设置好,我们来配置 PgBouncer 以跟踪和处理对主数据库的读写操作。
PgBouncer 是单线程的,增加 CPU 核心并不能显著提升其性能。有关更多信息,请参阅扩展文档。
以下 IP 地址作为示例:
10.6.0.31:PgBouncer 110.6.0.32:PgBouncer 210.6.0.33:PgBouncer 3
-
在每个 PgBouncer 节点上,编辑
/etc/gitlab/gitlab.rb,并将<consul_password_hash>和<pgbouncer_password_hash>替换为你之前设置的密码哈希(参考 [#postgresql-nodes]):# 禁用所有组件,仅启用 Pgbouncer 和 Consul 代理 roles(['pgbouncer_role']) # 配置 PgBouncer pgbouncer['admin_users'] = %w(pgbouncer gitlab-consul) pgbouncer['users'] = { 'gitlab-consul': { password: '<consul_password_hash>' }, 'pgbouncer': { password: '<pgbouncer_password_hash>' } } # 配置 Consul 代理 consul['watchers'] = %w(postgresql) consul['configuration'] = { retry_join: %w(10.6.0.11 10.6.0.12 10.6.0.13) } # 为 Prometheus 启用服务发现 consul['monitoring_service_discovery'] = true # 设置导出器监听的网路地址 node_exporter['listen_address'] = '0.0.0.0:9100' pgbouncer_exporter['listen_address'] = '0.0.0.0:9188' -
从你配置的第一个 Linux 包节点复制
/etc/gitlab/gitlab-secrets.json文件,并在此服务器上添加或替换同名文件。如果这是你要配置的第一个 Linux 包节点,则可以跳过此步骤。 -
重新配置 GitLab,使更改生效。
-
创建一个
.pgpass文件,以便 Consul 能够重新加载 PgBouncer。当被提示时输入 PgBouncer 密码两次:gitlab-ctl write-pgpass --host 127.0.0.1 --database pgbouncer --user pgbouncer --hostuser gitlab-consul -
确保每个节点都与当前的主节点通信:
gitlab-ctl pgb-console # 你将被提示输入 PGBOUNCER_PASSWORD如果有错误
psql: ERROR: Auth failed,请确保你之前使用正确的格式生成了 MD5 密码哈希。正确的格式是将密码与用户名拼接:PASSWORDUSERNAME。例如,Sup3rS3cr3tpgbouncer就是生成pgbouncer用户 MD5 密码哈希所需的文本。 -
一旦控制台提示符可用,运行以下查询:
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) -
验证 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 能够作为仲裁的一部分进行投票。当通过外部方式配置 Redis 时(例如云服务商的服务),此规则不适用。
Redis 主要是单线程的,增加 CPU 核心并不会带来显著的性能提升。更多信息请参阅 缩放环境文档。
如果 Redis 与 Sentinel 一起使用,则需要认证。更多信息请参阅 Redis 安全文档。我们建议结合 Redis 密码和严格的防火墙规则来保护您的 Redis 服务。
强烈建议在配置 GitLab 的 Redis 之前阅读 Redis Sentinel 文档,以全面了解其拓扑结构和架构。
Redis 设置需满足以下要求:
- 所有 Redis 节点必须能够相互通信,并接受 Redis(
6379)和 Sentinel(26379)端口的入站连接(除非您更改了默认端口)。 - 托管 GitLab 应用程序的服务器必须能够访问 Redis 节点。
- 使用防火墙等措施保护节点免受外部网络(互联网)的访问。
在本节中,我们将引导您完成两个外部 Redis 集群的配置,用于与 GitLab 协同工作。以下 IP 地址将用作示例:
10.6.0.61:Redis 主节点10.6.0.62:Redis 副本 110.6.0.63:Redis 副本 2
提供自己的 Redis 实例
您可以可选地使用 第三方外部服务作为 Redis 实例,遵循以下指引:
- 应使用信誉良好的提供商或解决方案。Google Memorystore 和 AWS ElastiCache 已知可用。
- 不支持 Redis Cluster 模式,但支持带有高可用性(HA)的 Redis Standalone。
- 您必须根据您的设置配置 Redis 逐出模式。
更多信息,请参阅 推荐的云服务商和服务。
配置 Redis 集群
本节将介绍如何安装和设置新的 Redis 实例。
主节点和副本 Redis 节点都需要在 redis['password'] 中定义相同的密码。在任何故障转移期间,Sentinel 都可以重新配置一个节点,将其状态从主节点变为副本节点(反之亦然)。
配置主Redis节点
-
通过SSH登录到主Redis服务器。
-
下载并安装 你选择的Linux包。请确保仅添加GitLab包仓库并为所选操作系统安装GitLab。选择与你当前安装相同的版本和类型(社区版或企业版)。
-
编辑
/etc/gitlab/gitlab.rb并添加以下内容:# 指定服务器角色为包含Sentinel和Consul代理的'redis_master_role' roles ['redis_sentinel_role', 'redis_master_role', 'consul_role'] # 设置Redis Sentinel服务的IP绑定地址和法定人数 sentinel['bind'] = '0.0.0.0' sentinel['quorum'] = 2 # 指向本地可被其他机器访问的IP地址。你也可以将bind设置为'0.0.0.0'以监听所有接口。 # 如果必须绑定到外部可访问的IP,请务必添加额外的防火墙规则以防止未授权访问。 redis['bind'] = '10.6.0.61' # 定义Redis监听的TCP端口,以便其他机器能够连接它。 redis['port'] = 6379 ## 主Redis服务器(用于Sentinel)的端口,取消注释可修改默认值。默认为`6379`。 #redis['master_port'] = 6379 # 为Redis及其副本设置密码认证(所有节点使用相同密码)。 redis['password'] = 'REDIS_PRIMARY_PASSWORD' 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), } # 设置导出器监听的地址 node_exporter['listen_address'] = '0.0.0.0:9100' redis_exporter['listen_address'] = '0.0.0.0:9121' # 防止在升级时自动运行数据库迁移 gitlab_rails['auto_migrate'] = false -
从你配置的第一个Linux包节点复制
/etc/gitlab/gitlab-secrets.json文件,并将同名文件添加或替换到此服务器上。如果这是你要配置的第一个Linux包节点,则可以跳过此步骤。 -
重新配置GitLab 以使更改生效。
配置副本Redis节点
-
通过SSH登录到副本Redis服务器。
-
下载并安装您选择的Linux软件包。请确保仅添加GitLab软件包仓库,并为所选操作系统安装GitLab。选择与当前安装相同的版本和类型(社区版或企业版)。
-
编辑
/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), } # 设置导出器监听的网路地址 node_exporter['listen_address'] = '0.0.0.0:9100' redis_exporter['listen_address'] = '0.0.0.0:9121' # 防止在升级时自动运行数据库迁移 gitlab_rails['auto_migrate'] = false -
从您配置的第一个Linux软件包节点复制
/etc/gitlab/gitlab-secrets.json文件,并在本服务器上添加或替换同名文件。如果这是您正在配置的第一个Linux软件包节点,则可以跳过此步骤。 -
重新配置GitLab以使更改生效。
-
对所有其他副本节点重复上述步骤,并确保正确设置IP地址。
高级配置选项受支持,如有需要可以添加。
配置 Gitaly 集群(Praefect)
Gitaly 集群(Praefect) 是 GitLab 提供并推荐的用于存储 Git 仓库的高可用解决方案。在此配置中,每个 Git 仓库都会存储在集群中的每个 Gitaly 节点上,其中一个被指定为主节点,若主节点宕机,故障转移会自动发生。
Gitaly 集群(Praefect)提供了高可用的好处,但也带来了额外的设置和管理复杂性。 在部署 Gitaly 集群(Praefect)之前,请先查看现有的 技术限制和注意事项。
有关以下方面的指导:
- 若要实现分片的 Gitaly,请遵循 单独的 Gitaly 文档 而不是本节。使用相同的 Gitaly 规格。
- 迁移现有非 Gitaly 集群(Praefect)管理的仓库,请参阅 迁移到 Gitaly 集群(Praefect)。
推荐的集群设置包括以下组件:
- 3 个 Gitaly 节点:Git 仓库的复制存储。
- 3 个 Praefect 节点:Gitaly 集群(Praefect)的路由器和事务管理器。
- 1 个 Praefect PostgreSQL 节点:Praefect 的数据库服务器。Praefect 数据库连接需高度可用,因此需要第三方解决方案。
- 1 个负载均衡器:Praefect 需要负载均衡器。内部负载均衡器 用于此目的。
本节详细说明如何按顺序配置推荐的标准设置。 如需更高级的设置,请参考 独立 Gitaly 集群(Praefect)文档。
配置 Praefect PostgreSQL
Praefect 是 Gitaly 集群(Praefect)的路由器和事务管理器,需要自己的数据库服务器来存储 Gitaly 集群(Praefect)的状态数据。
如果您希望拥有高可用性设置,Praefect 需要一个第三方 PostgreSQL 数据库。 内置解决方案正在 开发中。
使用Linux包的Praefect非高可用PostgreSQL独立部署
以下IP地址将用作示例:
10.6.0.141:Praefect PostgreSQL
首先,确保在Praefect PostgreSQL节点上安装 Linux包。请仅添加GitLab软件包仓库并安装对应操作系统的GitLab,但不要提供EXTERNAL_URL值。
-
通过SSH连接到Praefect PostgreSQL节点。
-
为Praefect PostgreSQL用户创建一个强密码。将该密码记作
<praefect_postgresql_password>。 -
为Praefect PostgreSQL的用户名/密码对生成密码哈希。此处假设你将使用默认用户名
praefect(推荐)。该命令会请求输入密码<praefect_postgresql_password>并进行确认。使用此命令输出的值作为下一步中<praefect_postgresql_password_hash>的值:sudo gitlab-ctl pg-password-md5 praefect -
编辑
/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 用户配置 -
从你配置的第一个Linux包节点复制
/etc/gitlab/gitlab-secrets.json文件,并在本服务器上添加或替换同名文件。如果这是你要配置的第一个Linux包节点,则可以跳过此步骤。 -
重新配置GitLab以使更改生效。
Praefect高可用PostgreSQL第三方解决方案
如前所述,若追求完整的高可用性,建议为Praefect数据库采用第三方PostgreSQL解决方案。
有许多PostgreSQL高可用的第三方方案。所选方案必须满足以下条件才能与Praefect配合工作:
- 所有连接需使用静态IP,故障转移时不改变。
- 必须支持
LISTENSQL功能。
在使用第三方设置时,可将Praefect数据库与主GItLab数据库放置在同一服务器上。但是,若使用Geo功能,则需要独立的数据库实例来正确处理复制。在此设置中,主数据库的规格无需变更,因其影响应最小。
应选择信誉良好的提供商或解决方案。Google Cloud SQL 和 Amazon RDS 已知可正常工作。然而,Amazon Aurora 在14.4.0版本后默认启用的负载均衡不兼容。
更多信息请参见推荐云服务商和服务。
数据库设置完成后,执行Praefect PostgreSQL后续配置。
Praefect PostgreSQL 后续配置
在设置好 Praefect PostgreSQL 服务器后,你必须配置供 Praefect 使用的用户和数据库。
我们建议将用户命名为 praefect,数据库名为 praefect_production,这些可以在 PostgreSQL 中按标准方式配置。该用户的密码与你之前配置的 <praefect_postgresql_password> 相同。
以下是 Linux 包安装的 PostgreSQL 环境下的操作流程:
-
通过 SSH 连接到 Praefect PostgreSQL 节点。
-
以管理员权限连接 PostgreSQL 服务器。此处应使用
gitlab-psql用户,因为这是 Linux 包默认添加的用户。使用template1数据库,因为它是所有 PostgreSQL 服务器默认创建的数据库。/opt/gitlab/embedded/bin/psql -U gitlab-psql -d template1 -h POSTGRESQL_SERVER_ADDRESS -
创建新用户
praefect,替换<praefect_postgresql_password>:CREATE ROLE praefect WITH LOGIN CREATEDB PASSWORD '<praefect_postgresql_password>'; -
重新连接 PostgreSQL 服务器,此次以
praefect用户身份连接:/opt/gitlab/embedded/bin/psql -U praefect -d template1 -h POSTGRESQL_SERVER_ADDRESS -
创建新数据库
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)的节点通过 virtual storage 在 Praefect 中配置。每个存储包含组成集群的每个 Gitaly 节点的详细信息。每个存储也被赋予一个名称,该名称在配置的多个区域中使用。在本指南中,存储的名称将是 default。此外,本指南针对新安装,如果升级现有环境以使用 Gitaly 集群(Praefect),可能需要使用不同的名称。有关更多信息,请参阅 Gitaly 集群(Praefect)文档。
以下 IP 将用作示例:
10.6.0.131:Praefect 110.6.0.132:Praefect 210.6.0.133:Praefect 3
要配置 Praefect 节点,在每个节点上执行以下操作:
- 通过 SSH 登录到 Praefect 服务器。
- 下载并安装 您选择的 Linux 包。确保仅添加 GitLab 包仓库并为所选操作系统安装 GitLab。
编辑 /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
# 开始用户配置
# 请根据“所需信息”部分说明设置真实值
#
praefect['configuration'] = {
# ...
listen_addr: '0.0.0.0:2305',
auth: {
# ...
#
# Praefect 外部令牌
# 这是集群外客户端(如 GitLab Shell)与 Praefect 集群通信所需的
token: '<praefect_external_token>',
},
# Praefect 数据库设置
database: {
# ...
host: '10.6.0.141',
port: 5432,
dbname: 'praefect_production',
user: 'praefect',
password: '<praefect_postgresql_password>',
},
# Praefect 虚拟存储配置
# 存储哈希的名称必须与 GitLab 服务器上 `gitlab_rails['repositories_storages']` 的存储名称('praefect')
# 以及 Gitaly 节点上 `gitaly['configuration'][:storage]` 的存储名称('gitaly-1')匹配
virtual_storage: [
{
# ...
name: 'default',
node: [
{
storage: 'gitaly-1',
address: 'tcp://10.6.0.91:8075',
token: '<praefect_internal_token>'
},
{
storage: 'gitaly-2',
address: 'tcp://10.6.0.92:8075',
token: '<praefect_internal_token>'
},
{
storage: 'gitaly-3',
address: 'tcp://10.6.0.93:8075',
token: '<praefect_internal_token>'
},
],
},
],
# 设置 Praefect 用于监控监听的网路地址prometheus_listen_addr: '0.0.0.0:9652',
}
# 设置节点导出器(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),
}
#
# END user configuration-
复制第一个你配置的Linux包安装节点的
/etc/gitlab/gitlab-secrets.json文件,并将此服务器上同名的文件添加或替换。如果这是你要配置的第一个Linux包安装节点,则可以跳过此步骤。 -
Praefect 需要运行一些数据库迁移,类似于主 GitLab 应用程序。为此,你应该选择仅在一个 Praefect 节点上运行迁移,即所谓的_部署节点(Deploy Node)_。该节点必须先于其他节点进行如下配置:
-
在
/etc/gitlab/gitlab.rb文件中,将praefect['auto_migrate']设置值从false更改为true -
为确保数据库迁移仅在重新配置时运行,而非在升级时自动运行,执行以下命令:
sudo touch /etc/gitlab/skip-auto-reconfigure- 重新配置 GitLab,使更改生效并运行 Praefect 数据库迁移。
-
-
在所有其他 Praefect 节点上,重新配置 GitLab,使更改生效。
配置 Gitaly
组成集群的 Gitaly 服务器节点有依赖于数据和负载的要求。
Gitaly 存储有特定的 磁盘要求。
Gitaly 服务器不应暴露在公共互联网上,因为默认情况下 Gitaly 的网络流量未加密。强烈建议使用防火墙限制对 Gitaly 服务器的访问。另一个选项是 使用 TLS。
配置 Gitaly 时,请注意以下几点:
- 应配置
gitaly['configuration'][:storage]以反映特定 Gitaly 节点的存储路径 auth_token应与praefect_internal_token相同
以下 IP 将用作示例:
10.6.0.91:Gitaly 110.6.0.92:Gitaly 210.6.0.93:Gitaly 3
在每个节点上:
-
下载并安装 您选择的 Linux 包。请确保仅添加 GitLab 包仓库并为所选操作系统安装 GitLab,但不要提供
EXTERNAL_URL值。 -
编辑 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 # Gitaly gitaly['enable'] = true # 配置 gitlab-shell API 回调 URL。若无此配置,`git push` 会失败。可以是您的“前端” GitLab URL 或内部负载均衡器。 gitlab_rails['internal_api_url'] = 'https://gitlab.example.com' # 配置 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', # Gitaly 认证令牌 # 应与 praefect_internal_token 一致 auth: { # ... token: '<praefect_internal_token>', }, # Gitaly Pack-objects 缓存 # 启用可提升性能,但会显著增加磁盘 I/O # 参见 https://docs.gitlab.com/ee/administration/gitaly/configure_gitaly.html#pack-objects-cache 了解更多信息 pack_objects_cache: { # ... enabled: true, }, } # # END 用户配置 -
向每台服务器的
/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',
-
在 Gitaly 节点 1 上:
gitaly['configuration'] = {
# ...
storage: [
{
name: 'gitaly-1',
path: '/var/opt/gitlab/git-data',
},
{
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',
},
]
}-
从你配置的第一个 Linux 包节点复制
/etc/gitlab/gitlab-secrets.json文件,并将此服务器上同名的文件添加或替换。如果这是你要配置的第一个 Linux 包节点,则可以跳过此步骤。 -
保存文件,然后重新配置 GitLab。
Gitaly 集群(Praefect)的 TLS 支持
Praefect 支持 TLS 加密。要与监听安全连接的 Praefect 实例通信,您必须:
- 在 GitLab 配置中对应存储条目的
gitaly_address中使用tls://URL 方案。 - 自行提供证书,因为系统不会自动提供。每个 Praefect 服务器对应的证书必须安装在该 Praefect 服务器上。
此外,所有与该 Praefect 通信的 Gitaly 服务器和 Praefect 客户端都必须按照 GitLab 自定义证书配置 中描述的步骤(下文重复),安装证书或其证书颁发机构。
请注意以下几点:
- 证书必须指定用于访问 Praefect 服务器的地址。您必须在证书中将主机名或 IP 地址添加为主题备用名称(Subject Alternative Name)。
- 您可以同时为 Praefect 服务器配置未加密的监听地址
listen_addr和加密的监听地址tls_listen_addr。如果需要,这允许您逐步从未加密流量过渡到加密流量。若要禁用未加密监听器,请设置praefect['configuration'][:listen_addr] = nil。 - 内部负载均衡器也会访问证书,因此必须配置为允许 TLS 直通(TLS passthrough)。有关如何配置,请参阅负载均衡器文档。
要配置带有 TLS 的 Praefect:
-
为 Praefect 服务器创建证书。
-
在 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 -
编辑
/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', }, } -
保存文件并执行 重新配置。
-
在 Praefect 客户端(包括每个 Gitaly 服务器)上,将证书或其证书颁发机构复制到
/etc/gitlab/trusted-certs:sudo cp cert.pem /etc/gitlab/trusted-certs/ -
在 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' } } -
保存文件并执行 重新配置 GitLab。
## 配置 Sidekiq
Sidekiq 需要连接到 [Redis](#configure-redis)、
[PostgreSQL](#configure-postgresql) 和 [Gitaly](#configure-gitaly) 实例。
还建议它连接到 [Object Storage](#configure-the-object-storage)。
由于建议使用对象存储 而不是 NFS 来存储数据对象,
以下示例包含对象存储配置。
如果您发现环境中 Sidekiq 作业处理缓慢且队列过长,
您可以相应地扩展它。有关更多信息,请参阅
扩展文档。
当配置额外的 GitLab 功能(如容器注册表、SAML 或 LDAP)时,
除了 Rails 配置外,还需更新 Sidekiq 配置。
有关更多信息,请参阅 外部 Sidekiq 文档。
以下 IP 将用作示例:
- `10.6.0.71`:Sidekiq 1
- `10.6.0.72`:Sidekiq 2
要在每个节点上配置 Sidekiq:
1. 通过 SSH 登录到 Sidekiq 服务器。
1. 确认可以访问 PostgreSQL、Gitaly 和 Redis 端口:
```shell
telnet <GitLab 主机> 5432 # PostgreSQL
telnet <GitLab 主机> 8075 # Gitaly
telnet <GitLab 主机> 6379 # Redis-
下载并安装 您选择的 Linux 包。请确保仅添加 GitLab 软件包仓库并为所选操作系统安装 GitLab。
-
创建或编辑
/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 集群 ## 为 Praefect 虚拟存储配置 repositories_storages ## 地址是 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 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.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>'
}-
从您配置的第一个Linux软件包节点复制
/etc/gitlab/gitlab-secrets.json文件,并将此服务器上同名的文件添加或替换。如果这是您正在配置的第一个Linux软件包节点,则可以跳过此步骤。 -
为确保数据库迁移仅在重新配置期间运行(而非在升级时自动运行),请执行:
sudo touch /etc/gitlab/skip-auto-reconfigure仅指定的单个节点应处理迁移,如GitLab Rails后配置部分所述。
-
保存文件并重新配置GitLab。
-
验证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 需要连接到 Redis、PostgreSQL 和 Gitaly 实例。同时建议配置与 Object Storage 的连接。
由于建议使用对象存储 而非 NFS 存储数据对象,因此以下示例包含对象存储配置。
在每个节点上执行以下操作:
-
下载并安装 您选择的 Linux 软件包。请务必仅添加 GitLab 软件包仓库,并为您选择的操作系统安装 GitLab。
-
创建或编辑
/etc/gitlab/gitlab.rb并使用以下配置。为保持各节点间链接的一致性,应用服务器的external_url应指向用户访问 GitLab 时使用的外部 URL。该 URL 是将流量路由至 GitLab 应用服务器的 外部负载均衡器 地址:external_url 'https://gitlab.example.com' # gitlab_rails['repositories_storages'] 为 Praefect 虚拟存储进行配置 # Address 是 Praefect 的内部负载均衡器 IP # 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 连接详情 ## 所有 Sentinel 节点必须一致 redis['master_name'] = 'gitlab-redis' ## 与您为 Redis 主节点设置的认证密码相同 redis['master_password'] = '<redis_primary_password>' ## 包含 `host` 和 `port` 的 Sentinel 列表 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 # 设置用于监控的 exporter 所监听的网路地址 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' ## 如已配置 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 # 对象存储 # 此处为 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’] = “
gitlab_rails[‘backup_upload_connection’] = {
‘provider’ => ‘Google’,
‘google_project’ => ‘
gitlab_rails[‘ci_secure_files_object_store_connection’] = {
‘provider’ => ‘Google’,
‘google_project’ => ‘
如果您使用 带有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>'
}
}-
将证书复制到
/etc/gitlab/trusted-certs:sudo cp cert.pem /etc/gitlab/trusted-certs/ -
从您配置的第一个Linux包节点复制
/etc/gitlab/gitlab-secrets.json文件,并将同名文件添加或替换到此服务器上。如果这是您正在配置的第一个Linux包节点,则可以跳过此步骤。 -
从您配置的第一个Rails节点复制SSH主机密钥(所有以
/etc/ssh/ssh_host_*_key*格式命名的文件),并将同名文件添加或替换到此服务器上。这可确保用户访问负载均衡的Rails节点时不会抛出主机不匹配错误。如果这是您正在配置的第一个Linux包节点,则可以跳过此步骤。 -
为确保数据库迁移仅在重新配置期间运行,而非升级时自动运行,请执行以下操作:
sudo touch /etc/gitlab/skip-auto-reconfigure只有指定的单个节点应处理迁移,详情见 GitLab Rails后配置 部分。
-
重新配置GitLab 以使更改生效。
-
运行
sudo gitlab-rake gitlab:gitaly:check确认节点可与Gitaly建立连接。 -
查看日志以查看请求:
sudo gitlab-ctl tail gitaly -
验证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 配置后步骤
-
确保所有迁移已运行:
gitlab-rake gitlab:db:configure此操作需要将 Rails 节点配置为直接连接主数据库,绕过 PgBouncer。迁移完成后,必须再次将节点配置为通过 PgBouncer。
配置 Prometheus
Linux 包可用于配置运行 Prometheus 的独立监控节点:
-
通过 SSH 登录到监控节点。
-
下载并安装 您选择的 Linux 包。请确保仅添加 GitLab 软件仓库并为所选操作系统安装 GitLab。
-
编辑
/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 -
保存文件并 重新配置 GitLab。
-
验证 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 集群的最佳实践建议,请阅读如何 选择最优集群配置。
支持的低用户数(HA)修改方案
我们推荐的能实现高可用性(HA)的最小 GitLab 参考架构是 60 RPS 或 3000 用户。然而,对于必须服务较少用户或较低 RPS 但需维持 HA 的环境,您可以对架构进行几种支持的修改以降低复杂性和成本。
需要注意的是,要实现 GitLab 的 HA,60 RPS 或 3000 用户架构的组成最终是必需的。每个组件都有各种注意事项和规则需要遵循,而该架构满足了所有这些要求。此架构的小型版本基本相同,但由于性能要求更低,以下修改方案受支持:
除非下方明确说明,否则不支持其他低用量场景的修改方案。
- 降低节点规格:根据您的用户数量,您可以按需降低所有建议的节点规格。不过,不建议低于 通用要求。
- 合并选定节点:以下特定组件支持合并到同一节点上,以降低复杂性(但会牺牲一些性能):
- GitLab Rails 和 Sidekiq:可以移除 Sidekiq 节点,并在 GitLab Rails 节点上启用该组件。
- PostgreSQL 和 PgBouncer:可以移除 PgBouncer 节点,而是在 PostgreSQL 节点上启用它,并将内部负载均衡器指向它们。但是,若要启用 数据库负载均衡,仍需要单独的 PgBouncer 阵列。
- 减少节点数量:某些节点类型不需要共识且可运行更少的节点(但至少两个以保证冗余):
- GitLab Rails 和 Sidekiq:无状态服务没有最小节点数要求。两个节点足以保证冗余。
- PostgreSQL 和 PgBouncer:严格来说不需要仲裁(quorum)。两个 PostgreSQL 节点和两个 PgBouncer 节点足以保证冗余。
- Consul、Redis Sentinel 和 Praefect:需要奇数个节点,且最少三个节点以满足投票仲裁(voting quorum)。
- 在信誉良好的云 PaaS 解决方案中运行选定组件:以下特定组件支持在信誉良好的云提供商 PaaS 解决方案中运行。这样做后,还可以移除额外的依赖组件:
- PostgreSQL:可以在信誉良好的云 PaaS 解决方案(如 Google Cloud SQL 或 Amazon RDS)上运行。在此设置中,不再需要 PgBouncer 和 Consul 节点:
- 如果 Prometheus 自动发现是必需的,可能仍需要 Consul;否则,您必须为所有节点 手动添加抓取配置。
- Redis:可以在信誉良好的云 PaaS 解决方案(如 Google Memorystore 和 AWS ElastiCache)上运行。在此设置中,不再需要 Redis Sentinel。
- PostgreSQL:可以在信誉良好的云 PaaS 解决方案(如 Google Cloud SQL 或 Amazon RDS)上运行。在此设置中,不再需要 PgBouncer 和 Consul 节点:
使用 Helm 图表的云原生混合参考架构(替代方案)
另一种方法是让特定的 GitLab 组件在 Kubernetes 中运行。
支持以下服务:
- GitLab Rails
- Sidekiq
- NGINX
- Toolbox
- Migrations
- Prometheus
混合安装结合了云原生和传统计算部署的优势。通过这种方式,无状态组件可以利用云原生工作负载管理的优势,而有状态组件则部署在带有 Linux 包安装的计算虚拟机上,以获得更高的持久性。
有关设置说明(包括如何在 Kubernetes 和后端组件之间同步哪些 GitLab 密钥的指导),请参阅 Helm 图表高级配置文档。
这是一个高级设置。在 Kubernetes 中运行服务众所周知是复杂的。仅当您具备扎实的 Kubernetes 工作知识和经验时,才建议采用此设置。本节其余部分假定这一点。
Gitaly 集群(Praefect)不支持在 Kubernetes 中运行。更多详情请参阅epic 6127。
集群拓扑结构
以下表格和图表详细说明了混合环境,使用了与之前记录的典型环境相同的格式。
首先是运行在 Kubernetes 中的组件。这些组件跨多个节点组运行,尽管您可以根据需要更改整体组成,只要遵守最低 CPU 和内存要求即可。
| 组件节点组 | 目标节点池总计 | GCP 示例 | AWS 示例 |\n|————|—————|————-|———-|\n| Web服务 | 16 vCPU
20 GB 内存(请求)
28 GB 内存(限制) | 2 × n1-standard-16 | 2 × c5.4xlarge |\n| Sidekiq | 7.2 vCPU
16 GB 内存(请求)
32 GB 内存(限制) | 3 × n1-standard-4 | 3 × m5.xlarge |\n| 支持服务 | 4 vCPU
15 GB 内存 | 2 × n1-standard-2 | 2 × m5.large |\n\n- 对于此设置,我们定期进行测试,并推荐使用Google Kubernetes Engine (GKE)和Amazon Elastic Kubernetes Service (EKS)。其他 Kubernetes 服务也可能适用,但效果可能因情况而异。\n- 提供机器类型示例仅用于说明目的。这些类型在验证和测试中使用,但不作为规定性默认值。支持切换到满足所列要求的其他机器类型。有关更多信息,请参阅支持的机器类型。\n- Web服务 和 Sidekiq 的目标节点池总数仅适用于 GitLab 组件。所选 Kubernetes 提供商的系统进程需要额外的资源。给出的示例已考虑这一点。\n- Supporting 目标节点池总数通常是为了容纳多个资源以支持 GitLab 部署,以及根据您的需求可能希望进行的任何额外部署。与其他节点池类似,所选 Kubernetes 提供商的系统进程也需要资源。给出的示例已考虑这一点。\n- 在生产部署中,不需要将 Pod 分配给特定节点。但是,建议在每个池中拥有多个分布在不同可用区的节点,以符合弹性云架构实践。\n- 出于效率原因,鼓励启用自动扩展功能(如集群自动扩展器),但通常建议针对 Web 服务和 Sidekiq Pod 的下限为 75%,以确保持续的性能。\n\n接下来是在静态计算虚拟机上运行的后端组件(或适用时的外部 PaaS 服务)使用 Linux 包:
| 服务 | 节点数 | 配置 | GCP 示例1 | AWS 示例1 |\n|—————————————-|——–|————–|———————|———————|\n| Consul2 | 3 | 2 vCPU, 1.8 GB 内存 | n1-highcpu-2 | c5.large |\n| PostgreSQL2 | 3 | 2 vCPU, 7.5 GB 内存 | n1-standard-2 | m5.large |\n| PgBouncer2 | 3 | 2 vCPU, 1.8 GB 内存 | n1-highcpu-2 | c5.large |\n| 内部负载均衡器4 | 1 | 4 vCPU, 3.6 GB 内存 | n1-highcpu-4 | c5n.xlarge |\n| Redis/Sentinel3 | 3 | 2 vCPU, 7.5 GB 内存 | n1-standard-2 | m5.large |\n| Gitaly67 | 3 | 4 vCPU, 15 GB 内存 | n1-standard-4 | m5.xlarge |\n| Praefect6 | 3 | 2 vCPU, 1.8 GB 内存 | n1-highcpu-2 | c5.large |\n| Praefect PostgreSQL2 | 1+ | 2 vCPU, 1.8 GB 内存 | n1-highcpu-2 | c5.large |\n| 对象存储5 | - | - | - | - |\n\n脚注:\n\n1. 提供机器类型示例仅用于说明目的。这些类型在验证和测试中使用,但不作为规定性默认值。支持切换到满足所列要求的其他机器类型,包括可用的 ARM 变体。有关更多信息,请参阅支持的机器类型。\n2. 可以选择在信誉良好的第三方外部 PaaS PostgreSQL 解决方案上运行。有关更多信息,请参见提供您自己的 PostgreSQL 实例。\n3. 可以选择在信誉良好的第三方外部 PaaS Redis 解决方案上运行。有关更多信息,请参见提供您自己的 Redis 实例。
-
建议使用信誉良好的第三方负载均衡器或服务(LB PaaS)运行,该服务可提供高可用性能力。 规格取决于所选的负载均衡器和网络带宽等其他因素。有关更多信息,请参阅负载均衡器。
-
应在信誉良好的云提供商或自管理解决方案上运行。有关更多信息,请参阅配置对象存储。
-
Gitaly 集群(Praefect)提供了容错的好处,但带来了额外的设置和管理复杂性。 在部署 Gitaly 集群(Praefect)之前,请查看现有的技术限制和注意事项。如果您想要分片的 Gitaly,请使用前表中列出的相同规格用于
Gitaly。 -
Gitaly 的规格基于健康状态下使用模式和仓库大小的高百分位数。 但是,如果您有大型单体仓库(大于几 GB)或额外工作负载,这些会显著影响 Git 和 Gitaly 的性能,可能需要进一步调整。
对于所有涉及配置实例的 PaaS 解决方案,建议在三个不同的可用区中实现至少三个节点,以符合弹性云架构实践。
@startuml 3k
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** x3" as redis_nodes #FF6347
}
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 组件所使用的目标。
Web 服务
每个 Web 服务 Pod(Puma 和 Workhorse)建议按以下配置运行:
- 4 个 Puma Worker
- 4 个 vCPU
- 5 GB 内存(请求)
- 7 GB 内存(限制)
对于 60 RPS 或 3000 用户,我们建议总共约有 16 个 Puma worker,因此建议至少运行 4 个 Web 服务 Pod。
有关 Web 服务资源用量的更多信息,请参阅图表文档中的 Web 服务资源。
NGINX
还建议将 NGINX 控制器 Pod 作为 DaemonSet 部署在 Web 服务节点上。这允许控制器随其所服务的 Web 服务 Pod 动态扩展,并利用较大机器类型通常具有的更高网络带宽。
这不是硬性要求。只要 NGINX 控制器 Pod 有足够的资源来处理 Web 流量,就可以按需部署它们。
Sidekiq
每个 Sidekiq Pod 建议按以下配置运行:
- 1 个 Sidekiq worker
- 900m vCPU
- 2 GB 内存(请求)
- 4 GB 内存(限制)
与之前记录的标准部署类似,此处使用了初始目标 8 个 Sidekiq worker。根据您具体的工作流程,可能需要额外的 worker。
有关 Sidekiq 资源用量的更多信息,请参阅图表文档中的 Sidekiq 资源。
支持
支持节点池旨在容纳所有不需要在 Web 服务和 Sidekiq 池中运行的辅助部署。
这包括与云提供商实现相关的各种部署,以及支持 GitLab 的部署,例如 GitLab Shell。
若要部署其他服务(如容器注册表、Pages 或监控),请尽可能将这些服务部署在支持节点池中,而不是 Web 服务或 Sidekiq 池中。支持节点池已设计为可容纳多个额外部署。但是,如果您的部署不适合给定的池,则可以相应地增加节点池。相反,如果您的使用场景中该池过度配置,您可以相应地减少。
示例配置文件
针对 60 RPS 或 3000 用户的参考架构配置,GitLab Helm 图表的示例可在 Charts 项目中找到。
下一步骤
按照本指南操作后,您现在应该拥有一个配置了核心功能的全新 GitLab 环境。
根据您的需求,您可能需要配置 GitLab 的其他可选功能。有关更多信息,请参阅 安装 GitLab 后的步骤。
根据您的环境和需求,设置所需附加功能可能需要额外的硬件要求或调整。有关更多信息,请参阅各个页面。