knative-build提供将源码编译、构建、打包的整个流水线流程。其核心原理是基于pod的init contaier来定义一系列串行执行的stage。由于每一个stage都可以由用户自定义,若加以扩展,还可以用于更多场景。
资源模型
build
一条具体可运行的pipeline任务,里面包括多个stage(第一个stage为从代码仓库拉取源码)step
组成pipeline的一个执行阶段,其底层通过使用init container来实现。build-template
对同一类pipeline任务流程的抽象,通常用户指定参数的形势来实例化为具体的build。
Builder
就是build中的每一个step所使用的构建基础工具或环境,通常通过基础镜像的形势来指定。这里对常用的集中builder做简单介绍。
bazel
在buildTemplate中,对应使用的builder为镜像 gcr.io/cloud-builders/bazel
。
1 | apiVersion: build.knative.dev/v1alpha1 |
kaniko
kaniko貌似是通过dockerfile来生成镜像的,这里需要指定dockerfile目录以及目标镜像的名称。其builder使用的image为 gcr.io/kaniko-project/executor,除此之外,google来提供了很多的工具,可以在各个阶段中用到,也可以用来扩展buildTemplate的steps。
1 | apiVersion: build.knative.dev/v1alpha1 |
buildkit
buildkit是docker提供出来的,运行这个buildTemplate的build-and-push step其实是运行了一个buildkit的client。该client向运行在远端的buildkit server发送构建的任务,其具体流程可以参考docker buildkit项目。
1 | apiVersion: build.knative.dev/v1alpha1 |
代码实现
knative-build的代码主要实现对三种CRD资源的controller。三种CRS资源分别是:
- build
- buildTemplate
- clusterBuildTemplate
下面是核心代码的主流程,如下图所示:
Controller
在后两种template资源的controller代码中,到检测到有新的template创建时,会创建对应的builder镜像(通过get image可以查询)的操作。template资源的功能主要是为实例化build提供一种快速生成的模板和工具。
再来说build,build的operator首先判断该build是否基于buildTemplate创建。如果是,就将输入参数应用到模板,再将包含多个steps的完整build资源转化为由多个initContainer串行的pod。值得注意的是,build的前两个阶段一般是挂载秘钥volume(后面会再讲到)和拉取source code的initContainer,但该字段并非必须。
对于拉取代码,这里有三种情况,见下表:
代码拉取方式 | image | 备注 |
---|---|---|
git | git-init |
基于git拉取代码 |
gcs | gcs-fetcher |
google专用 |
custom | 无 | 该情况适用于用户通过volume挂载的方式来获取源码 |
1 | for i, source := range sources { |
基于远端仓库拉取代码的方式,大多的代码仓库都需要做认证。这块knative是使用 creds-init
来实现的,该镜像运行起来后会生成一个initContainer。该initContainer通过找出serviceaccount下匹配builder的sercret,然后通过挂载volume的形势,将该secret挂载到pod对应的目录下,供builder在拉取代码的时候使用。
Image
knative启动时,指定了了四个镜像,其中的三个在前面已经提到过。nopImage
用于在所有initContainer执行完之后运行的pod,该container并不做实质性的工作,只用来结束串行的initContainer;其代码很简单,只是在main函数中打印了成功执行完build的提示消息。
1 | var ( |
下面是启动后四个images的CRD信息。
1 | [root@k8s-master ~]# kkb get images |