规划并运维实例或群组 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(如 Docker Machine 和 Kubernetes)与不自动扩缩的 Runner,限制有所不同。
- 对于不自动扩缩的 Runner,limit 定义了该 Runner 在主机系统上的容量。
- 对于自动扩缩 Runner,limit 是您希望总共运行的 Runner 数量。
有关 concurrency、limit 和 request_concurrency 如何相互作用以控制作业流的更多信息,请参阅关于极狐GitLab Runner 并发调优的 KB 文章。
基本配置:一个 Runner Manager,一个 Runner
对于最基本的配置,您需要在受支持的计算架构和操作系统上安装极狐GitLab Runner 软件。例如,您可能有一台运行 Ubuntu Linux 的 x86-64 虚拟机(VM)。
安装完成后,您只需执行一次 Runner 注册命令,并选择 shell 执行器。然后编辑 Runner 的 config.toml 文件,将并发设置为 1。
toml1concurrent = 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,那么主机最多可以同时运行三个作业。
toml1concurrent = 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-machine 或 kubernetes 执行器来实现。在这种仅管理器的配置类型中,Runner 代理本身不执行任何 CI/CD 作业。
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_id。system_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,请使用 UI 或 API。使用 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_total | API 请求总数,按 Runner、端点和状态进行分区。 |
| gitlab_runner_autoscaling_idle_target | 应用 IdleScaleFactor 和 IdleCountMin 后,自动扩缩器旨在保持的可用机器数量。 |
| 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 标签。可能的值为 warning 和 error。如果您计划包含此指标,请在观察时使用 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 | 按模式(steps 或 traditional)和执行器显示已执行的总作业数。 |
| gitlab_runner_job_router_circuit_breaker_state | Job Router 熔断器的状态(0 = 关闭,1 = 打开,2 = 半开)。 |
| gitlab_runner_job_router_circuit_breaker_trips_total | Job Router 熔断器跳闸打开的次数。 |
| gitlab_runner_job_router_discovery_cache_events_total | Job Router 发现缓存查找的次数,按 result(hit 或 miss)进行分区。 |
| gitlab_runner_job_router_fallbacks_total | 从 Job Router 回退到直接极狐GitLab 轮询的作业请求数量,按 reason(no_discovery、breaker_open、dial_failed、breaker_tripped 或 router_disabled)进行分区。 |
| gitlab_runner_job_router_get_job_duration_seconds | Runner 端 Job Router GetJob 请求持续时间的直方图,按 runner、system_id 和 result(job、no_job 或 error)进行分区。 |
| gitlab_runner_job_router_get_job_requests_total | Runner 端 Job Router GetJob 请求的数量,按 runner、system_id 和 gRPC 状态 code(OK、速率受限请求的 ResourceExhausted、Unavailable 等)进行分区。 |
| 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 基础设施的自动化脚本。要为您的自有环境生成这些仪表板:
- 使用 jsonnet 配置语言(.dashboard.jsonnet 文件)创建仪表板。
- 使用 jsonnet 库处理 jsonnet 文件以生成 JSON 输出。
- 将生成的 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 模板变量来创建可在不同上下文中复用的仪表板模板:
- 环境:例如 production、staging、development。
- 阶段:例如 main、canary。
- 类型:例如 ci、verify。因用例而异。
- 分片:可选。用于分布式 Runner 部署。
实施这些仪表板的组织必须调整这些变量以匹配其自有环境结构。导入后,请在 Grafana 仪表板设置中更新这些变量。
支持的 Runner
这些仪表板适用于所有极狐GitLab Runner 执行器类型:
- Kubernetes
- Shell
- VM(Docker Machine)
- Windows
指标收集与执行器无关,并且适用于所有 Runner 集群类型。
自定义仪表板
要为您的环境修改仪表板:
-
编辑 dashboards/ci-runners/ 目录中的 .dashboard.jsonnet 文件。
-
使用 Grafonnet 库语法(基于 jsonnet 构建)。
-
使用 playground 测试更改:
shell./test-dashboard.sh dashboards/ci-runners/your-dashboard.dashboard.jsonnet -
使用 ./generate-dashboards.sh 重新生成并部署。
在 Kubernetes 上监控 Runner 的注意事项
对于托管在 OpenShift、EKS 或 GKE 等 Kubernetes 平台上的 Runner 集群,请使用不同的方法来设置 Grafana 仪表板。
在 Kubernetes 上,Runner CI/CD 作业执行 Pod 可能会被频繁创建和删除。在这些情况下,您应该规划监控 Runner Manager Pod,并可能实施以下措施:
- 仪表:显示来自不同来源的同一指标的聚合值。
- 计数器:在应用 rate 或 increase 函数时重置计数器。
高基数指标
某些指标由于高基数,在摄取和存储时可能会占用大量资源。当指标包含具有许多可能值的标签时,就会出现高基数,从而导致大量唯一的时间序列数据点。
为了优化性能,此类指标默认未启用,可以通过使用 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 值的所有指标:
yaml1scrape_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 阶段的指标,并完全丢弃其他指标:
yaml1scrape_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