理解 Prow-Images 生态系统:大规模 Kubernetes CI/CD 构建实践

引言

prow-images 仓库是基于 Kubernetes Prow 构建的复杂 CI/CD 基础设施的核心组件。它作为专用容器镜像的集中式集合,为持续集成和交付流水线的各个方面提供动力。本文将深入探讨 prow-images 生态系统的架构、组件和工作流程,特别关注它与 prow-configs 仓库和 manual-trigger 服务之间的关系。

什么是 prow-images?

prow-images 仓库是一个包含超过 35 个不同专用容器镜像的单体仓库(monorepo),每个镜像都设计用于处理 Prow 作业中的特定任务。这些镜像从基本实用工具(如 Git 操作)到复杂工具(如 E2E 测试框架、Kubernetes 集群配置和自动安全 PR 生成)应有尽有。

仓库结构

仓库中的每个组件都遵循一致的结构:

  • 用于构建容器镜像的 Dockerfile
  • 跟踪当前版本的 VERSION 文件(例如 v0.0.1
  • 包含基于 Go 的主应用程序的 entrypoint 目录
  • 组件特定的 README 文档

根目录的 Makefile 负责协调所有镜像的构建和推送到中央镜像仓库 hub.tess.io/prowimages/

核心组件

让我们深入了解组成这个生态系统的一些关键组件:

1. CI Generator - 配置自动化引擎

CI Generator 是生态系统中最关键的组件之一。它从简化的清单文件自动生成 Prow 作业规范。

主要特性:

  • 从 prow-configs 仓库读取 .manifest 文件
  • 支持多种作业生成类型:BuildUnitTest
  • 自动生成 presubmit 和 postsubmit 作业配置
  • 处理与 Kaniko 集成的复杂构建场景

工作原理:

  1. 开发者在 prow-configs 中的仓库作业目录中创建 ci.manifest 文件
  2. CI Generator 读取这些清单文件并生成完整的 Prow 作业 YAML 规范
  3. 生成的文件会自动标记头部信息:”此文件由 ci generator 自动生成,请勿手动编辑”
  4. 作业可以配置不同的触发器:PR 时 (onPr)、标签时 (onTag),支持正则表达式模式

清单示例片段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
tess/maintenance:
- jobGenType: Build
name: build-maintenance-controller
branch: master
dockerFile: Dockerfile
versionFile: VERSION
buildTime: kaniko
targets:
- onPr:
imageTags:
- hub.tess.io/maintenance/maintenance-controller:pr-${PULL_NUMBER}
- onTag:
tagRegex:
- ^v(\d)+\.(\d)+\.(\d)+
imageTags:
- hub.tess.io/maintenance/maintenance-controller:${PULL_BASE_REF}

2. Kaniko - 安全的容器构建

Kaniko 镜像包装器提供了一种在 Kubernetes Pod 中安全构建容器镜像的方式,无需访问 Docker 守护进程。

功能:

  • 支持可配置深度的 Git 仓库克隆
  • 支持 git-crypt 加密仓库
  • 多个目标镜像仓库
  • 构建参数和标签
  • 镜像仓库镜像支持
  • TLS 验证选项
  • 自动向 GitHub PR 发送构建结果评论
  • 构建后命令执行

在 Prow 作业中的使用模式:

1
2
3
4
5
6
7
8
spec:
containers:
- image: hub.tess.io/prowimages/kaniko:latest
args:
- --dockerfile=Dockerfile
- --context=/workspace/repo
- --destination=hub.tess.io/myapp:${PULL_NUMBER}
- --build-arg=VERSION=${VERSION}

3. Kind - Docker 中的 Kubernetes 测试环境

Kind 镜像能够在 CI 流水线中创建临时 Kubernetes 集群用于 E2E 测试。

特性:

  • 创建隔离的 Kubernetes 集群
  • 支持多个 Kubernetes 版本(1.20、1.32、1.34)
  • 与上游 Kubernetes 补丁集成
  • 可脚本化的集群配置
  • 自动清理

4. Auto Security PR - 自动化 RBAC 管理

这个专用工具自动化创建跨多个集群的安全相关 RBAC 资源的拉取请求。

工作流程:

  1. 在 YAML 中定义 RBAC 资源(ClusterRoles、ServiceAccounts、ClusterRoleBindings)
  2. 指定作用域:fcpclustertessAppsAZtessNetAZtessMasterAZ
  3. 针对特定集群或使用 all: true 针对作用域中的所有集群
  4. 该工具生成并提交 PR 到 sig-security 仓库

使用示例:

1
2
3
4
5
6
7
8
9
10
clusterRoles:
- metadata:
name: cluster-role-1
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
scope:
cluster:
all: true

5. Auto Approval/Validation - PR 自动化

这些组件处理拉取请求的自动批准和验证:

  • Auto Approval:当特定文件包含某些键值对时自动批准 PR
  • Auto Validation:验证 PR 更改的不可变性和 Kubernetes 对象的正确性

6. E2E 测试套件

多个 E2E 测试镜像提供全面的测试能力:

  • e2e:通用 E2E 测试的基础镜像
  • fd-e2e:专门用于功能开发 E2E 测试
  • tessci:用于 E2E 测试的集群获取和管理工具

7. 构建工具集合

各种专业的构建工具:

  • Bazel:多个版本(3.4.1、4.2.2、7.3.1、7.7.1)用于 Bazel 构建
  • Go:标准化的 Golang 构建环境
  • Ko:Go 容器镜像构建器
  • Buildctl:BuildKit CLI 包装器
  • Python:Python 运行时环境(3.8.15、3.14.0)

8. Git 操作

Git 相关实用工具:

  • git:核心 Git 操作包装器
  • git-sync-k8s-patches:同步 Kubernetes 补丁与上游
  • make-commit:自动化提交创建

9. 开发工具

  • helm-bot:自动化 Helm chart 管理和 PR 创建
  • autotag:自动化版本标记
  • clone-and-do:克隆仓库并执行命令(Bash、Make)
  • gotestcover:Go 测试覆盖率分析和报告

10. 专用工具

  • canirun:镜像漏洞扫描
  • prow-config-validator:验证 Prow 配置文件
  • prow-image-builder:构建此仓库中定义的镜像
  • create-release:自动化发布创建
  • release-notes:生成发布说明

三仓库生态系统

仓库 1:prow-images

用途:容器镜像定义和构建逻辑

位置/Users/tashen/prow-images

内容

  • 35+ 个专用容器镜像定义
  • Dockerfile 和 VERSION 文件
  • 基于 Go 的入口应用程序
  • 通过 Makefile 进行构建编排
  • 公共 Go 库(git 实用工具、清单处理)

构建过程

1
2
3
4
5
6
7
8
# 构建所有镜像
make image

# 推送所有镜像到镜像仓库
make push

# 构建特定镜像
make image-kaniko

镜像仓库:所有镜像都推送到 hub.tess.io/prowimages/

仓库 2:prow-configs

用途:Prow 作业配置和 CI/CD 流水线定义

位置/Users/tashen/prow-configs

结构

1
2
3
4
5
6
7
8
9
prow-configs/
├── jobs/
│ ├── ebaytess/ # 组织特定的作业
│ ├── ebayistio/
│ ├── ESTOOLS/
│ └── ...
├── prow-configs/ # Prow 配置文件
├── hack/ # 辅助脚本
└── Makefile

关键文件

  • ci.manifest:CI Generator 处理的简化作业定义
  • *.yaml:自动生成的 Prow 作业规范
  • presubmit、postsubmit 和 periodic 作业的配置

工作流程

  1. 开发者创建/修改 ci.manifest 文件
  2. 运行 make jobgen 生成作业规范
  3. CI 验证生成的配置
  4. 合并后,Prow 加载新配置

仓库 3:test-infra/prow/cmd/manual-trigger

用途:手动作业触发服务

位置/Users/tashen/test-infra/prow/cmd/manual-trigger

功能:HTTP 服务,允许在没有 GitHub 事件的情况下触发 Prow 作业

完整工作流程

场景 1:添加新的构建作业

  1. 开发者操作(prow-configs)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # 在 prow-configs/jobs/myorg/myrepo/ci.manifest
    myorg/myrepo:
    - jobGenType: Build
    name: build-myapp
    branch: main
    dockerFile: Dockerfile
    versionFile: VERSION
    buildTime: kaniko
    targets:
    - onPr:
    imageTags:
    - hub.tess.io/myorg/myapp:pr-${PULL_NUMBER}
  2. CI 生成

    • CI Generator(来自 prow-images)读取清单
    • 生成完整的 Prow 作业 YAML 规范
    • 创建在 PR 上运行的 presubmit 作业
    • 配置来自 prow-images 的 Kaniko 镜像作为作业容器
  3. 作业执行

    • 当创建 PR 时,Prow 触发 presubmit 作业
    • Kaniko 镜像克隆仓库
    • 使用指定的 Dockerfile 构建容器
    • 推送到镜像仓库,标签为 pr-${PULL_NUMBER}
    • 将构建状态发布回 GitHub PR

场景 2:手动运行 E2E 测试

  1. 开发者需要测试特定提交

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    curl -X POST "http://manual-trigger.tessprow/manual-trigger" \
    -H "Content-Type: application/json" \
    -d '{
    "org": "tess",
    "repo": "tessops",
    "base_ref": "feature-branch",
    "prowtype": "postsubmit",
    "prowjob": "sddz-e2e-k8s-1.32",
    "user": "developer-name"
    }'
  2. Manual Trigger 服务

    • 验证请求参数
    • 在来自 prow-configs 的 Prow 配置中查找作业
    • 在 Kubernetes 中创建 ProwJob 自定义资源
    • 设置 AUTHOR=developer-name 环境变量
  3. 作业执行

    • Prow 调度器拾取 ProwJob
    • 使用来自 prow-images 的 e2e 镜像
    • 配置 Kind 集群(使用来自 prow-images 的 kind 镜像)
    • 运行 E2E 测试
    • 报告结果(但不会发布到 GitHub,因为是手动触发)

场景 3:自动生成的安全 PR

  1. 安全团队操作

    • 在 YAML 文件中定义 RBAC 资源
    • 指定目标集群(集群 11、22 或所有集群)
  2. 自动化工作流程

    • Prow periodic 作业触发 auto-security-pr 镜像
    • 镜像扫描集群配置
    • 为每个集群生成适当的 RBAC 清单
    • 创建 PR 到 sig-security 仓库
    • Auto-validation 作业验证 PR
    • 如果满足条件,Auto-approval 作业批准

场景 4:构建和更新 prow-images 本身

  1. 开发者更新 Kaniko 镜像

    • 修改 /Users/tashen/prow-images/kaniko/entrypoint/main.go
    • /Users/tashen/prow-images/kaniko/VERSION 中将版本提升到 v0.0.2
  2. 本地构建

    1
    2
    3
    cd /Users/tashen/prow-images
    make image-kaniko
    make push-kaniko
  3. CI 集成

    • prow-images 的 PR 触发 presubmit 作业
    • prow-image-builder 作业构建所有修改的镜像
    • 测试验证新镜像
    • 合并后,postsubmit 作业构建并推送到镜像仓库
  4. Prow-configs 更新

    • prow-configs 中引用 Kaniko 镜像的作业现在可以使用新版本
    • 在清单文件中更新镜像标签或使用 latest 标签自动更新

关键集成点

1. 镜像仓库作为中心枢纽

所有组件通过 hub.tess.io 的中央镜像仓库进行通信:

  • prow-images 构建并推送到 hub.tess.io/prowimages/
  • prow-configs 从此镜像仓库引用镜像
  • 应用程序镜像构建并推送到组织特定的命名空间

2. 清单驱动的配置

CI Generator 在简单清单和复杂 Prow 配置之间建立桥梁:

  • 开发者编写简单的 .manifest 文件
  • CI Generator(来自 prow-images)将它们转换为完整的作业规范
  • Prow(由 prow-configs 配置)执行这些作业
  • 作业使用来自 prow-images 的镜像

3. Git 作为真相来源

所有三个仓库都使用 Git 进行版本控制和触发:

  • prow-images 的更改触发镜像重建
  • prow-configs 的更改触发配置验证
  • 应用程序仓库的更改触发在 prow-configs 中定义的作业
  • Manual-trigger 在需要时提供带外触发

4. Kubernetes 原生架构

一切都在 Kubernetes 上运行:

  • Prow 组件作为 Kubernetes 服务运行
  • ProwJob 是 Kubernetes 自定义资源
  • 所有作业执行都在 Kubernetes Pod 中进行
  • 来自 prow-images 的镜像提供 Pod 容器

高级功能

版本管理

prow-images 中的每个镜像都维护一个 VERSION 文件:

1
v0.0.1

这使得:

  • 工具的语义版本控制
  • 可重现的构建
  • 回滚能力
  • CI 作业中的镜像标签生成

多触发器支持

作业可以配置在不同的触发器上运行:

  • onPr:在拉取请求时运行
  • onTag:当推送特定标签模式时运行
  • Manual:通过 manual-trigger 服务触发
  • Periodic:定期执行

安全和认证

  • Git 操作使用基于令牌的认证
  • 镜像支持用于加密仓库的 git-crypt
  • 通过 Kubernetes Secret 进行镜像仓库认证
  • Prow 作业执行权限的 RBAC

可观测性

  • 在端口 9090 上暴露 Prometheus 指标
  • 所有镜像中的详细日志
  • PR 作业的 GitHub 状态报告
  • 在 Prow UI(deck)中可见 ProwJob 状态

最佳实践

prow-images 开发

  1. 版本提升:进行更改时始终更新 VERSION 文件
  2. 测试:推送前在本地测试镜像
  3. 文档:对重大更改更新组件 README
  4. 向后兼容性:更改接口时考虑现有用户

prow-configs 管理

  1. 使用清单:优先使用 .manifest 文件而不是手写作业 YAML
  2. 本地验证:提交 PR 前运行 make jobgen
  3. 测试作业:合并前使用 manual-trigger 测试新作业
  4. 避免手动编辑:永远不要直接编辑自动生成的文件

