首页
/ etcd Prow CI 作业体系:作业类型、测试触发方式与资源用量分析实战

etcd Prow CI 作业体系:作业类型、测试触发方式与资源用量分析实战

2026-09-06 11:26:31作者:翟江哲Frasier

etcd 的持续集成构建在 Kubernetes Prow 之上,本文基于仓库内 prow_jobs.md 的贡献者指南,系统讲解 etcd 的 Prow 作业分类(presubmit/postsubmit/periodic)、如何通过 /ok-to-test/retest 命令触发测试、Grafana 构建资源看板的使用方法,并结合本仓库的 Makefilescripts/test.sh 源码,说明每个 Prow 作业名背后实际执行的具体测试入口与参数,帮助你既看懂 CI 看板,也能在本地复现同样的测试链路。

1. Prow 是什么,etcd 的 CI 为何依赖它

Prow 是一套基于 Kubernetes 的 CI/CD 系统:作业可由多种事件触发,并将状态汇报给多个不同服务。它通过 GitHub 自动化能力实现策略执行与 chat-ops 交互——贡献者可以直接在 Pull Request 评论中通过 /test/approve/retest/command 触发作业、管理工作流。

当用户在 PR 上评论 /ok-to-test/retest 时,GitHub 会将 webhook 发送到 Prow 所在的 Kubernetes 集群,由 Prow 拉起对应的构建作业。etcd 的 CI 由 kubernetes/test-infra 仓库托管的 Prow 实例运行,所有 etcd 的 Prow 作业状态都可以在 Prow 官方状态页(按 repo=etcd-io/etcd 过滤)查询。

从仓库文档 triage_prs.md 也可以印证这一流程:etcd 项目使用 Kubernetes Prow 和 GitHub Actions 运行测试,若 PR 已就绪测试但仍带有 needs-ok-to-test 标签,需要评论 /ok-to-test 才会执行全部必需测试。

2. etcd 的 Prow 作业类型与配置文件

etcd 的作业配置位于 test-infra 仓库的 config/jobs/etcd 目录下,按作业类型拆分为多个 YAML 文件。etcd 共有三类作业(presubmit、postsubmit、periodic),各配置文件及其职责如下:

配置文件(test-infra: config/jobs/etcd) 类型 职责
etcd-benchmarks-periodic.yaml recurring/periodic 定期运行 etcd 性能基准,专门针对 put API、amd64 架构
etcd-presubmits.yaml presubmit 在 PR 合并前运行:构建 main 与所有 release 分支,确保新变更不破坏构建与测试
etcd-postsubmits.yaml postsubmit 代码合并进 etcd-io/etcd 的 main 或 release 分支后自动运行
etcd-periodics.yaml periodic 按计划周期(如每 4 小时、每天一次)自动运行,不依赖代码变更或 PR,持续检验项目的稳定性、兼容性与性能
etcd-operator-presubmits.yaml / etcd-operator-postsubmits.yaml presubmit / postsubmit etcd-io/etcd-operator 仓库的合并前/合并后作业
etcd-raft-presubmits.yaml presubmit 在 main 与 release-3.6 分支上测试 etcd-io/raft 仓库的 PR
etcd-website-presubmits.yaml presubmit 检查 website 变更的 markdown 格式
protodoc-postsubmits.yaml / protodoc-presubmits.yaml postsubmit / presubmit etcd-io/protodoc 仓库的合并后/合并前作业

以一个真实作业为例:pull-etcd-e2e-amd64 是 presubmit 之一,针对 etcd 仓库 main、release-3.6、release-3.5、release-3.4 分支上的每个 PR,自动在 amd64 架构上运行端到端(e2e)测试。其历史执行结果可在 Prow 状态页按 type=presubmit&job=pull-etcd-e2e-amd64 过滤查看。

如何通过评论触发 Prow 测试

以下命令在 PR 上留言即可触发:

  • /ok-to-test:允许 Prow 对首次贡献者(first-time contributor)的 PR 运行测试(该权限通常由 etcd-io 成员授予);
  • /retest:让 Prow 重跑该 PR 上失败或不稳定(flaky)的作业,适用于因瞬时问题导致的失败。

完整的受支持命令列表见 Prow 官方的 command-help 页面。

3. Prow 作业名到仓库测试入口的映射(源码级解读)

Prow 作业名(如 pull-etcd-e2e-amd64pull-etcd-robustness)背后的实际执行逻辑,都收敛在仓库根目录 Makefilescripts/test.sh 中。理解这层映射,就能在看板上看到的作业名与仓库代码之间建立对应关系。

3.1 测试通道(pass)总览

