GitLab Architecture Overview

GitLab Architecture Overview

GitLab 有两种软件发行 :开源社区版 (CE)和开放核心 (EE). GitLab 在不同的订阅下可用.

GitLab 的新版本在稳定的分支中发布,而 master 分支则用于前沿开发.

有关信息,请参见 .

EE 和 CE 都需要一些名为 GitLab Shell 和 Gitaly 的附加组件. 这些组件分别可从GitLab Shell和存储库中获得. 新版本通常是标签,但是停留在 master 分支上将为您提供最新的稳定版本. 新版本通常与 GitLab CE 发布大约相同的时间,但非正式的安全更新被认为很重要.

Components

A typical install of GitLab will be on GNU/Linux. It uses NGINX or Apache as a web front end to proxypass the Unicorn web server. By default, communication between Unicorn and the front end is via a Unix domain socket but forwarding requests via TCP is also supported. The web front end accesses bypassing the Unicorn server to serve static pages, uploads (e.g. avatar images or attachments), and pre-compiled assets. GitLab serves web pages and the using the Unicorn web server. It uses Sidekiq as a job queue which, in turn, uses Redis as a non-persistent database backend for job information, meta data, and incoming jobs.

我们还支持使用我们的GitLab Helm 图表在 Kubernetes 上部署 GitLab.

GitLab Web 应用程序将 PostgreSQL 用于持久数据库信息(例如,用户,权限,问题,其他元数据). GitLab 默认将其服务的裸 Git 存储库存储在/home/git/repositories . 它还使用裸存储库保留默认的分支和挂钩信息.

通过 HTTP / HTTPS 提供存储库时,GitLab 利用 GitLab API 来解析授权和访问以及提供 Git 对象.

附加组件 GitLab Shell 通过 SSH 提供存储库. 它管理/home/git/.ssh/authorized_keys的 SSH 密钥,不应手动对其进行编辑. GitLab Shell 通过 Gitaly 访问裸仓库以提供 Git 对象,并与 Redis 进行通信以将作业提交给 Sidekiq,以供 GitLab 处理. GitLab Shell 查询 GitLab API 以确定授权和访问权限.

Gitaly 从 GitLab Shell 和 GitLab Web 应用程序执行 Git 操作,并向 GitLab Web 应用程序提供 API,以从 Git 获取属性(例如标题,分支,标签,其他元数据),并获取 Blob(例如 diff,commit,文件).

您可能也的生产体系结构感兴趣 .

这是一个简化的架构图,可用于了解 GitLab 的架构.

下面的中提供了完整的架构图.

Component diagram

