Omnibus 极狐GitLab 架构和组件
Omnibus 极狐GitLab 是 Chef 的 Omnibus 项目的定制化分支,它使用 Chef 组件,如配方和食谱,在用户的计算机上执行配置极狐GitLab 的任务。Omnibus 极狐GitLab 仓库在 JihuLab.com托管了 Omnibus 极狐GitLab 所需的所有组件。这些包括构建软件包所需的 Omnibus 部分,如配置和项目元数据,以及在安装后用于用户计算机的 Chef 相关组件。

软件定义
极狐GitLab 项目定义文件
Omnibus 架构的主要组件之一是项目定义文件,该文件列出了项目详细信息和与外部软件及库的依赖关系。
项目定义文件 的主要组件包括:
- 项目元数据:包括项目的名称和描述等属性。
- 项目的许可证详情。
- 依赖列表:构建或运行极狐GitLab 所需的外部工具和软件列表,有时包括它们的元数据。
- 用于安装极狐GitLab 的全局配置变量:包括安装目录、系统用户和系统群组。
单个软件定义
Omnibus 极狐GitLab 遵循包含电池的分发方式。所有必要的软件、库和二进制文件均以嵌入格式作为软件包的一部分提供,以确保极狐GitLab 实例的正常运行。
因此,Omnibus 架构的另一个主要组件是软件定义和配置。典型的软件配置包括以下部分:
- 所需的软件版本。
- 软件的许可证。
- 构建/运行软件所需的依赖项。
- 构建软件并将其嵌入软件包中的命令。
有时,为了与极狐GitLab 配合使用,可能需要修补软件的源代码。这可能是为了修复安全漏洞、添加极狐GitLab 所需的某些功能,或者使其能够与极狐GitLab 的其他组件一起工作。为此,Omnibus 极狐GitLab 包含一个补丁目录,其中存储了不同软件的补丁。
对于更广泛的更改,可能更方便在镜像上的分支中跟踪所需的更改。遵循的模式是从上游标签或 sha 创建分支,并在分支名称中引用该分支点。例如,从 Omnibus 代码库,gitlab-omnibus-v5.6.10 是基于上游项目的 v5.6.10 标签。这使我们能够生成一个比较链接,如 https://jihulab.com/gitlab-cn/omnibus/compare/v5.6.10...gitlab-omnibus-v5.6.10,以识别存在的本地更改。
全局极狐GitLab 配置模板
Omnibus 极狐GitLab 随附一个单一配置文件,可用于配置用户计算机上安装的极狐GitLab 实例的每个部分。此配置文件充当将应用于极狐GitLab 实例的所有配置设置的规范来源。它列出了极狐GitLab 实例的一般设置以及不同组件的各种选项。此文件的常见结构包括以 <component>['<setting>'] = <value> 格式指定的配置。所有可用选项都在配置模板中列出,但默认情况下,除了极狐GitLab 基本工作所需的选项外,所有选项均被注释掉。用户可以取消注释并指定相应的值,如果有必要。
极狐GitLab 食谱
如前所述,Omnibus 极狐GitLab 使用 Chef 组件,如食谱、属性和资源。极狐GitLab EE 使用一个独立的食谱,该食谱从极狐GitLab CE 使用的食谱扩展,并添加了仅限 EE 的组件。Omnibus 极狐GitLab 中与 Chef 相关的部分的主要参与者如下:
默认属性
默认属性,顾名思义,指定了配置文件中不同设置的默认值。这些值充当故障保护,如果用户未提供设置值,则会使用这些值,从而确保极狐GitLab 实例的正常工作,而无需用户进行最低限度的调整。
配方
配方在使用 Omnibus 软件包安装极狐GitLab 时承担了大部分繁重的工作,因为它们负责在用户的计算机上设置极狐GitLab 生态系统的每个组件。它们在相应位置创建必要的文件、目录和链接,设置它们的权限和所有者,配置、启动和停止必要的服务,并在文件对应更改时通知这些服务。一个名为 default 的主配方充当入口点,并调用各种组件和服务的所有其他必要配方。
自定义资源
自定义资源可以被视为在配方中可用的全局级宏。自定义资源的一些常见用途是定义常用服务使用的端口,以及列出可能被不同配方使用的重要目录。它们定义了可被不同配方重用的资源。
用于组件配置的模板
如前所述,Omnibus 极狐GitLab 提供了一个单一配置文件来调整极狐GitLab 实例的所有组件。但是,不同组件的架构设计可能需要它们在特定位置拥有单独的配置文件。这些配置文件必须从用户在通用配置文件中指定的值或默认值中生成。因此,Omnibus 极狐GitLab 随附此类配置文件的模板,其中的占位符可以由默认值或用户的值填充。配方完成这些模板的工作,通过填充它们并将它们放置在必要位置。
通用库方法
Omnibus 极狐GitLab 还附带一些库方法,主要用于代码重用。这包括检查服务是否正在运行的方法、检查文件是否存在的方法以及与不同组件交互的辅助方法。它们通常在 Chef 配方中使用。
在 Omnibus 极狐GitLab 使用的所有库中,有一些特殊的库:主要的极狐GitLab 模块及其调用的所有组件特定库。组件特定库包含用于解析配置文件以获取其对应组件定义的设置的方法。主要的极狐GitLab 模块包含协调此过程的方法。它负责识别默认值、调用组件特定库、合并默认值和用户指定值、验证它们,并根据初始值生成附加配置。Omnibus 极狐GitLab 包附带的每个顶级组件都被添加到此模块中,以便它们可以在配置文件和默认属性中被提及并正确解析。
runit
极狐GitLab 使用 runit 配方进行服务管理和监督。runit 配方负责识别操作系统使用的初始化系统,并执行基本的服务管理任务,如为极狐GitLab 创建必要的服务文件、启用服务以及重新加载服务。runit 提供 runit_service 定义,可供其他配方用来与服务进行交互,详见 /files/gitlab-cookbooks/runit 获取更多信息。
服务
服务是我们使用 runit 进程初始化/监督运行的软件进程。您可以使用 gitlab-ctl 命令检查它们的状态、启动、停止和重启它们。配方还可以根据其进程群组和为极狐GitLab 实例配置的设置/角色来禁用或启用这些服务。与它们关联的服务列表和服务群组可以在 files/gitlab-cookbooks/package/libraries/config/services.rb 中找到。
额外的 gitlab-ctl 命令
Omnibus 默认提供了一些包装命令,如 gitlab-ctl reconfigure 和 gitlab-ctl restart,用于管理极狐GitLab 实例。还有一些额外的包装命令,针对 Omnibus 极狐GitLab 仓库中定义的一些特定用例。这些命令与通用 gitlab-ctl 命令一起使用,以执行某些操作,如运行数据库迁移或删除休眠账户以及类似不太常见的任务。
测试
Omnibus 极狐GitLab 仓库使用 ChefSpec 来测试它附带的食谱和配方。通常的策略是检查配方在两种(或更多)情况下是否表现正确:当用户未指定任何相应配置时(即使用默认值时)和使用用户指定配置时。测试可能包括检查文件是否生成在正确位置、服务是否启动/停止/通知、是否调用正确的二进制文件以及方法调用是否传递了正确的参数。配方和库方法都与测试相关联。Omnibus 极狐GitLab 还使用一些支持方法或宏来帮助测试过程。这些测试被定义为在可能的情况下兼容并行化,以减少运行整个测试套件所需的时间。
因此,上述组件中,有些(如软件定义、项目元数据和测试)在构建环境中用于软件包构建期间,而有些(如 Chef 食谱和配方、极狐GitLab 配置文件、runit 和 gitlab-ctl 命令)用于配置用户已安装的实例。
Omnibus 极狐GitLab 的工作生命周期
软件包构建期间发生了什么
构建的软件包类型取决于运行构建过程的操作系统。如果构建是在 Debian 环境中完成的,将创建 .deb 软件包。软件包构建过程中发生的事情可以总结为以下步骤:
- 获取依赖软件的来源:
- 解析软件定义以找出相应版本。
- 从远程或缓存获取源代码。
- 构建单个软件组件:
- 设置必要的环境变量和标志。
- 如果适用,应用补丁。
- 执行组件的构建和安装,将其安装到适当位置(在 /opt/gitlab 内)。
- 生成所有捆绑组件的许可证信息 - 包括外部软件、Ruby gems 和 JS 模块。这涉及分析每个依赖项的定义以及组件提供的任何附加许可证文件(如极狐GitLab Rails 提供的 licenses.csv 文件)。
- 检查组件的许可证,以确保我们不会分发具有不兼容许可证的组件。
- 对软件包进行健康检查,以确保二进制文件链接到可用库。对于捆绑库,二进制文件应链接到它们,而不是全局可用的库。
- 使用 /opt/gitlab 的内容构建软件包。这利用了 gitlab.rb 文件中提供的元数据。这包括软件包名称、版本、维护者、主页以及与其他软件包冲突的信息。
缓存
Omnibus 使用两种类型的缓存来优化构建过程:一种用于存储软件工件(依赖软件的来源),另一种用于存储每个软件组件构建后项目树的快照。
软件工件缓存(用于极狐GitLab Inc 构建)
软件工件缓存使用 Amazon S3 存储桶来存储依赖软件的来源。在我们的构建过程中,此缓存使用命令 bin/omnibus cache populate 填充。这将从 Amazon 存储桶中拉入所有必要的软件来源,并将其存储在必要位置。当软件的版本要求发生变化时,Omnibus 从原始上游拉取并添加到工件缓存中。此过程是 Omnibus 的内部过程,我们在仓库根目录中的 omnibus.rb 文件中配置要使用的 Amazon 存储桶。此缓存确保即使原始上游远程失效,依赖软件仍然可用。
构建缓存
构建过程中的另一个重要缓存类型是构建缓存。构建缓存可以描述为项目树(项目构建的位置 - /opt/gitlab)在每个依赖软件构建后快照。考虑一个具有五个依赖软件的项目 - A、B、C、D 和 E,以此顺序构建,我们不考虑它们的依赖关系。构建缓存利用 Git 标签创建快照。在每个软件构建后,会计算并提交 Git 标签。现在,考虑我们对软件 D 的定义进行了一些更改。A、B、C 和 E 保持不变。当我们尝试再次构建时,Omnibus 可以重用之前在上次构建中 D 构建之前创建的快照。因此,构建 A、B 和 C 所花费的时间可以节省,因为它可以简单地签出在 C 构建后创建的快照。Omnibus 使用在软件“弄脏”缓存(弄脏可能发生在软件定义更改、前一个组件名称/版本更改或当前组件版本更改)构建之前的快照。类似地,如果在构建中软件 A 的定义发生变化,它将弄脏缓存,因此 A 和所有后续依赖项将从头开始构建。如果 C 弄脏缓存,则 A 和 B 被重用,而 C、D 和 E 将重新从头开始构建。
这个缓存只有在跨构建保留时才有意义。为此,我们使用极狐GitLab CI 的缓存机制。我们有一个专用 runner,配置为将其内部缓存存储在 Amazon 存储桶中。在每次构建之前,我们拉入此缓存(我们的 Makefile 中的 restore_cache_bundle 目标),将其移动到适当位置并开始构建。它在弄脏点之前被 Omnibus 使用。构建后,我们打包新的缓存并告诉 CI 备份到 Amazon 存储桶(我们的 Makefile 中的 pack_cache_bundle)。
两种类型的缓存都减少了极狐GitLab 的整体构建时间和对外部因素的依赖。
缓存机制可以总结如下:
- 对每个软件依赖项:
- 解析定义以了解版本和 SHA256。
- 如果在 Amazon 存储桶中的工件缓存中可用的源文件压缩包与版本和 SHA256 匹配,则使用它。
- 否则,从上游远程下载正确的压缩包。
- 从 CI 缓存中获取缓存。
- 对每个软件依赖项:
- 如果缓存被弄脏,则退出循环。
- 否则,签出快照。
- 如果还有剩余的依赖项:
- 对每个剩余依赖项:
- 构建依赖项。
- 创建快照并提交。
- 对每个剩余依赖项:
- 将新的构建缓存推回到 CI 缓存。
多个数据库
以前,极狐GitLab Rails 应用程序是连接到 Omnibus 极狐GitLab 数据库的唯一客户端。随着时间的推移,这种情况发生了变化:
- Praefect 和容器注册表使用自己的数据库。
- Rails 应用程序现在使用分解数据库。
由于可能需要额外的数据库: