本篇文章将对 Prow 进行基本的介绍,并根据架构对其中的工作原理逐一讲解。之后再引导大家如何在 Kubernetes 环境中部署使用 Prow。
Prow 介绍
Prow 是基于 Kubernetes 的 CI/CD 系统。它能够对各种类型的事件进行触发,并向不同的服务报告状态。与此同时,它还为 GitHub 自动化实现了策略增强、ChatOps(如 /foo 风格的命令)以及自动化合并 PR等功能。
目前 Kubernetes、Istio、Prometheus 等 CNCF 项目都使用 Prow 进行开源协同。另外一款云原生的 CI/CD 平台 —— Jenkins X 也将 Prow 作为关键组件集成到项目中以实现 Serverless。
Prow 项目还是作为 kubernetes/test-infra 项目下的子目录而存在。
- Kubernetes 生态的 Prow 系统:https://prow.k8s.io/
- Prow 开源仓库:https://github.com/kubernetes/test-infra/
- Prow 官方文档:https://github.com/kubernetes/test-infra/blob/master/prow/README.md
Prow 架构
下图是 Prow 的微服务结构,每个服务组件在 Kubernetes 中都以无状态的 Deployment 进行部署。
核心组件
Hook
是整个系统中最重要的一块。这是一个无状态服务,用于监听 GitHub Webhooks 并分发事件到相应的 Plugins。这些 Plugin 能够实现触发 Jobs、处理 /foo 风格的命令、发送信息到 Slack 等功能。 参阅 prow/plugins 以获取更多关于 Plugin 的信息。Plank
是 Prow 系统的 controller,用于管理运行在 Kubernetes Pods 中的 jobs 的执行与生命周期。Deck
是 Prow 系统的可视化界面,用于展示 Jobs 状态、PR 状态、自动化合并的状态和历史记录、命令和插件等帮助信息。Horologium
用于触发定时任务 (periodic jobs)。Sinker
用于清理旧的任务和 pods。Crier
用于报告 Prowjob 的状态。目前支持的 reporter 有 Gerrit、Pubsub、GitHub、Slack。Tide
用于自动重新测试 PR,并根据预先设定好的合并条件,对 PR 进行自动化合并。
ProwJob
Prow 的 job 是通过 ProwJob 进行定义的。ProwJob 以 Kubernetes CustomResourceDefinition 实现。
Prowjob 类型主要分为以下三种:
Periodic
针对于定时任务。Postsubmit
针对于 PR 合并之后的任务。Presubmits
针对于 PR 代码的任务。
参阅 ProwJob docs 以获取更多关于 Prowjob 的信息。
Prow 工作流程
上图为 Prow 对于 PR 的交互序列图,能够清楚的了解 Prow 的基本用法与交互流程。
Prow Hook 监听来自 GitHub 的 http 请求,并将其转化为 “GitHub event objects”,随后 Hook 将 GitHub event 广播到 Prow Plugins,根据 GitHub event 触发相应的 Prow Plugin 来处理事件。就 /ok-to-test 而言,Prow Hook 会为此创建一个 “Issue Comment Event”
当 “hook” 发送用于表达 /test all 命令的 event 到 Trigger plugin,Trigger plugin 在运行测试之前会检查该 PR 是否符合要求,要求例如有 “该 PR 提交者是否为 GitHub Organization 成员”、“该 PR 是否存在 ok-to-test
标签”等。验证通过后,Trigger plugin 会根据 ProwJob 的类型和相关信息告知 Kubernetes API server 创建 ProwJob Custom Resource
ProwJob 的 yaml 表现形式可能如下:
apiVersion: prow.k8s.io/v1
kind: ProwJob
metadata:
name: 32456927-35d9-11e7-8d95-0a580a6c1504
spec:
job: pull-test-infra-bazel
decorate: true
pod_spec:
containers:
- image: gcr.io/k8s-testimages/bazelbuild:0.11