scripts/test.sh 通过 PASSES 环境变量选择测试通道,默认为 bom dep build unit(见 scripts/test.sh#L76)。每个通道对应一个 xxx_pass 函数,Prow 作业本质上就是带着不同 PASSES 值调用该脚本:

测试通道 Makefile 目标 实际执行的测试包与关键参数
unit make test-unit 全 workspace 模块 -short -failfast -timeout=3m,amd64/arm64 自动加 --racescripts/test.sh#L131-L139
integration make test-integration ./tests/integration/..../tests/common/...-tags=integration),-p=2 -failfast -timeout=15m,另追加 ./tests/integration/v2store/...scripts/test.sh#L153-L172
e2e make test-e2e make build 构建二进制,再跑 ./tests/e2e/...-timeout=30m)与 ./tests/common/...-tags=e2e);注意 e2e 使用预构建二进制,--race/-cover 等编译期参数无效(scripts/test.sh#L174-L186
robustness make test-robustness ./tests/robustness-timeout=30mscripts/test.sh#L188-L194
coverage make test-coverage COVERDIR=covdir PASSES="build cov",汇总 unit + integration 各子集的 coverprofile 后合并出 all.coverprofilescripts/test.sh#L287-L344

几个值得注意的脚本级细节:

  • 脚本顶部强制 export GOFLAGS=-mod=readonlyset -e / pipefail / nounset,即测试过程不允许悄悄改动 go.mod/go.sum,任何依赖漂移都会直接判失败(scripts/test.sh#L50-L61);
  • 细粒度调试支持 PKGTESTCASETIMEOUT 组合,例如 PASSES=unit PKG=./wal TESTCASE=TestNew TIMEOUT=1m ./scripts/test.sh
  • KEEP_GOING_SUITE=true 可让某个 suite 失败后继续执行后续 suite。

3.2 静态检查(verify)通道

Makefile#L102-L106 中的 make verify 聚合了一整串静态检查,这正是 presubmit 中 pull-etcd-verifypull-etcd-lintpull-etcd-unit 这类"快速确定性检查"作业的内容:

verify: verify-bom verify-lint verify-dep verify-shellcheck verify-mod-tidy \
    verify-shellws verify-proto-annotations verify-genproto verify-yamllint \
    verify-markdown-marker verify-go-versions verify-gomodguard \
    verify-go-workspace verify-grpc-experimental

逐项含义:verify-bom 校验许可证物料清单 bill-of-materials.jsonverify-lint 用 golangci-lint(配置 tools/.golangci.yaml)检查代码;verify-dep 检查各 Go 模块间依赖版本一致性(scripts/test.sh#L482-L500);verify-shellcheckscripts/*.sh 做 shellcheck;verify-mod-tidygo mod tidy -diff 检测 go.mod 漂移;verify-genproto 校验 protobuf 生成代码是否最新;verify-yamllintverify-markdown-marker 检查 YAML 与 Markdown 链接格式。这些检查快速且确定性强,构成昂贵的 e2e/robustness 测试之前的快速反馈环。

3.3 Robustness 作业与故障注入(failpoint)

Prow 文档将 robustness 作业归类为"长时运行、故障注入/混沌风格的端到端测试",用于在节点崩溃、网络分区、资源耗尽、版本升级等故障下验证 etcd 的正确性与可用性。etcd 的 robustness 测试框架在 tests/robustness/README.md 中有完整说明:其核心是把真实集群的客户端操作历史与"期望行为模型"比对,任何偏差都会生成详细报告。

本地复现 CI 上 robustness 作业的步骤(摘自该 README):

# 1. 构建带 failpoint 的 etcd
make gofail-enable
make build
make gofail-disable

# 2. 运行 robustness 测试
make test-robustness

常用环境变量:GO_TEST_FLAGS(追加 go test 参数,README 建议 GO_TEST_FLAGS='--count=100 --failfast' 多次运行)、EXPECT_DEBUG=true(输出集群日志)、RESULTS_DIR(报告目录)、PERSIST_RESULTS(成功时也保留报告)、TRACING_SERVER_ADDR(导出 OpenTelemetry 链路)。

tests/robustness/Makefile 进一步展示了 CI 上 robustness 作业的实际形态:gofail-enable 会对特定目录打 failpoint(server/etcdserver/server/leaseserver/lease/leasehttpserver/storage/backend/server/storage/mvcc/server/storage/wal/server/etcdserver/api/v3rpc/server/etcdserver/api/membership/server/etcdserver/api/rafthttp/,见 tests/robustness/Makefile#L103-L109);test-robustness-maintest-robustness-release-3.7 等目标则通过 --bin-dir--bin-last-release 参数组合"当前分支 + 上一版本"的二进制,模拟跨版本恢复/升级场景。此外还有一批 test-robustness-issue* 目标(如 test-robustness-issue14370)用于在特定历史提交上回归复现已发现的正确性缺陷——该 README 中的 track record 表格记录了十余个由 robustness 与 Antithesis 发现的真实一致性问题(如崩溃期间 revision 不一致、网络分区后 watch 事件回退等)。

3.4 定期基准作业(periodic benchmarks)

Prow 文档提到 recurring 作业定期在 amd64 上针对 put API 运行性能基准。对应仓库入口是 Makefile#L20-L23bench-put

make bench-put   # 等价于 make build install-benchmark 后执行 ./scripts/benchmark_test.sh put

scripts/benchmark_test.sh 的完整流程是:在 /tmp/etcd 下创建临时数据目录启动本地 etcd → 用 etcdctl endpoint health --cluster 轮询确认健康(最多 10 次)→ 调用 tools/benchmark 的 put 基准,并固定追加 --report-perfdash 参数输出 perfdash 格式结果(scripts/benchmark_test.sh#L22scripts/benchmark_test.sh#L46-L64)。基准完成后 trap 会负责杀进程并清理数据目录。perfdash 报告格式由仓库内 pkg/report/perfdash.go 定义,这正是 Prow 定期作业能持续追踪 put 性能趋势的数据来源。

3.5 发布链路(release)相关的 CI 行为

scripts/test.sh#L562-L588 中的 release_tests_pass 展示了 CI 特有的行为:当检测到 CI 环境变量(即运行在 Prow 中)时,脚本会配置 git 身份为 Prow <prow@etcd.io>、生成 GPG 签名密钥、添加 remote,然后以 DRY_RUN=true 执行 scripts/release.sh--no-upload --no-docker-push --no-gh-release --in-place)并运行 scripts/test_images.sh 验证产物。本地可通过 make test-release 触发同样的链路。

4. 使用 Grafana 看板分析 Prow 作业资源用量

test-infra 的 Prow 暴露了 Grafana 看板,用于观察 Prow 构建集群上 Kubernetes 作业的资源用量(CPU、内存、运行中构建数等)。看板按组织(organization)、仓库(repository)、构建标识(build identifier)和时间范围四类过滤器限定范围。etcd 有两个集群的看板,查询参数为:

过滤器参数 取值
var-org etcd-io
var-repo etcd
var-build All(可改为具体作业名)
from / to now-7d / now(近 7 天)
refresh 30s

分别对应 GKE 与 EKS 两个监控域名(monitoring-gke.prow.k8s.iomonitoring-eks.prow.k8s.io 下的 builds 看板)。分析资源用量主要有四个用途:

  1. 资源调参:深入每次构建运行,确定该类型作业真实的内存与 CPU requests/limits,既避免浪费,也避免构建因触顶资源限制而失败;
  2. 发现异常:若某次构建突然用了 8 GiB 而该作业平常只用 1 GiB,可能意味着回归或配置错误;
  3. 容量规划:观察典型与峰值用量,帮助集群运维规划节点规格、调度策略与构建并发度;
  4. 性能问题排障:CPU 或内存异常偏高的构建可能卡住、死循环或低效消耗资源。

看板面板解读

"Running / Pending Builds" 面板:展示 Running 与 Pending 状态构建数量随时间的变化。用来跟踪构建积压与并发度——"Pending" 曲线抬升说明构建在排队等资源;"Running" 曲线的波动或稳定值可推断通常有多少构建并行运行。

"Memory Usage per Build" 面板:按构建 ID(图例中逐条列出)展示内存用量随时间的变化,纵轴为内存(MiB/GiB)。用来发现内存异常偏高的构建——出现尖峰说明某次构建消耗了大量资源。

"CPU Usage per Build" 面板:结构同上,展示每个构建的 CPU 用量。CPU 尖峰可能意味着重计算任务、低效实现或需要资源调参。

"Resources" 面板(Memory 子面板)

  • 绿线("used"):该构建 Pod 在各时间点的实际内存使用量;
  • 橙/黄线("requested"):Pod 申请的内存(Kubernetes requests.memory);
  • 红线("limit"):Pod 的内存上限(Kubernetes limits.memory);
  • 纵轴为内存(GiB/MiB),横轴为时间。

判读规则:绿色 used 线贴近或触及红色 limit 线,说明构建接近内存上限,有 OOM 风险;used 明显低于 requested,说明内存申请过度(浪费);requested 远高于 used,则建议下调该作业的 request 值。

"Resources" 面板(CPU 子面板):结构相同——绿色为实际使用,橙/黄为申请值,红色为 CPU limit(若设置)。纵轴常以 CPU 核数或其分数表示(1.0 = 一个核)。绿色曲线出现尖峰通常对应构建/编译阶段,空闲期则低平。若 CPU 使用持续打满 limit,作业可能被限流(throttled)或延迟;若持续远低于 request,下调即可降本。

5. Prow 作业分类:静态检查、Robustness、Integration

Prow 文档将 etcd 的作业按性质分为三大类,各类的定位与运行时机如下:

  • 静态检查(Static check)

    • 定义:快速、确定性的检查(构建、单元测试、linter、go vet/staticcheck、格式化、license/header 检查、生成代码校验),尽早暴露风格、正确性与打包问题;
    • 运行时机:每个 PR 作为 presubmit;在跑昂贵测试之前提供快速反馈;
    • 示例作业模式:pull-etcd-verifypull-etcd-lintpull-etcd-unit
    • 对应仓库入口即 Makefileverify/test-unit 链路(见本文 3.1、3.2 节)。
  • Robustness(健壮性)

    • 定义:长时运行的故障注入/混沌风格端到端测试,验证 etcd 在故障(节点崩溃、网络分区、资源耗尽、升级)下的正确性与可用性;
    • 运行时机:periodic 提供持续覆盖;针对共识、存储、恢复或升级路径的 PR 应当运行;
    • 示例作业模式:pull-etcd-robustnessperiodic-robustness
    • 仓库入口:make test-robustnesstests/robustness/Makefile 中按分支定义的 failpoint 构建目标。
  • Integration(集成)

    • 定义:功能性端到端与跨组件测试,覆盖真实 client/server 交互、快照/恢复、升级及跨操作系统/架构的兼容性;
    • 运行时机:改动 API、客户端行为或集成点的 PR 走 presubmit;periodic 提供广平台覆盖;
    • 示例作业模式:pull-etcd-e2e-amd64pull-etcd-integration
    • 仓库入口:make test-integration / make test-e2e(见本文 3.1 节参数表)。

6. 解读 Prow 指标(Prometheus Metrics)

Prow 的多个组件暴露了 Prometheus 指标,可用于监控与告警,例如每个 Tide 池中 PR 的数量、每次合并中 PR 数量的直方图等。指标清单可在 Prow 官方文档的 metrics 章节(kubernetes-sigs/prow 的 site/content/en/docs/metrics)查阅。对于 etcd 维护者,结合第 4 节的 Grafana 资源看板与第 2 节的作业状态页,即可覆盖"作业是否通过"与"资源是否健康"两个维度的日常巡检。

7. 从 Prow 作业页获取测试产物(以 Robustness 报告为例)

Prow 作业执行页会提供测试产物(Artifacts),这是排障的关键入口。以 robustness 测试为例,tests/robustness/README.md 给出的流程是:进入 Prow 作业运行页 → 下载 artifacts/results.zip → 解压后按 TestRobustness 前缀目录定位失败场景(通常体积最大的目录对应失败场景)→ 将报告目录拷入 tests/robustness/testdata → 运行 make test-robustness-reports 重新校验。该目录中的 Makefile 目标 tests/robustness/Makefile#L3-L6 实际执行 go test ./robustness/validate --run TestDataReports。Prow 作业运行页与产物页的实际界面如下:

Prow 作业运行页面,展示构建状态与日志入口

Prow 作业产物页面,展示 results.zip 等可下载的 Artifacts 列表

注意:robustness 报告格式并不稳定,默认仅失败的测试会生成报告;使用最新版本重新评估旧报告时,不能保证所有历史报告都可重新校验。

8. 小结:作业名、入口与看板的完整链路

把本文信息串起来,etcd 一个 Prow 作业的生命周期是:test-infra 的 config/jobs/etcd/*.yaml 声明作业(presubmit/postsubmit/periodic)→ GitHub 事件或 /ok-to-test/retest 评论触发 → 作业容器内调用 Makefile 的对应目标(test-unittest-integrationtest-e2etest-robustnessbench-putverify 等)→ 最终执行 scripts/test.sh 的各 pass 函数或 scripts/benchmark_test.sh → 结果回报 Prow 状态页,日志与产物(如 robustness 的 results.zip)挂在作业页,资源用量进入 Grafana 看板供调参与容量规划。掌握这条链路后,无论是阅读 CI 失败日志、本地复现某个 Prow 作业,还是调整作业资源配置,都能直接定位到仓库内的确切代码位置。

登录后查看全文
热门项目推荐
相关项目推荐