手动触发

  1. 使用正确的类型:选择 presubmit 用于 PR 测试,postsubmit 用于分支测试
  2. 设置用户:始终提供 user 参数以进行审计跟踪
  3. 监控作业:在 Prow UI 或通过 kubectl 检查作业状态
  4. 清理:应该调查并清理失败的作业

常见工作流程总结

向 prow-images 添加新工具

1
2
3
4
5
6
7
8
1. 创建目录:prow-images/mytool/
2. 添加 Dockerfile
3. 添加 VERSION 文件
4. 实现 entrypoint/main.go
5. 更新 Makefile 添加构建目标
6. 构建:make image-mytool
7. 推送:make push-mytool
8. 在 prow-configs 作业定义中使用

向 prow-configs 添加新作业

1
2
3
4
5
6
7
1. 创建/编辑 ci.manifest 文件
2. 使用 jobGenType、name、triggers 定义作业
3. 运行:make jobgen
4. 验证生成的 YAML
5. 创建 PR 到 prow-configs
6. CI 验证配置
7. 合并 → Prow 加载新作业

手动触发作业

1
2
3
4
5
6
1. 从 prow-configs 查找作业名称
2. 识别 org、repo、branch
3. POST 到 manual-trigger 服务
4. 在响应中接收 job_name
5. 监控:kubectl get prowjobs -n tessprow | grep <job_name>
6. 在 Prow UI 中查看日志

架构图(概念)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
┌─────────────────────────────────────────────────────────┐
│ GitHub 事件 │
│ (创建 PR、推送提交) │
└────────────────────┬────────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
│ Prow 控制器 │
│ (从 prow-configs 仓库读取配置) │
└─────────┬──────────────────────────────────────┬────────┘
│ │
│ 触发 ProwJob │
│ │
▼ ▼
┌──────────────────────┐ ┌──────────────────────┐
│ Manual Trigger │ │ 定期作业 │
│ (HTTP 服务) │ │ (Periodic) │
└─────────┬────────────┘ └──────────┬───────────┘
│ │
│ 创建 ProwJob │
│ │
▼ ▼
┌─────────────────────────────────────────────────────────┐
│ Kubernetes ProwJob 资源 │
└─────────┬───────────────────────────────────────────────┘

│ 生成 Pod


┌─────────────────────────────────────────────────────────┐
│ 容器执行 │
│ (使用来自 prow-images 仓库的镜像) │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Kaniko │ │ Kind │ │ E2E │ │
│ │ 镜像 │ │ 镜像 │ │ 镜像 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Git │ │ CI-Gen │ │ Auto-Sec │ │
│ │ 镜像 │ │ 镜像 │ │ 镜像 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────┬───────────────────────────────────────────────┘

│ 结果


┌─────────────────────────────────────────────────────────┐
│ GitHub 状态 / Prow UI │
└─────────────────────────────────────────────────────────┘

故障排除指南

镜像构建失败

问题make image-kaniko 失败

  • 检查 Dockerfile 语法
  • 验证基础镜像可用性
  • 确保依赖项已被 vendor
  • 检查 Docker 守护进程是否运行

作业不运行

问题:Prow 作业在 PR 上不触发

  • 验证 prow-configs 中是否启用了 trigger 插件
  • 检查作业名称在配置中是否匹配
  • 确保 prow-configs release 对象状态为 Succeeded
  • 验证清单文件是否已正确处理

Manual Trigger 错误

问题:”配置中未找到作业 X”

  • 验证确切的作业名称(区分大小写)
  • 检查 org/repo 组合是否正确
  • 确保已部署最新的 prow-configs
  • 验证作业类型匹配(presubmit/postsubmit)

镜像版本不匹配

问题:作业使用旧镜像版本

  • 检查作业规范中的镜像标签
  • 验证新镜像是否已推送到镜像仓库
  • 通过删除 :latest 标签强制拉取
  • 检查 imagePullPolicy 是否设置正确

结论

prow-images 生态系统代表了基于 Kubernetes 和 Prow 构建的全面的生产级 CI/CD 基础设施。三仓库架构提供了清晰的关注点分离:

  • prow-images:工具和实用程序(”如何做”)
  • prow-configs:作业定义和流水线(”做什么”)
  • manual-trigger:带外控制平面(”何时做”)

这些组件共同实现了:

  • 自动化构建和测试
  • 安全的容器镜像创建
  • 临时测试环境
  • 自动化安全管理
  • 灵活的作业触发
  • 企业级规模的可扩展 CI/CD

通过 CI Generator 的清单驱动方法显著降低了 Prow 配置的复杂性,使开发者能够轻松使用,同时保持 Kubernetes 原生 CI/CD 的全部功能。

无论您是构建新工具、添加测试作业还是手动触发部署,理解这三个仓库如何交互是有效使用这个强大 CI/CD 平台的关键。

延伸阅读


最后更新:2026 年 4 月 8 日