基于Kubernetes的CI/CD利器 — Prow 入门指南

简介

Prow 是 Kubernetes 官方使用的 CI/CD 系统,用于管理k8s的issue和pr。若是你常常去 Kubernetes 社区查看 PR 或者提交过一些 PR 后,就会常常看到一个叫k8s-ci-bot的机器人在各个Pr中回复,而且还能合并pr。在k8s-ci-bot中背后工做的就是Prow。Prow是为了弥补 GitHub 上一些功能上的缺陷,它也是Jenkins-X的一部分,它具有这些功能:html

  1. 执行各类 Job,包括测试,批处理和制品发布等,可以基于github webhook配置 Job 执行的时间和内容。
  2. 一个可插拔的机器人功能(Tide),可以接受/foo这种样式的指令。
  3. 自动合并Pr
  4. 自带一个网页,可以查看当前任务的执行状况以及Pr的情况,也包括一些帮助信息
  5. 基于OWNER文件在同一个repo里配置模块的负责人
  6. 可以同时处理不少repo的不少pr
  7. 可以导出Prometheus指标

Prow 拥有本身的CI/CD系统,可是也能与咱们常见的 CI/CD 一块儿协做,因此若是你已经习惯了 Jenkins 或者travis,均可以使用 Prow。nginx

安装指南

官方repo提供了一个基于GKE快速安装指南,本文将基于青云的Iaas搭建Prow环境。不用担忧,其中大部分步骤都是平台无关的,整个安装过程可以很方便的在其余平台上使用。git

1、 准备一个 Kubernetes集群

有如下多种方式准备一个 Kubernetes 集群github

  1. 利用kubeadm自建集群;
  2. 在青云QingCloud一键部署 KubeSphere 集群,或直接下载安装 KubeSphere
  3. 将集群的kubeconfig复制到本地,请确保在本地运行kubectl cluster-info正确无误。

2、 准备一个 GitHub 机器人帐号

若是没有机器人帐号,用我的帐号也能够。机器人帐号便于区分哪些Prow的行为,因此正式使用时应该用机器人帐号。web

  1. 在想要用prow管理的仓库中将机器人帐号设置为管理员。docker

  2. 在帐号设置中添加一个[personal access token][1],此token须要有如下权限:bash

    • 必须public_reporepo:status
    • 可选repo假如须要用于一些私有repo
    • 可选admin_org:hook 若是想要用于一个组织
  3. 将此Token保存在文件中,好比${HOME}/secrets/oauthapp

  4. openssl rand -hex 20生成一个随机字符串用于验证webhook。将此字符串保存在本地,好比${HOME}/secrets/h-macide

注意最后两步建立的token必定须要保存好,除了须要上传到k8s,后续配置也要用到,用于双向验证工具

3、 配置 Kubernetes 集群

这里使用的default命名空间配置prow,若是须要配置在其余命名空间,须要在相关kubectl的命令中配置-n参数,而且在部署的yaml中配置命名空间。 建议将本repo克隆到本地,这个repo带有不少帮助配置Prow的小工具。

  1. 将上一步中建立token和hmac保存在k8s集群中
# openssl rand -hex 20 > ${HOME}/secrets/h-mac
kubectl create secret generic hmac-token --from-file=hmac=${HOME}/secrets/h-mac
kubectl create secret generic oauth-token --from-file=oauth=${HOME}/secrets/oauth
复制代码
  1. 部署Prow。因为Prow官方yaml中使用了grc.io镜像,这个镜像在中国大陆没法访问,因此咱们将相应的repo搬到了dockerhub上,并提供了一份替换相关镜像名称的yaml,利用下面的命令便可部署Prow(使用的这个repo修改后的yaml)
kubectl apply -f https://raw.githubusercontent.com/magicsong/prow-tutorial/master/prow.yaml
复制代码
  1. 使用kubectl get pod看到全部Pod都running表示安装已经完成。以下图:

  1. 配置外网访问
  • 若是使用的QKE,那么集群默认带有LoadBalancer Controller。若是只是一个单独集群,那么只须要按照github.com/yunify/qing…中的安装便可,安装很是方便。
  • Prow官方采用的是ingress配置外网访问,因此咱们须要配置ingress-controller。QKE默认带有一个ingress-controller,在kubesphere-control-system中。若是集群中尚未ingress-controller,须要安装一个。官方文档中尚未青云的配置指南,须要安装下面的指令安装ingress-controller
  • kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
    kubectl apply -f https://raw.githubusercontent.com/magicsong/prow-tutorial/master/manifest/ingress-service.yaml #这个命令QKE须要执行
    复制代码
    执行上述两条命令以后,敲 kubectl get svc -n ingress-nginx,等待获取公网IP便可,以下图(若是须要手动指定公网IP,参考LB的配置文档配置ingress-nginx这个service):