图 TB HTTP [HTTP / HTTPS]-TCP 80、443-> NGINX [NGINX] SSH-TCP 22-> GitLabShell [GitLab Shell] SMTP [SMTP Gateway] Geo [GitLab Geo Node]-TCP 22, 80,443-> NGINX GitLabShell —TCP 8080-> Unicorn [“ Unicorn(GitLab Rails)”] GitLabShell-> Praefect GitLabShell-> Redis Unicorn-> PgBouncer [PgBouncer] Unicorn-> Redis Unicorn- -> Praefect Sidekiq-> Redis Sidekiq-> PgBouncer Sidekiq-> Praefect GitLabWorkhorse [GitLab Workhorse]-> Unicorn GitLabWorkhorse-> Redis GitLabWorkhorse-> Praefect Praefect-> Gitaly NGINX-> GitLabWorkhorse NGINX- TCP 8090-> GitLabPages [GitLab 页面] NGINX-> Grafana [Grafana] Grafana-TCP 9090-> Prometheus [Prometheus] Prometheus-TCP 80,443-> Unicorn RedisExporter [Redis Exporter]-> Redis Prometheus-TCP 9121-> RedisExporter PostgreSQLExporter [PostgreSQL 导出器]-> PostgreSQL PgBouncerExporter [PgBouncer 导出器]-> PgBouncer Prometheus-TCP 9187-> PostgreSQLExporter Prometheus-TCP 9100-> NodeExporter [Node Exp orter] Prometheus-TCP 9168-> GitLabExporter [GitLab Exporter] Prometheus-TCP 9127-> PgBouncerExporter GitLabExporter-> PostgreSQL GitLabExporter-> GitLabShell GitLabExporter-> Sidekiq PgBouncer-> Consul PostgreSQL-> Consul PgBouncer -> PostgreSQL NGINX->注册表 Unicorn->注册表 NGINX-> Mattermost Mattermost —- Unicorn Prometheus-> Alertmanager 迁移-> PostgreSQL Runner-TCP 443-> NGINX Unicorn-TCP 9200- > Elasticsearch Sidekiq-TCP 9200-> Elasticsearch Sidekiq-TCP 80,443-> Sentry Unicorn-TCP 80,443-> Sentry Sidekiq-UDP 6831-> Jaeger Unicorn-UDP 6831-> Jaeger Gitaly-UDP 6831-> Jaeger GitLabShell-UDP 6831-> Jaeger GitLabWorkhorse-UDP 6831-> Jaeger Alertmanager-TCP 25-> SMTP Sidekiq-TCP 25-> SMTP Unicorn-TCP 25-> SMTP Unicorn-TCP 369-> LDAP Sidekiq-TCP 369-> LDAP Unicorn-TCP 443-> ObjectStorage [“ Object Storage”] Sidekiq-TCP 443-> ObjectStorage GitLabWorkhorse- TCP 协议 443-> ObjectStorage 注册表-TCP 443-> ObjectStorage Geo-TCP 5432-> PostgreSQL

Component legend

  • ✅-默认安装
  • ⚙-需要其他配置或 GitLab 托管应用
  • ⤓-需要手动安装
  • ❌-不支持或无可用说明
  • 不适用-不适用

组件状态链接到每个组件的配置文档.

Component list

表描述链接:

Component details

本文档供系统管理员和 GitLab 支持工程师使用,他们希望进一步了解 GitLab 的内部结构以及如何协同工作.

部署后,应将 GitLab 视为以下过程的合并. 在进行故障排除或调试时,请尽可能明确地指出要引用的组件. 那应该增加清晰度并减少混乱.

Layers

从流程的角度来看,可以认为 GitLab 具有两层:

  • 监视 :不需要任何层来交付 GitLab 应用程序,但是它将允许管理员更深入地了解他们的基础结构以及整个服务在做什么.
  • 核心 :对 GitLab 作为平台交付至关重要的任何过程. 如果这些过程中的任何一个停止,都将导致 GitLab 中断. 对于核心层,您可以进一步分为:
    • 处理器 :这些进程负责实际执行操作并提供服务.
    • 数据 :这些服务为 GitLab 服务存储/公开结构化数据.

Alertmanager

警报管理器是 Prometheus 提供的工具,用于“处理由客户端应用程序(例如 Prometheus 服务器)发送的警报. 它负责将重复数据删除,分组和路由到正确的接收者集成,例如电子邮件,PagerDuty 或 Opsgenie. 它还负责沉默和禁止警报.” 您可以在阅读更多有关我们将要发出警报的内容.

Certificate management

Consul

  • Configuration:
  • 层:核心服务(数据)
  • GitLab.com: Consul

Consul 是用于服务发现和配置的工具. Consul 是分布式的,高度可用的,并且具有极高的可伸缩性.

Database migrations

Elasticsearch

Elasticsearch 是为云构建的分布式 RESTful 搜索引擎.

Gitaly

  • Configuration:
  • 层:核心服务(数据)
  • Process: gitaly
  • GitLab.com:

Gitaly 是一项由 GitLab 设计的服务,旨在消除我们在 GitLab 的分布式部署(请考虑 GitLab.com 或高可用性部署)中对 Git 存储使用 NFS 的需求. 从 11.3.0 开始,此服务处理 GitLab 中的所有 Git 级别访问. 您可以在项目的 README 中阅读有关该项目的更多信息.

