极狐 GitLab

规划并运维实例或群组 Runner 集群

在共享服务模型中扩展 Runner 集群时,请应用这些最佳实践和建议。

当您托管实例 Runner 集群时,需要精心规划基础设施,并考虑以下因素:

  • 计算容量。
  • 存储容量。
  • 网络带宽和吞吐量。
  • 作业类型(包括编程语言、操作系统平台和依赖库)。

请根据您组织的需求,使用这些建议来制定极狐GitLab Runner 部署策略。

考虑您的工作负载和环境#

在部署 Runner 之前,请考虑您的工作负载和环境要求。

  • 列出您计划接入极狐GitLab 的团队。
  • 梳理您组织中使用的编程语言、Web 框架和库。例如 Go、C++、PHP、Java、Python、JavaScript、React、Node.js。
  • 估算每个团队每小时、每天可能执行的 CI/CD 作业数量。
  • 确认是否有团队存在无法通过使用容器来满足的构建环境要求。
  • 确认是否有团队的构建环境要求最适合通过为该团队配备专用 Runner 来满足。
  • 估算支持预期需求可能需要的计算容量。

您可以选择不同的基础设施栈来托管不同的 Runner 集群。例如,您可能需要在公有云中部署一些 Runner,并在本地部署另一些 Runner。

Runner 集群上 CI/CD 作业的性能与集群环境直接相关。如果您要执行大量资源密集型 CI/CD 作业,不建议将集群托管在共享计算平台上。

Runner、执行器和自动扩缩能力#

gitlab-runner 可执行文件负责运行您的 CI/CD 作业。每个 Runner 都是一个独立进程,用于获取作业执行请求,并根据预定义配置处理这些请求。作为独立进程,每个 Runner 都可以创建“子进程”(也称为“工作进程”)来运行作业。

并发和限制#

  • 并发:设置当您使用主机系统上所有已配置的 Runner 时,可以同时运行的作业数量。
  • 限制:设置一个 Runner 可以创建用于同时执行作业的子进程数量。

对于自动扩缩 Runner(如 Docker Machine 和 Kubernetes)与不自动扩缩的 Runner,限制有所不同。

  • 对于不自动扩缩的 Runner,limit 定义了该 Runner 在主机系统上的容量。
  • 对于自动扩缩 Runner,limit 是您希望总共运行的 Runner 数量。

有关 concurrencylimitrequest_concurrency 如何相互作用以控制作业流的更多信息,请参阅关于极狐GitLab Runner 并发调优的 KB 文章

基本配置:一个 Runner Manager,一个 Runner#

对于最基本的配置,您需要在受支持的计算架构和操作系统上安装极狐GitLab Runner 软件。例如,您可能有一台运行 Ubuntu Linux 的 x86-64 虚拟机(VM)。

安装完成后,您只需执行一次 Runner 注册命令,并选择 shell 执行器。然后编辑 Runner 的 config.toml 文件,将并发设置为 1

toml
1concurrent = 1 2 3[[runners]] 4 name = "instance-level-runner-001" 5 url = "" 6 token = "" 7 executor = "shell"

此 Runner 可以处理的极狐GitLab CI/CD 作业会直接在您安装 Runner 的主机系统上执行。这就像您自己在终端中运行 CI/CD 作业命令一样。在这种情况下,由于您只执行了一次注册命令,config.toml 文件中只包含一个 [[runners]] 部分。假设您将并发值设置为 1,那么在此系统上,只有一个 Runner“工作进程”可以为 Runner 进程执行 CI/CD 作业。

中级配置:一个 Runner Manager,多个 Runner#

您也可以在同一台机器上注册多个 Runner。这样做时,Runner 的 config.toml 文件中会包含多个 [[runners]] 部分。如果所有额外的 Runner 工作进程都使用 shell 执行器,并且您将全局 concurrent 设置值更新为 3,那么主机最多可以同时运行三个作业。

toml
1concurrent = 3 2 3[[runners]] 4 name = "instance_level_shell_001" 5 url = "" 6 token = "" 7 executor = "shell" 8 9[[runners]] 10 name = "instance_level_shell_002" 11 url = "" 12 token = "" 13 executor = "shell" 14 15[[runners]] 16 name = "instance_level_shell_003" 17 url = "" 18 token = "" 19 executor = "shell" 20

您可以在同一台机器上注册多个 Runner 工作进程,每个工作进程都是一个独立进程。每个工作进程的 CI/CD 作业性能取决于主机系统的计算容量。

自动扩缩配置:一个或多个 Runner Manager,多个工作进程#

当极狐GitLab Runner 设置为自动扩缩时,您可以将一个 Runner 配置为其他 Runner 的管理器。您可以使用 docker-machinekubernetes 执行器来实现。在这种仅管理器的配置类型中,Runner 代理本身不执行任何 CI/CD 作业。

Docker Machine 执行器#

使用 Docker Machine 执行器

  • Runner Manager 会按需预配带有 Docker 的虚拟机实例。
  • 在这些虚拟机上,极狐GitLab Runner 使用您在 .gitlab-ci.yml 文件中指定的容器镜像来执行 CI/CD 作业。
  • 您应该测试 CI/CD 作业在各种机器类型上的性能。
  • 您应该考虑根据速度或成本来优化计算主机。

Kubernetes 执行器#

使用 Kubernetes 执行器

  • Runner Manager 会在目标 Kubernetes 集群上预配 Pod。
  • CI/CD 作业在每个 Pod 上执行,每个 Pod 由多个容器组成。
  • 用于作业执行的 Pod 通常比托管 Runner Manager 的 Pod 需要更多的计算和内存资源。

复用 Runner 配置#

与同一 Runner 认证令牌关联的每个 Runner Manager 都会被分配一个 system_id 标识符。system_id 用于标识使用该 Runner 的机器。使用同一认证令牌注册的 Runner 会通过唯一的 system_id. 归入同一个 Runner 条目下。

将相似的 Runner 归入单一配置可以简化 Runner 集群的运维。

以下是一个可以将相似 Runner 归入单一配置的示例场景:

平台管理员需要使用标签 docker-builds-2vCPU-8GB 提供多个具有相同底层虚拟机实例规格(2 vCPU、8 GB RAM)的 Runner。他们希望至少有两个这样的 Runner,以实现高可用性或扩展。管理员无需在 UI 中创建两个不同的 Runner 条目,而是可以为所有具有相同计算实例规格的 Runner 创建一个 Runner 配置。他们可以复用该 Runner 配置的认证令牌来注册多个 Runner。每个已注册的 Runner 都会继承 docker-builds-2vCPU-8GB 标签。对于单个 Runner 配置下的所有子 Runner,system_id 充当唯一标识符。

分组后的 Runner 可以被多个 Runner Manager 复用来运行不同的作业。

极狐GitLab Runner 会在启动时或保存配置时生成 system_idsystem_id 会保存到与 config.toml 相同目录下的 .runner_system_id 文件中,并显示在作业日志和 Runner 管理页面中。

生成 system_id 标识符#

为了生成 system_id,极狐GitLab Runner 会尝试从硬件标识符中派生唯一系统标识符(例如,在某些 Linux 发行版中是 /etc/machine-id)。如果不成功,极狐GitLab Runner 会使用随机标识符来生成 system_id

system_id 具有以下前缀之一:

  • r_:极狐GitLab Runner 分配了随机标识符。
  • s_:极狐GitLab Runner 从硬件标识符分配了唯一系统标识符。

例如,在创建容器镜像时,务必考虑到这一点,以免将 system_id 硬编码到镜像中。如果 system_id 被硬编码,您将无法区分执行给定作业的主机。

删除 Runner 和 Runner Manager#

要删除使用 Runner 注册令牌(已弃用)注册的 Runner 和 Runner Manager,请使用 gitlab-runner unregister 命令。

要删除使用 Runner 认证令牌创建的 Runner 和 Runner Manager,请使用 UIAPI。使用 Runner 认证令牌创建的 Runner 是可复用配置,可以在多台机器上复用。如果您使用 gitlab-runner unregister 命令,则只会删除 Runner Manager,而不会删除 Runner。

配置实例 Runner#

在自动扩缩配置中使用实例 Runner(其中一个 Runner 充当“Runner Manager”)是一种高效且有效的入门方式。

托管虚拟机或 Pod 的基础设施栈的计算容量取决于:

  • 您在考虑工作负载和环境时收集到的要求。
  • 用于托管 Runner 集群的技术栈。

在开始运行 CI/CD 工作负载并随时间分析性能后,您可能需要调整计算容量。

对于使用带自动扩缩执行器的实例 Runner 的配置,您必须至少从两个 Runner Manager 开始。

随着时间推移,您可能需要的 Runner Manager 总数取决于:

  • 托管 Runner Manager 的栈的计算资源。
  • 您为每个 Runner Manager 选择配置的并发数。
  • 每个管理器每小时、每天和每月执行的 CI/CD 作业所产生的负载。

例如,在 GitLab.com 上,我们使用 Docker Machine 执行器运行七个 Runner Manager。每个 CI/CD 作业都在 Google Cloud Platform(GCP)n1-standard-1 虚拟机中执行。通过这种配置,我们每月处理数百万个作业。

监控 Runner#

大规模运维 Runner 集群的一个关键步骤是设置并使用极狐GitLab 自带的 Runner 监控功能。

下表汇总了极狐GitLab Runner 指标。该列表不包括 Go 特定的进程指标。要在 Runner 上查看这些指标,请按照可用指标中的说明执行命令。

指标名称描述
gitlab_runner_api_request_statuses_totalAPI 请求总数,按 Runner、端点和状态进行分区。
gitlab_runner_autoscaling_idle_target应用 IdleScaleFactorIdleCountMin 后,自动扩缩器旨在保持的可用机器数量。
gitlab_runner_autoscaling_machine_creation_duration_seconds机器创建时间的直方图。
gitlab_runner_autoscaling_machine_states此提供商中每种状态的机器数量。
gitlab_runner_autoscaling_max_growth_rate可以同时处于创建状态的最大机器数量(0 = 无限制)。
gitlab_runner_concurrent并发设置的值。
gitlab_runner_errors_total捕获的错误数量。此指标是一个跟踪日志行的计数器。该指标包含 level 标签。可能的值为 warningerror。如果您计划包含此指标,请在观察时使用 rate()increase()。换句话说,如果您注意到警告或错误的速率在增加,这可能表明存在需要进一步调查的问题。
gitlab_runner_jobs显示正在执行的作业数量(标签中具有不同的作用域)。
gitlab_runner_job_duration_seconds作业持续时间的直方图。
gitlab_runner_job_queue_duration_seconds表示作业排队持续时间的直方图。
gitlab_runner_acceptable_job_queuing_duration_exceeded_total统计作业超过配置的排队时间阈值的频率。
gitlab_runner_job_stage_duration_seconds表示作业在每个阶段持续时间的直方图。此指标是一个高基数指标。有关更多信息,请参阅高基数指标部分
gitlab_runner_jobs_total显示已执行的总作业数。
gitlab_runner_job_execution_mode_total按模式(stepstraditional)和执行器显示已执行的总作业数。
gitlab_runner_job_router_circuit_breaker_stateJob Router 熔断器的状态(0 = 关闭,1 = 打开,2 = 半开)。
gitlab_runner_job_router_circuit_breaker_trips_totalJob Router 熔断器跳闸打开的次数。
gitlab_runner_job_router_discovery_cache_events_totalJob Router 发现缓存查找的次数,按 resulthitmiss)进行分区。
gitlab_runner_job_router_fallbacks_total从 Job Router 回退到直接极狐GitLab 轮询的作业请求数量,按 reasonno_discoverybreaker_opendial_failedbreaker_trippedrouter_disabled)进行分区。
gitlab_runner_job_router_get_job_duration_secondsRunner 端 Job Router GetJob 请求持续时间的直方图,按 runnersystem_idresultjobno_joberror)进行分区。
gitlab_runner_job_router_get_job_requests_totalRunner 端 Job Router GetJob 请求的数量,按 runnersystem_id 和 gRPC 状态 codeOK、速率受限请求的 ResourceExhaustedUnavailable 等)进行分区。
gitlab_runner_limit限制设置的当前值。
gitlab_runner_request_concurrency当前对新作业的并发请求数。
gitlab_runner_request_concurrency_exceeded_total超过配置的 request_concurrency 限制的过量请求计数。
gitlab_runner_version_info一个具有常量 1 值的指标,由不同的构建统计字段标记。
process_cpu_seconds_total用户和系统 CPU 花费的总时间(以秒为单位)。
process_max_fds打开文件描述符的最大数量。
process_open_fds打开文件描述符的数量。
process_resident_memory_bytes常驻内存大小(以字节为单位)。
process_start_time_seconds进程的启动时间,以 Unix 纪元以来的秒数衡量。
process_virtual_memory_bytes虚拟内存大小(以字节为单位)。
process_virtual_memory_max_bytes可用的最大虚拟内存量(以字节为单位)。

Grafana 仪表板配置提示#

在这个公共代码仓库中,您可以找到我们用于运维 GitLab.com 上 Runner 集群的 Grafana 仪表板源代码。

我们为 GitLab.com 跟踪了大量指标。作为大型云 CI/CD 提供商,我们需要对系统有多种不同的视图,以便调试问题。在大多数情况下,私有化部署的 Runner 集群不需要跟踪我们在 GitLab.com 上跟踪的那么多指标。

仪表板生成流程#

Grafana 只接受 JSON 格式,因此您必须将 jsonnet 文件转换为 JSON。

runbooks 代码仓库仅包含用于 GitLab 基础设施的自动化脚本。要为您的自有环境生成这些仪表板:

  1. 使用 jsonnet 配置语言(.dashboard.jsonnet 文件)创建仪表板。
  2. 使用 jsonnet 库处理 jsonnet 文件以生成 JSON 输出。
  3. 将生成的 JSON 文件上传到 Grafana(使用 API 或 UI)。

可用的 Runner 仪表板#

以下是您应该用来监控 Runner 集群的几个基本仪表板:

Runner 上启动的作业:

  • 查看在选定时间间隔内 Runner 集群上执行的总作业概览。
  • 查看使用趋势。您至少应每周分析一次此仪表板。
  • 将此数据与作业持续时间等指标关联起来,以确定是否需要进行配置更改或容量升级,从而满足您的 CI/CD 作业性能 SLO。

作业持续时间:

  • 分析 Runner 集群的性能和扩展情况。
  • 识别性能瓶颈和优化机会。

Runner 容量:

  • 查看正在执行的作业数量除以限制值或并发值。
  • 确定是否仍有容量来执行额外作业。
  • 根据利用率趋势规划容量升级。

其他仪表板包括:

  • 主仪表板(main.dashboard.jsonnet):Runner 基础设施和 HAProxy 指标概览。
  • 业务指标(business-stats.dashboard.jsonnet):作业统计、已完成的作业分钟数和 Runner 饱和度。
  • 自动扩缩算法(autoscaling-algorithm.dashboard.jsonnet):自动扩缩行为和机器状态的可视化。
  • 排队概览(queuing-overview.dashboard.jsonnet):作业队列深度和等待时间。
  • 请求并发(request-concurrency.dashboard.jsonnet):并发请求分析。
  • 部署(deployment.dashboard.jsonnet):与部署相关的指标。
  • 事件仪表板:用于排查自动扩缩、数据库、应用程序和 Runner Manager 问题的专用仪表板。

每个仪表板都在源 jsonnet 文件中包含描述和上下文,以说明正在显示哪些指标。

模板变量#

仪表板使用 Grafana 模板变量来创建可在不同上下文中复用的仪表板模板:

  • 环境:例如 productionstagingdevelopment
  • 阶段:例如 maincanary
  • 类型:例如 civerify。因用例而异。
  • 分片:可选。用于分布式 Runner 部署。

实施这些仪表板的组织必须调整这些变量以匹配其自有环境结构。导入后,请在 Grafana 仪表板设置中更新这些变量。

支持的 Runner#

这些仪表板适用于所有极狐GitLab Runner 执行器类型:

  • Kubernetes
  • Shell
  • VM(Docker Machine)
  • Windows

指标收集与执行器无关,并且适用于所有 Runner 集群类型。

自定义仪表板#

要为您的环境修改仪表板:

  1. 编辑 dashboards/ci-runners/ 目录中的 .dashboard.jsonnet 文件。

  2. 使用 Grafonnet 库语法(基于 jsonnet 构建)。

  3. 使用 playground 测试更改:

    shell
    ./test-dashboard.sh dashboards/ci-runners/your-dashboard.dashboard.jsonnet
  4. 使用 ./generate-dashboards.sh 重新生成并部署。

在 Kubernetes 上监控 Runner 的注意事项#

对于托管在 OpenShift、EKS 或 GKE 等 Kubernetes 平台上的 Runner 集群,请使用不同的方法来设置 Grafana 仪表板。

在 Kubernetes 上,Runner CI/CD 作业执行 Pod 可能会被频繁创建和删除。在这些情况下,您应该规划监控 Runner Manager Pod,并可能实施以下措施:

  • 仪表:显示来自不同来源的同一指标的聚合值。
  • 计数器:在应用 rateincrease 函数时重置计数器。

高基数指标#

某些指标由于高基数,在摄取和存储时可能会占用大量资源。当指标包含具有许多可能值的标签时,就会出现高基数,从而导致大量唯一的时间序列数据点。

为了优化性能,此类指标默认未启用,可以通过使用 FF_EXPORT_HIGH_CARDINALITY_METRICS 功能标志来切换。

高基数指标列表#

  • gitlab_runner_job_stage_duration_seconds:以秒为单位衡量各个作业阶段的持续时间。此指标包含 stage 标签,该标签可以具有以下预定义值:

    • resolve_secrets
    • prepare_executor
    • prepare_script
    • get_sources
    • clear_worktree
    • restore_cache
    • download_artifacts
    • after_script
    • step_script
    • archive_cache
    • archive_cache_on_failure
    • upload_artifacts_on_success
    • upload_artifacts_on_failure
    • cleanup_file_variables

    此外,此列表还可能包括自定义的用户定义步骤,例如 step_run

管理高基数指标#

您可以使用 Prometheus relabel 配置来移除不必要的标签值或整个指标,从而控制和降低基数。

移除特定阶段的示例配置#

以下配置会移除 stage 标签中具有 prepare_executor 值的所有指标:

yaml
1scrape_configs: 2 - job_name: 'gitlab_runner_metrics' 3 static_configs: 4 - targets: ['localhost:9252'] 5 metric_relabel_configs: 6 - source_labels: [__name__, "stage"] 7 regex: "gitlab_runner_job_stage_duration_seconds;prepare_executor" 8 action: drop

仅保留相关阶段的示例#

以下配置仅保留 step_script 阶段的指标,并完全丢弃其他指标:

yaml
1scrape_configs: 2 - job_name: 'gitlab_runner_metrics' 3 static_configs: 4 - targets: ['localhost:9252'] 5 metric_relabel_configs: 6 - source_labels: [__name__, "stage"] 7 regex: "gitlab_runner_job_stage_duration_seconds;step_script" 8 action: keep