etcd Prow CI 作业体系:作业类型、测试触发方式与资源用量分析实战
etcd 的持续集成构建在 Kubernetes Prow 之上,本文基于仓库内 prow_jobs.md 的贡献者指南,系统讲解 etcd 的 Prow 作业分类(presubmit/postsubmit/periodic)、如何通过 /ok-to-test 与 /retest 命令触发测试、Grafana 构建资源看板的使用方法,并结合本仓库的 Makefile 与 scripts/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-amd64、pull-etcd-robustness)背后的实际执行逻辑,都收敛在仓库根目录 Makefile 与 scripts/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 自动加 --race(scripts/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=30m(scripts/test.sh#L188-L194) |
| coverage | make test-coverage |
COVERDIR=covdir PASSES="build cov",汇总 unit + integration 各子集的 coverprofile 后合并出 all.coverprofile(scripts/test.sh#L287-L344) |
几个值得注意的脚本级细节:
- 脚本顶部强制
export GOFLAGS=-mod=readonly并set -e / pipefail / nounset,即测试过程不允许悄悄改动go.mod/go.sum,任何依赖漂移都会直接判失败(scripts/test.sh#L50-L61); - 细粒度调试支持
PKG、TESTCASE、TIMEOUT组合,例如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-verify、pull-etcd-lint、pull-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.json;verify-lint 用 golangci-lint(配置 tools/.golangci.yaml)检查代码;verify-dep 检查各 Go 模块间依赖版本一致性(scripts/test.sh#L482-L500);verify-shellcheck 对 scripts/*.sh 做 shellcheck;verify-mod-tidy 以 go mod tidy -diff 检测 go.mod 漂移;verify-genproto 校验 protobuf 生成代码是否最新;verify-yamllint、verify-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/lease、server/lease/leasehttp、server/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-main、test-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-L23 的 bench-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#L22、scripts/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.io 与 monitoring-eks.prow.k8s.io 下的 builds 看板)。分析资源用量主要有四个用途:
- 资源调参:深入每次构建运行,确定该类型作业真实的内存与 CPU requests/limits,既避免浪费,也避免构建因触顶资源限制而失败;
- 发现异常:若某次构建突然用了 8 GiB 而该作业平常只用 1 GiB,可能意味着回归或配置错误;
- 容量规划:观察典型与峰值用量,帮助集群运维规划节点规格、调度策略与构建并发度;
- 性能问题排障: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-verify、pull-etcd-lint、pull-etcd-unit。 - 对应仓库入口即 Makefile 的
verify/test-unit链路(见本文 3.1、3.2 节)。
-
Robustness(健壮性)
- 定义:长时运行的故障注入/混沌风格端到端测试,验证 etcd 在故障(节点崩溃、网络分区、资源耗尽、升级)下的正确性与可用性;
- 运行时机:periodic 提供持续覆盖;针对共识、存储、恢复或升级路径的 PR 应当运行;
- 示例作业模式:
pull-etcd-robustness、periodic-robustness; - 仓库入口:
make test-robustness及 tests/robustness/Makefile 中按分支定义的 failpoint 构建目标。
-
Integration(集成)
- 定义:功能性端到端与跨组件测试,覆盖真实 client/server 交互、快照/恢复、升级及跨操作系统/架构的兼容性;
- 运行时机:改动 API、客户端行为或集成点的 PR 走 presubmit;periodic 提供广平台覆盖;
- 示例作业模式:
pull-etcd-e2e-amd64、pull-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 作业运行页与产物页的实际界面如下:
注意:robustness 报告格式并不稳定,默认仅失败的测试会生成报告;使用最新版本重新评估旧报告时,不能保证所有历史报告都可重新校验。
8. 小结:作业名、入口与看板的完整链路
把本文信息串起来,etcd 一个 Prow 作业的生命周期是:test-infra 的 config/jobs/etcd/*.yaml 声明作业(presubmit/postsubmit/periodic)→ GitHub 事件或 /ok-to-test、/retest 评论触发 → 作业容器内调用 Makefile 的对应目标(test-unit、test-integration、test-e2e、test-robustness、bench-put、verify 等)→ 最终执行 scripts/test.sh 的各 pass 函数或 scripts/benchmark_test.sh → 结果回报 Prow 状态页,日志与产物(如 robustness 的 results.zip)挂在作业页,资源用量进入 Grafana 看板供调参与容量规划。掌握这条链路后,无论是阅读 CI 失败日志、本地复现某个 Prow 作业,还是调整作业资源配置,都能直接定位到仓库内的确切代码位置。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00