Praefect

  • Project page
  • Configuration:
  • 层:核心服务(数据)
  • Process: praefect
  • GitLab.com:

Praefect 是每个 Git 客户端和 Gitaly 之间的透明代理,用于协调将存储库更新复制到辅助节点.

GitLab Geo

  • Configuration:
  • 层:核心服务(处理器)

GitLab Exporter

GitLab Exporter 是一个内部设计的流程,允许我们将有关 GitLab 应用程序内部的度量导出到 Prometheus. 您可以阅读更多内容.

GitLab Pages

  • Configuration:
  • 层:核心服务(处理器)
  • GitLab.com:

GitLab 页面是一项功能,可让您直接从 GitLab 中的存储库发布静态网站.

您可以将其用于个人或企业网站,例如投资组合,文档,清单和业务演示. 您还可以将任何许可证归于您的内容.

GitLab Runner

GitLab Runner 运行作业并将结果发送到 GitLab.

GitLab CI / CD 是 GitLab 附带的开源持续集成服务,用于协调测试. 该项目的旧名称是GitLab CI Multi Runner但从现在开始,请使用GitLab Runner (不带 CI).

GitLab Shell

GitLab Workhorse

  • Configuration:
  • 层:核心服务(处理器)
  • Process: gitlab-workhorse
  • GitLab.com:

GitLab Workhorse是由 GitLab 设计的程序,可帮助缓解 Unicorn 的压力. 您可以阅读有关发展的更多信息. 它旨在充当智能反向代理,以帮助整体上加快 GitLab 的速度.

Grafana

Grafana 是适用于 Graphite,Elasticsearch,OpenTSDB,Prometheus 和 InfluxDB 的开源,功能丰富的指标仪表板和图形编辑器.

Jaeger

受到 Dapper 和 OpenZipkin 启发的 Jaeger 是一个分布式跟踪系统. 它可以用于监视基于微服务的分布式系统.

有关监视已部署的应用程序,请参阅Jaeger 跟踪文档.

Logrotate

  • Project page
  • Configuration:
  • 层:核心服务
  • Process: logrotate

GitLab 包含大量全部记录的服务. 从 7.4 开始,我们开始捆绑自己的 logrotate,以确保我们负责任地进行日志记录. 这只是普通开源产品的打包版本.

Mattermost

Mattermost 是一种开放源代码的私有云,是 Slack 替代品.

MinIO

  • Configuration:
  • 层:核心服务(数据)
  • GitLab.com:

MinIO 是根据 Apache License v2.0 发布的对象存储服务器. 它与 Amazon S3 云存储服务兼容. 它最适合存储非结构化数据,例如照片,视频,日志文件,备份和容器/ VM 映像. 一个对象的大小范围可以从几个 KB 到最大 5TB.

NGINX

NGINX 有一个用于所有 HTTP 请求的 Ingress 端口,并将它们路由到 GitLab 中的相应子系统. 我们捆绑了流行的开源 Web 服务器的未修改版本.

Node Exporter

Node Exporter是 Prometheus 工具,可为我们提供底层计算机的指标(以 CPU /磁盘/负载为例). 它只是 Prometheus 项目中常见开源产品的打包版本.

PgBouncer

PostgreSQL 的轻量级连接池.

PgBouncer Exporter

  • Configuration:
  • 层:监控
  • GitLab.com:

Prometheus PgBouncer 的出口商. 导出指标为 9127 / metrics.

PostgreSQL

  • Configuration:
  • 层:核心服务(数据)
  • Process: postgresql
  • GitLab.com:

GitLab 打包了流行的数据库,以存储应用程序元数据和用户信息.

PostgreSQL Exporter

是社区提供的 Prometheus 导出器,它将 PostgreSQL 的有关数据传递给 Prometheus,以在 Grafana 仪表板中使用.

Prometheus

Prometheus 是一个时序工具,可帮助 GitLab 管理员公开有关用于向 GitLab 提供服务的各个流程的指标.

Redis

Redis 被打包以提供存储位置:

  • 会话数据
  • 临时缓存信息
  • 后台作业队列

Redis Exporter

Redis Exporter旨在向 Prometheus 提供有关 Redis 流程的特定指标,以便我们可以在 Grafana 中绘制这些指标.

Registry

用户使用注册表来存储自己的 Docker 映像. 捆绑的注册表使用 NGINX 作为负载平衡器,并使用 Gi​​tLab 作为身份验证管理器. 每当客户端请求从注册表中拉出或推送图像时,客户端都会返回401响应以及标头,其中详细说明了从何处获取身份验证令牌(在本例中为 GitLab 实例). 然后,客户端将向 GitLab 请求”拉”或”推”身份验证令牌,然后将原始请求重试到注册表. 了解有关令牌认证的更多信息.

也可以将外部注册表配置为将 GitLab 用作身份验证端点.

Sentry

从根本上说,Sentry 是一项服务,可帮助您实时监视和修复崩溃. 该服务器使用 Python,但是它包含用于在任何应用程序中从任何语言发送事件的完整 API.

有关监视已部署的应用程序,请参阅Sentry 集成文档

Sidekiq

Sidekiq 是 Ruby 后台作业处理器,可从 Redis 队列中提取作业并进行处理. 后台作业使 GitLab 通过将工作移至后台来提供更快的请求/响应周期.

Unicorn

Unicorn是一个 Ruby 应用程序服务器,用于运行核心的 Rails 应用程序,该应用程序在 GitLab 中提供面向用户的功能. 通常,根据 GitLab 版本,您会看到此输出为bundleconfig.ru .

LDAP Authentication

Outbound Email

Inbound Email

GitLab Managed Apps

GitLab 提供GitLab 托管应用程序 ,一键安装各种应用程序,可以直接将其添加到配置的集群中. 使用 Auto DevOps 时,Review Apps 和部署需要这些应用程序. 您可以在创建集群后安装它们. 这包括:

GitLab 为最终用户提供了两个”接口”来访问服务:

  • Web HTTP 请求(查看 UI / API)
  • Git HTTP / SSH 请求(推/拉 Git 数据)

了解两者之间的区别很重要,因为某些过程在两种过程中都使用,而另一些过程则是特定请求类型所独有的.

向 HTTP 端点发出请求(认为/users/sign_in )时,请求将通过 GitLab 服务采用以下路径:

  • NGINX-充当我们的第一线反向代理.
  • GitLab Workhorse-确定是否需要转到 Rails 应用程序或其他地方以减少 Unicorn 上的负载.
  • Unicorn-由于这是一个 Web 请求,并且需要访问该应用程序,因此它将转到 Unicorn.
  • PostgreSQL / Gitaly / Redis-根据请求的类型,它可能会通过这些服务来存储或检索数据.

GitLab Git Request Cycle

下面我们描述 HTTP 与 SSH Git 请求将采用的不同路径. Web 请求周期有一些重叠,但也有一些差异.

Web Request (80/443)

通过 HTTP 进行的 Git 操作使用Git 文档中描述的无状态”智能”协议,但处理这些操作的职责分散在多个 GitLab 组件中.

这是git fetch的序列图. 请注意,所有请求都会通过 NGINX 以及任何其他 HTTP 负载平衡器传递,但不会以任何方式进行转换. 所有路径都相对于/namespace/project.git URL 呈现.