注意若是使用的QKE,须要执行上面两个命令中的第二个命令。第二个命令对应的yaml就是ingrsss,在apply以前须要将其中的namespace修改成kubesphere-control-system

  1. 访问Prow地址,默认应该为刚才的ingress的公网ip+端口8080,应该能在页面中看到一个Echo Test的任务。访问效果以下:

恭喜你!你已经拥有了一个prow集群,这个集群已经准备工做了,下一步就是要作一些配置工做,以使得Prow能按照咱们的意图工做。

配置指南

Prow配置较为复杂,这里只演示最小配置,能让咱们的Pr机器人工做起来

工具准备

  1. 安装bazel。Bazel是google公司用来构建k8s代码的一个工具,一样prow也是用bazel构建的。后续的配置都是用bazel动态生成的工具来配置的(相似于go run ./pkg/tool -a -b)。若是你身处非大陆地区,也能够不用Bazel,直接时候用go get来获取静态binay执行命令。
  2. 若是要使用bazel,安装完成以后须要将整个仓库github.com/kubernetes/… 整个仓库clone下来,用于Bazel运行命令的仓库。clone完成以后cd 进入这个repo的根目录

配置webhook

Prow是基于webhook工做的,github上的活动会发送给处理

  1. 选择一个github仓库配置webhook。执行下面的命令添加一个repo,须要替换掉其中的hmac-pathgithub-token-path,hook的地址是上面的prow地址加一个”/hook“:
# Ideally use https://bazel.build, alternatively try:
# go get -u k8s.io/test-infra/experiment/add-hook && add-hook
bazel run //experiment/add-hook -- \
  --hmac-path=/path/to/hook/secret \
  --github-token-path=/path/to/oauth/secret \
  --hook-url http://an.ip.addr.ess/hook \
  --repo my-org/my-repo \
  --repo my-whole-org \
  --confirm=false  # Remove =false to actually add hook
复制代码
  1. 若是运行没问题,那么须要将最后一行改成--confirm=true。运行成功后,在repo的webhooks配置中,应该能看到一个新的webhook:

配置集群使用的插件

Prow是以插件机制运行的,相似CoreDNS那种,没有插件就什么都不作,可是依然能正常运行。咱们须要配置咱们的repo须要哪些插件

  1. 官方提供了很多插件,在上面的Prow页面中就能看到一些,如今演示如何使用内置的一些插件。首先建立一个plugins.yaml的文件,以下:
plugins:
  github.com/kubesphere-test/prow-tutorial:
 - size
 - cat 
 - dog
 - pony 
 - yuks 
 - label
 - trigger
 - approve
 - lgtm 
复制代码
  1. 建立一个空白的config.yaml,这个文件将会在后续配置任务中使用,插件配置部分留空便可。
  2. 若是安装了bazel,那么进入test-infra这个目录,执行下面的命令(记得替换其中的相关文件的路径),这个命令会检查config.yamlplugins.yaml的配置是否正确:
bazel run //prow/cmd/checkconfig -- --plugin-config=path/to/plugins.yaml --config-path=path/to/config.yaml
复制代码
  1. 检查无误以后就能够将plugins.yaml上传到集群中(替换其中的路径):
kubectl create configmap plugins \
  --from-file=plugins.yaml=${PWD}/samples/plugins.yaml --dry-run -o yaml \
  | kubectl replace configmap plugins -f -
复制代码
  1. 这样size插件就完成了。能够提一个PR,效果应该以下图:

  1. 上述演示中还安装了不少好玩的插件,能够参考prow页面中帮助页面,学习如何使用这些命令。

配置Tide机器人

tide机器人最主要的功能就是自动合并Pr,当设定的目标达成时,tide机器人就会自动将代码Merge进主分支。Tide的完整的配置较为复杂,这里演示一个基本的配置,无需修改不少就能运行。

  1. 在上述config.yaml中加入下列字段(请修改相应的repo和相应的tide页面):
