Prow 生态系统架构全景:test-infra、prow-configs、prow-images、cimaster 四大项目关系深度解析
Prow 生态系统架构全景
本文深入解析 eBay Tess CI/CD 系统的四个核心项目:test-infra、prow-configs、prow-images、cimaster,通过架构图和流程图展示它们之间的依赖关系与协作方式。
一、四大项目概览
| 项目 | 仓库 | 定位 | 核心产物 |
|---|---|---|---|
| test-infra | tess/test-infra |
Prow 框架源码(fork 自 kubernetes/test-infra) | Prow 组件二进制:hook、plank、deck、manual-trigger 等 |
| prow-configs | tessops/prow-configs |
Prow 运行时配置 + Job 定义 | config.yaml、plugins.yaml、所有 ProwJob YAML |
| prow-images | tess-contrib/prow-images |
CI 任务用的工具镜像集合 | kaniko、e2e、golang、tess-build 等镜像 |
| cimaster | tess-contrib/cimaster |
E2E 测试集群资源管理器 | cimaster HTTP 服务,管理测试集群的分配与回收 |
二、项目关系总图
1 | ┌──────────────────────────────────────────────────────────────────────────────────────┐ |
三、静态依赖关系图
graph TB
subgraph test-infra["test-infra(Prow 框架源码)"]
hook["hook
处理 GitHub 事件"]
plank["plank
ProwJob 调度器"]
deck["deck
Web UI"]
manual["manual-trigger
手动触发 HTTP API"]
clonerefs["pod-utils
clonerefs/sidecar 等"]
end
subgraph prow-configs["prow-configs(运行时配置)"]
config["config.yaml
全局 Prow 配置"]
plugins["plugins.yaml
插件配置"]
jobs["jobs/**/*.yaml
所有 Job 定义"]
presets["config.presets.yaml
通用 Preset"]
end
subgraph prow-images["prow-images(工具镜像)"]
kaniko["kaniko
构建/推送镜像"]
e2e["e2e
E2E 测试框架"]
golang["golang
Go 编译环境"]
tessbuild["tess-build
Tess 构建工具"]
release["create-release
自动打 Tag/发布"]
validator["prow-config-validator
配置校验"]
cigen["ci-generator
Job 自动生成"]
end
subgraph cimaster["cimaster(集群资源管理)"]
api["HTTP API
:8080"]
mgr["ClusterManager
分配/回收/持有"]
configmap["K8s ConfigMap
集群状态池"]
end
%% prow-configs 被 test-infra 读取
config -->|"ConfigAgent 加载"| hook
config -->|"ConfigAgent 加载"| plank
config -->|"ConfigAgent 加载"| deck
config -->|"ConfigAgent 加载"| manual
plugins -->|"PluginAgent 加载"| hook
jobs -->|"Job 定义"| plank
%% prow-images 被 Job 使用
kaniko -.->|"ProwJob spec.containers.image"| jobs
e2e -.->|"ProwJob spec.containers.image"| jobs
tessbuild -.->|"ProwJob spec.containers.image"| jobs
release -.->|"ProwJob spec.containers.image"| jobs
%% cimaster 使用 manual-trigger 创建集群
api -->|"POST /manual-trigger"| manual
mgr --> api
configmap --> mgr
%% e2e 镜像与 cimaster 交互
e2e -->|"GET /getvacant 申请集群"| api
e2e -->|"GET /finishtest 释放集群"| api
%% prow-configs validator 使用 test-infra 逻辑
validator -.->|"引用 prow/config 包"| test-infra
style test-infra fill:#dbeafe,stroke:#3b82f6
style prow-configs fill:#dcfce7,stroke:#22c55e
style prow-images fill:#fef9c3,stroke:#eab308
style cimaster fill:#fce7f3,stroke:#ec4899
四、端到端流程:一次 E2E 测试的完整生命周期
4.1 流程总图
sequenceDiagram
participant Dev as 开发者
participant GH as GitHub
participant Hook as hook
(test-infra)
participant Plank as plank
(test-infra)
participant Pod as E2E Pod
(prow-images/e2e)
participant CI as cimaster
participant CM as K8s ConfigMap
(集群池)
participant Manual as manual-trigger
(test-infra)
Dev->>GH: 提交 PR
GH->>Hook: GitHub Webhook
(pull_request event)
Hook->>Hook: 查找 prow-configs/jobs 中的 presubmit jobs
Hook->>Plank: 创建 ProwJob CRD
(e2e-test)
Plank->>Pod: 启动 Pod
image: hub.tess.io/prowimages/e2e:latest
Note over Pod: InitContainers 运行
clonerefs 克隆代码
Pod->>CI: GET /getvacant?build=123&job=e2e-test
CI->>CM: 查询空闲集群
CM-->>CI: 返回 cluster-01
CI->>CM: 标记 cluster-01 为 testing
CI-->>Pod: 返回 "cluster-01"
Note over Pod: 在 cluster-01 上运行 E2E 测试
Pod->>CI: GET /finishtest?cluster=cluster-01
CI->>CM: 标记 cluster-01 为 finished
Pod-->>Plank: 任务完成 (exit 0)
Plank->>GH: 上报 CI 结果 ✅
GH-->>Dev: PR Check 通过
4.2 手动触发 + 集群创建流程
sequenceDiagram
participant User as 用户/运维
participant CI as cimaster
participant Manual as manual-trigger
(test-infra)
participant Plank as plank
(test-infra)
participant Pod as 集群创建 Pod
(prow-images/tess-build)
participant CM as K8s ConfigMap
User->>CI: GET /createcluster?user=john&branch=master
CI->>Manual: POST /manual-trigger
{"org":"tess","repo":"tessops","prowjob":"sddz-e2e-k8s-1.32","user":"john"}
Manual->>Manual: 在 prow-configs 中查找
"sddz-e2e-k8s-1.32" 任务定义
Manual->>Plank: 创建 ProwJob CRD
Plank->>Pod: 启动集群创建 Pod
image: hub.tess.io/prowimages/tess-build:latest
Note over Pod: 执行集群创建脚本
创建新的 Tess 集群
Pod-->>Plank: 完成 (exit 0)
User->>CI: GET /addcluster?cluster=new-cluster®ion=us-west&name=admin
CI->>CM: 将新集群加入集群池
CM-->>CI: 写入成功
CI-->>User: "cluster new-cluster is added successfully"
五、各项目内部结构详解
5.1 test-infra 项目结构
1 | test-infra/ |
核心职责: 提供 Prow 框架的所有运行时二进制和Go 库。
5.2 prow-configs 项目结构
1 | prow-configs/ |
核心职责: 定义什么任务在什么时机运行(Job 配置)以及 Prow 如何行为(全局配置)。
5.3 prow-images 项目结构
1 | prow-images/ |
核心职责: 提供 ProwJob Pod 中运行的工具镜像,每个镜像对应一种 CI 能力。
5.4 cimaster 项目结构
1 | cimaster/ |
核心职责: 维护一个共享 E2E 测试集群资源池,通过 HTTP API 提供集群的申请、释放、持有、创建能力。
六、配置流向图
prow-configs 如何影响各个 Prow 组件:
graph LR
subgraph prow-configs
C[config.yaml]
P[plugins.yaml]
J[jobs/**/*.yaml]
PR[config.presets.yaml]
end
subgraph test-infra 运行时
Hook["hook
(处理 Webhook)"]
Plank["plank
(调度 Job)"]
Deck["deck
(展示 UI)"]
Tide["tide
(合并 PR)"]
MT["manual-trigger
(手动触发)"]
end
C -->|"plank/tide/deck 行为配置"| Plank
C -->|"tide 合并策略"| Tide
C -->|"deck 展示配置"| Deck
C -->|"job 查询"| MT
P -->|"trigger/lgtm/approve 插件"| Hook
J -->|"presubmit/postsubmit 定义"| Hook
J -->|"PowJob spec.PodSpec 来源"| Plank
PR -->|"Preset env/volumes 注入"| Plank
style prow-configs fill:#dcfce7
style test-infra 运行时 fill:#dbeafe
七、镜像引用关系图
prow-images 中各镜像的依赖层级:
graph BT
Base["hub.tess.io/tess/ubuntu-22.04:hardened
(基础系统镜像)"]
CloneAndDo["clone-and-do
通用克隆+执行"]
Golang["golang:1.21~1.24
Go 编译环境"]
TessBuild["tess-build
含 git-crypt"]
E2E["e2e
含 tessci + e2e.sh"]
Kaniko["kaniko
镜像构建工具"]
Release["create-release
Git Release 工具"]
Validator["prow-config-validator
配置校验"]
CIGen["ci-generator
Job 生成器"]
Base --> CloneAndDo
CloneAndDo --> Golang
Golang --> TessBuild
Golang --> E2E
Golang --> Kaniko
Golang --> Release
Golang --> Validator
Golang --> CIGen
style Base fill:#f3f4f6
style CloneAndDo fill:#fef9c3
style Golang fill:#fef9c3
style TessBuild fill:#fef3c7
style E2E fill:#fde68a
style Kaniko fill:#fde68a
style Release fill:#fde68a
八、cimaster 集群状态机
stateDiagram-v2
[*] --> finished: addcluster (管理员添加)
finished --> testing: getvacant (测试任务申请)
testing --> finished: finishtest (测试完成)
testing --> held: holdcluster (暂时持有)
held --> finished: releasecluster (释放持有)
held --> finished: 自动过期 (6小时后)
finished --> disabled: disablecluster (管理员禁用)
disabled --> finished: enablecluster (管理员启用)
finished --> [*]: deletecluster (管理员删除)
九、完整 CI 任务数据流
从代码提交到 CI 结果的完整数据链路:
1 | ┌──────────────────────────────────────────────────────────────────────────────┐ |
十、项目协作矩阵
| 动作 | test-infra | prow-configs | prow-images | cimaster |
|---|---|---|---|---|
| 定义 Prow 框架组件 | ✅ 实现 | - | - | - |
| 定义 Job 触发规则 | - | ✅ 定义 | - | - |
| 提供 Job 运行镜像 | - | 引用镜像 URL | ✅ 构建 | - |
| 管理 E2E 测试集群 | - | - | 调用 API | ✅ 实现 |
| 触发集群创建 Job | 提供 API | 定义 Job | 执行构建 | 调用 API |
| 校验 prow-configs | 提供 Go 库 | ✅ 被校验 | 校验工具镜像 | - |
| 自动生成 Job YAML | - | ✅ 存储 | 生成器镜像 | - |
十一、关键接口汇总
test-infra ↔ prow-configs
- 接口: 文件系统 / Kubernetes ConfigMap
- 方向: prow-configs → test-infra
- 内容:
config.yaml(ConfigAgent)、plugins.yaml(PluginAgent)、Job YAML(PresubmitsStatic/PostsubmitsStatic)
test-infra ↔ prow-images
- 接口: Docker 镜像引用(字符串)
- 方向: prow-images → ProwJob spec → plank
- 内容:
hub.tess.io/prowimages/<name>:latest
cimaster ↔ test-infra (manual-trigger)
- 接口: HTTP REST API
- 方向: cimaster → manual-trigger
- 内容:
1
2
3
4
5
6
7
8
9POST https://prow.tess.io/manual-trigger
{
"org": "tess",
"repo": "tessops",
"base_ref": "master",
"prowtype": "postsubmit",
"prowjob": "sddz-e2e-k8s-1.32",
"user": "john"
}
prow-images/e2e ↔ cimaster
- 接口: HTTP REST API
- 方向: e2e Pod → cimaster
- 内容:
1
2GET http://cimaster.tess.io/getvacant?build=123&job=e2e-test
GET http://cimaster.tess.io/finishtest?cluster=cluster-01
cimaster ↔ Kubernetes ConfigMap
- 接口: Kubernetes API
- 方向: 双向读写
- 内容:
ci/clustersConfigMap,存储集群池状态 JSON
十二、总结
这四个项目构成了一个完整的 CI/CD 闭环:
1 | prow-configs ──定义Job──→ test-infra ──调度──→ Pod (prow-images镜像) |
- test-infra: 系统的大脑——框架、调度、编排
- prow-configs: 系统的配置中枢——Job 定义、行为规则
- prow-images: 系统的工具箱——各种 CI 能力封装为镜像
- cimaster: 系统的资源管家——E2E 集群资源的统一调度
作者: Tashen
日期: 2026-04-17
标签: #Kubernetes #Prow #CI/CD #DevOps #架构