内容简介:作者:bbbmj(才云软件工程师)编辑:bot(才云)
作者:bbbmj(才云软件工程师)
编辑:bot(才云)
如果你正在大规模进行 CI/CD,却没有使用 Kubernetes 原生 CD,你可能错过了不少东西。Prow——正如这个希腊语的含义“船头”——一直是使 Kubernetes 成为大规模执行 CI/CD 的优秀平台的强大助力。多年来,它也始终处在原生 Kubernetes CD 的最前沿。
如果你经常混迹于 Kubernetes 上游社区,你一定知道 k8s-ci-bot:point_down:,它能帮助管理上游的 PR & Issue,几乎无处不在。今天,我们就来探究一下它背后的项目 Prow。
什么是 Prow
Prow 的出现称得上是顺势而为。在它诞生前夕,Kubernetes 正值快速发展,开发者们每天需要在数个 GitHub 组织的 100 多个代码库中执行超过 10,000 个 CI/CD job。为了简化工作,Kubernetes 测试特别兴趣小组(sig-testing)创建了一系列 工具 和服务,其中就包括 Prow。
在官方文档中,Prow 被描述为是一个 Kubernetes 原生 CI/CD 系统,可以通过各种类型的 GitHub 事件触发 job,并将其状态报告给不同的服务 (如 Gerrit、Google Cloud Pubsub 和 GitHub 等)。除了执行 job,它还能通过以下形式提供 GitHub 自动化:
-
策略驱动(科学的策略,让 GitHub 权限管理更严谨、安全)
-
/foo 样式命令的 chat-ops
-
自动合并 PR
注:GitHub 自动化包括 issue 管理、PR 管理(Review 代码、Approval、自动化测试、自动化合并、自动化检测代码测试覆盖率)和 Release 管理三类内容。
目前,Prow 已被超过 140 个项目使用,下面是一些典型组织和项目:
-
Kubernetes
-
OpenShift
-
Istio
-
Knative
-
Jetstack
-
Kyma
-
Prometheus
-
Caicloud :point_left: 我所在的公司 :sunglasses:
-
Kubeflow
-
Azure acs-engine
-
tensorflow/minigo
-
helm/charts
作为一种基于事件的解决方案,Prow 提供了适合云原生世界的松散耦合架构,被许多 Kubernetes 项目用于 CI/CD。例如,Tekton 目前正在使用 Prow 构建和测试 Tekton Pipeline;Istio 在其早期就集成了 Prow;Jenkins X 把 Prow 作为 Serverless Jenkins 的一部分;Knative 不仅为 Prow 提供了一个 CI/CD job 执行引擎,它也把 Prow 作为自己的 CI。
完整的项目生态,多次 KubeCon 登台经历,Prow 的实力毋庸置疑 :exclamation:️
工作原理
作为 Kubernetes 测试特别兴趣小组(sig-testing)的顶级项目之一,现在 Prow 是 Kubernetes test-infra 项目的一部分。但截至目前,它还没有自己的独立 GitHub repo,只是作为 kubernetes/test-infra 目录下的一个子目录。
下图是 Prow 的微服务架构,其中每一个组件都是单独的 Docker Image,在 Kubernetes 中以 Deployment 的形式运行。
为方便读者理解 ,我从 GitHub 上翻译了官方的一部分文档内容,用以解释 图中 Prow 各个组件, 具体如下:
Projob
Prowjob :使用 Kubernetes CustomResourceDefinition 实现,以下我会用 job 指代 Prowjob。
GitHub
GitHub :将 PR / issue 等状态变化的事件发送到用户指定的 Webhook URL。
核心组件
Hook :Prow 最核心的组件,它是一个无状态服务,开启 /hook
路由接收 GitHub webhooks (events),验证 hmac secret 并根据 event type 分发任务到不同的 plugin 中执行。plugin 负责触发 jobs、实现 /foo
样式命令的 chat-ops、通知到 Slack 等工作。Prow 在部署时,可以配置你的 repo 使用哪些 plugin。
Plank :Prowjob controller,负责管理在 Kubernetes 中 job 的执行与生命周期。
Deck :一个 dashboard,展示 job、PR 的状态信息,还有各种 Hook Plugins 对应的 chat-ops 命令帮助信息。Kubernetes 官方的 Deck 链接:https://prow.k8s.io。
Horologium :根据策略创建 Periodics 类型的 job。
Sinker :定时清理旧的 job 和相关联的 job 状态是 finished
的 Pod,清理周期可配置。
自动化合入 PR
Tide :自动重新测试 PR,并根据预先设定的合并标准,自动化合并 PR。
辅助组件
Crier :Prowjob controller,负责 watch job status,并更新 reporter 的 status。reporter 目前支持 Gerrit、Pubsub、GitHub。(功能上与 Plank 有所重复,择一即可)。
来源: https://github.com/kubernetes/test-infra/blob/master/prow/cmd/README.md
Prowjob 生命周期
关于 Prow 是如何执行 job 的,官方在 GitHub 上其实有简要介绍,详见[1], 这里再基于源码做具体解读 。
在 PR 中评论 /test all
,Github 将创建一个表示该事件的 JSON 对象,并发送 webhook 到 Prow。webhook payload 示例见[2]。
webhook 在 ingress
的帮助下进入集群, ingress
中有一条规则 /hook
指向 hook。
hook 反序列化 payload 到 go 结构体,然后传给各个 plugin。对于每一个 plugin,hook 会传两个对象,plugin client 和反序列化的 github event(这里是 IssueCommentEvent)。plugin client 结构体中包含 GithubClient
(对 GitHub 操作的方法)、 KubeClient
和 Config
(Prow 相关配置)。
trigger
plugin 在 init
方法中注册了 GenericCommentEvent
,hook 会把 event 分发给它处理。
trigger
plugin 中有一个 handleGenericComment()
方法通过 event 的 body 与 PluginClient.Config 进行比较,来判断哪些 job 需要运行,然后在集群中创建对应的 ProwJob
。 到这里,hook 的一次 webhook 处理就结束了,之后它会继续下一次 sync。
ProwJob
的 YAML 文件表示可能如下:
然后 Plank
会根据预先设定的周期,去 list CreatedByProw
和 ProwJobAgent = "kubernetes"
的 Pod,根据 Prowjob 的状态分成两种类型:pending job、triggered job,再分别 sync 两种类型的 job,维护其生命周期和状态,并传到 report 的 go channel 中。最终读取 report channel 中的数据并更新 GitHub status。
最后, Sinker
会根据预先设定的周期,定期清理旧的 job 和相关联的 job 状态是 finished
的 Pod。
如何写一个 Prow plugin
关于 Prow 的部署,看视频会比看文字更直观,所以这里我给大家推荐一个 Youtube 视频,有条件的读者可以科学上网看一看 :
https://www.youtube.com/watch?v=eMNwB96A1Qc
下面,我们通过一个示例—— cat
plugin ,来描述 plugin 的实现和使用,源码见[3]。
新增 plugin 代码需要在 plugins 目录下。
首先定义 plugin 的名字
在 init 方法中注册需要处理的 event 对应的 handler
,当发生该 event,hook 会分发给你处理。
根据需要对 GitHub 有哪些操作,定义对应的方法:
实现 helpProvider:
实现 handleGenericComment 的具体逻辑:
然后在 hook/plugins.go 中 import "k8s.io/test-infra/prow/plugins/cat"
。
最后在 plugins.yaml 中添加这个 plugin,就大功告成了。
plugin 相关部分配置:
最后的最后,如果可以的话,记得写上测试。
最终效果:
这里我只描述了 cat
plugin 的实现原理,比较简单。如果你对这方面的实践感兴趣,只要大胆发挥想象,自定义插件可以做到更多~
写在最后
篇幅所限,我在这篇文章里只分享了 Prow 的部分内容,关于它的核心策略及更深层次的内容,读者可以自行了解。除此之外,test-infra 还有很多功能和有用的小工具, 如果有问题或是心得体会,欢迎进 K8sMeetup 中国社区的微信群找我 ,或上 GitHub 多撸几下:)
进群小助手:kubernetes-china
官方 : https://github.com/kubernetes/test-infra/tree/master/prow
--
参考资料
[1]Prow 生命周期: https://github.com/kubernetes/test-infra/blob/master/prow/life_of_a_prow_job.md
[2] webhook payload 示例: https://github.com/kubernetes/test-infra/blob/92c3881f49/prow/cmd/phony/examples/lgtm_comment.json
[3] https://github.com/kubernetes/test-infra/blob/92c3881f49/prow/plugins/cat/cat.go
推荐阅读:
在看点一下
写留言
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。