tide:
 merge_method:
    kubesphere-test/prow-tutorial: squash

 target_url: http://139.198.121.161:8080/tide
 queries:
 - repos:
 - kubesphere-test/prow-tutorial
 labels:
 - lgtm
 - approved
 missingLabels:
 - do-not-merge
 - do-not-merge/hold
 - do-not-merge/work-in-progress
 - needs-ok-to-test
 - needs-rebase

 context_options:
    # Use branch protection options to define required and optional contexts
 from-branch-protection: true
    # Treat unknown contexts as optional
 skip-unknown-contexts: true
 orgs:
 org:
 required-contexts:
 - "check-required-for-all-repos"
 repos:
 repo:
 required-contexts:
 - "check-required-for-all-branches"
 branches:
 branch:
 from-branch-protection: false
 required-contexts:
 - "required_test"
 optional-contexts:
 - "optional_test"
复制代码
  1. 执行下面的命令将config.yaml推送到k8s集群中(替换相应的config.yaml文件位置):
kubectl create configmap config --from-file=config.yaml=${PWD}/samples/config.yaml --dry-run -o yaml | kubectl replace configmap config -f -
复制代码
  1. 去刚才的pr上看,应该能够看到下面的check:

  1. 因为这是我提的Pr,因此自动会带上approved标签,如今只要添加一个lgtm的标签就能够。须要找代码Review的人看过代码,而后让他们输入/lgtm的评论便可,Prow会自动打上lgtm的标签。(因为此次演示没有其余人打/lgtm,而且本身没法给本身评论/lgtm,因此本次演示须要手动给这个pr在lables中选择lgtm的标签)。效果以下图:

高级配置

Prow 是一个高效的CI/CD系统,也是一个复杂的系统,本文没法阐述全部的高级配置,更深刻的配置能够参考官方文档。本Repo整理了一些经常使用的脚本,方便后续使用Prow的时候进行配置。使用这些脚本时,请注意替换一些数据。 更多的请参考如下的OWNERS 使用指南。

OWNERS 使用指南

OWNERS是一个配置文件,用于标记代码的文件夹的所属。

工做原理

  1. OWNERS文件表示这这个文件所在的目录的全部者,包括子目录。因此root目录里的OWNERS文件拥有整个集群的最高权限,称之为"root owner",全部的Pr只要root owner赞成了都会被自动合并。
  2. repo下的每一个文件夹均可以设置OWNERS,若是某一个Pr改动了这个文件夹后者其子文件夹的内容,就须要这个文件夹的OWNER 赞成才行,若是改了多个,那就须要多我的都approve。固然也能够直接找root owner
  3. 能够在OWNERS文件中设置Label,全部改动了这个文件夹中的Pr都会被打上相应标签。固然,这个Label不该该出如今root OWNERS中,这样会给全部的Pr都打上标签。

基本语法

OWNERS是一个yaml文件,其基本形式(最简单配置)以下:

approvers:
 - alice
 - bob     # this is a comment
reviewers:
 - alice
 - carol   # this is another comment
 - sig-foo # this is an alias
lables:
 - re/foo
 - re/question
复制代码
  1. approvers 可以是用/approve命令,这个命令是Pr可以合并的最小条件。能够没有lgtm,可是必需要有approved。因此appovers拥有Merge权限,相似于maintainer级别。这里还有一个注意事项就是approvers提的pr若是知足了工做原理中的第二条规则,就会自动会被打上approved的标签(出现这种状况有两种可能,1. 他是root owner,2. 他是subdir owner,并且他改的代码都是在这个目录下的),因此须要在pr merge上添加上另一个标签的限制(一般是lgtm),来阻止approvers的代码自动被merge。
  2. reviewer 可以使用/lgtm命令(Looks good to me),用于审阅代码。通常的repo都会把lgtm这个命令做为必要条件,任何人提的代码都不会自动打上lgtm的标签,必需要手动使用命令才行。主要是约束代码必须被review过才行。
  3. 若是approvers使用了github的approve功能,也能打上approve的标签。

高级语法

OWNERS还支持Fliter参数(这个参数不能和上面的这些混合使用),这个参数主要用于对代码文件进行分类,能够参考github.com/kubernetes/…了解更详细的用法。

相关文章
相关标签/搜索