sequenceDiagram 参与者客户端参与者上的 Git NGINX 参与者 Workhorse 参与者 Rails 参与者 Gitaly 参与者服务器上的 Git 注意客户端上的 Git 左侧:git fetch 客户端上的 info-refs Git->> + Workhorse:GET / info / refs?service = git-upload-pack Workhorse->> + Rails:GET / info / refs?service = git-upload-pack 注意 Rails 的右侧:验证检查 Rails->>-Workhorse:Gitlab :: Workhorse.git_http_ok​​ Workhorse->> + Gitaly:SmartHTTPService.InfoRefsUploadPack 请求服务器上的 Gitaly->> + Git:git upload-pack —stateless-rpc —advertise-refs 服务器上的 Git->>-Gitaly:git upload-pack 响应 Gitaly->>-工作马:SmartHTTPService.InfoRefsUploadPack 响应 Workhorse->>-客户端上的 Git:200 OK 注意客户端上的 Git 左侧:git fetch 在客户端上获取包装 Git->> + Workhorse:POST / git-upload-pack Workhorse->> + Rails:POST / git-upload-pack 注意 Rails 的权利:Auth check Rails->>-Workhorse:Gitlab: :Workhorse.git_http_ok​​ Workhorse->> + Gitaly:SmartHTTPService.PostUploadPack 请求 Gitaly->> + Git 在服务器上:git upload-pack —stateless-rpc 服务器上的 Git->>-Gitaly:git upload-pack 响应 Gitaly- ->>-Workhorse:SmartHTTPService.PostUploadPack 响应 Workhorse->>-客户端上的 Git:200 OK

该序列与git push相似,除了使用代替git-upload-pack .

SSH Request (22)

没有任何 GitLab 组件直接使用 SSH-所有 SSH 连接都是在客户端计算机上的 Git 与 SSH 服务器之间建立的,从而终止了连接. 对于 SSH 服务器,所有连接均以git用户身份进行身份验证; GitLab 用户通过客户端提供的 SSH 密钥来区分.

这是git fetch的序列图,假设启用了快速 SSH 密钥查找 . 请注意, AuthorizedKeysCommand是提供的可执行文件:

sequenceDiagram 参与者客户端参与者上的 Git SSH 服务器参与者 AuthorizedKeysCommand 参与者 GitLab Shell 参与者 Rails 参与者 Gitaly 参与者服务器上的 Git 注意客户端上的 Git 左侧:git fetch 客户端上的 Git->> + SSH 服务器:ssh git fetch-pack request SSH 服务器-> > + AuthorizedKeysCommand:gitlab-shell-authorized-keys-check git AAAA … AuthorizedKeysCommand->> + Rails:GET / internal / api / authorized_keys?key = AAAA …注意 Rails 的右边:查找密钥 ID Rails— >>-AuthorizedKeysCommand:200 OK,command =” gitlab-shell upload-pack key_id = 1” AuthorizedKeysCommand->>-SSH 服务器:command =” gitlab-shell upload-pack key_id = 1” SSH 服务器->> + GitLab Shell:gitlab-shell upload-pack key_id = 1 GitLab Shell->> + Rails:GET / internal / api / allowed?action = upload_pack&key_id = 1 注意 Rails 的权利:Auth check Rails->>-GitLab Shell:200 OK ,{gitaly:…} GitLab Shell->> + Gitaly:SSHService.SSHUploadPack 请求服务器上的 Gitaly->> + Git:git upload-pack 请求注意客户端上的 Git,Git on 服务器:Git 客户端和服务器上服务器 Git 之间的双向通信->>-Gitaly:git upload-pack 响应 Gitaly->>-GitLab Shell:SSHService.SSHUploadPack 响应 GitLab Shell->>-SSH 服务器:gitlab-shell 上载 SSH 伺服器的上载回应->>-Git 使用者:ssh git fetch-pack 回应

git push操作非常相似,除了使用git receive-pack代替git upload-pack .

如果未启用快速 SSH 密钥查找,则 SSH 服务器将从~git/.ssh/authorized_keys文件读取,以确定为给定的 SSH 会话运行什么命令. 它由 Rails 中的AuthorizedKeysWorker保持最新状态,并计划在用户修改 SSH 密钥时运行.

可以使用代替密钥. 在这种情况下, AuthorizedKeysCommand替换为AuthorizedPrincipalsCommand . 这将从证书中提取用户名,而无需使用 Rails 内部 API,该 API 稍后将代替/api/internal/allowed调用中的key_id使用.

GitLab Shell 还具有一些不涉及 Gitaly 的操作,例如重置两因素身份验证代码. 这些操作以相同的方式处理,除了没有往返 Gitaly 的往返-Rails 作为内部 API调用的一部分执行操作,并且 GitLab Shell 将响应直接流回用户.

System Layout

在图片中引用~git时,它表示 Git 用户的主目录,通常是/home/git .

GitLab 主要以git用户身份安装在/home/git用户主目录中. GitLab 服务器软件以及存储库都位于主目录中(尽管存储库位置是可配置的).

裸存储库位于/home/git/repositories . GitLab 是 Ruby on Rails 应用程序,因此可以通过研究 Ruby on Rails 应用程序的工作方式来了解内部工作的细节.

为了通过 SSH 提供存储库,有一个名为 GitLab Shell 的附加应用程序,它安装在/home/git/gitlab-shell .

Installation Folder Summary

总结一下,这里是的目录结构 .

GitLab 有几个要运行的组件. 它需要一个持久数据库(PostgreSQL)和 Redis 数据库,并使用 Apache httpd或 NGINX 代理传递 Unicorn. 所有这些组件都应以与 GitLab 不同的系统用户身份运行(例如, postgresrediswww-data ,而不是git ).

作为git用户,它将启动 Sidekiq 和 Unicorn(默认情况下在端口8080上运行的简单 Ruby HTTP 服务器). 在 GitLab 用户下,通常有 4 个进程: unicorn_rails master (1 个进程), unicorn_rails worker (2 个进程), (1 个进程).

Repository access

可以通过 HTTP 或 SSH 访问存储库. HTTP 克隆/推/拉使用 GitLab API,而 SSH 克隆由 GitLab Shell 处理(先前已说明).

有关更多信息,请参见自述文件.

Init scripts of the services

GitLab 初始化脚本启动和停止 Unicorn 和 Sidekiq:

  1. /etc/init.d/gitlab
  2. Usage: service gitlab {start|stop|restart|reload|status}

Redis(键值存储/非持久数据库):

SSH daemon:

  1. /etc/init.d/sshd
  2. Usage: /etc/init.d/sshd {start|stop|restart|reload|force-reload|condrestart|try-restart|status}

Web 服务器(以下之一):

永久数据库:

  1. $ /etc/init.d/postgresql
  2. Usage: /etc/init.d/postgresql {start|stop|restart|reload|force-reload|status} [version ..]

Log locations of the services

GitLab(包括 Unicorn 和 Sidekiq 日志):

  • /home/git/gitlab/log/ contains application.log, production.log, sidekiq.log, unicorn.stdout.log, git_json.log and unicorn.stderr.log normally.

GitLab 外壳:

  • /home/git/gitlab-shell/gitlab-shell.log

SSH:

  • /var/log/auth.log身份验证日志(在 Ubuntu 上).
  • /var/log/secure身份验证日志(在 RHEL 上).

NGINX:

  • /var/log/nginx/包含错误和访问日志.

Apache httpd:

  • Explanation of Apache logs.
  • /var/log/apache2/包含错误和输出日志(在 Ubuntu 上).
  • /var/log/httpd/包含错误和输出日志(在 RHEL 上).

Redis:

  • /var/log/redis/redis.log那里还有日志循环日志.

PostgreSQL:

  • /var/log/postgresql/*

GitLab specific configuration files

GitLab 的配置文件位于/home/git/gitlab/config/* . 常用的配置文件包括:

  • gitlab.yml -GitLab 配置.
  • unicorn.rb -Unicorn Web 服务器设置.
  • database.yml数据库连接设置.

GitLab Shell 在/home/git/gitlab-shell/config.yml有一个配置文件.

GitLab提供 Rake 任务,您可以在其中查看版本信息,并对配置进行快速检查以确保在应用程序中正确配置了它. 请参阅 . 简而言之,请执行以下操作:

GitLab.com

我们还详细介绍但是除非您拥有数百万的用户,否则这可能是最重要的.