关于kubernetes:Kubernetes-原生-CICD-构建框架-Tekton-详解

作者:FogDong(Tekton 社区)
编辑:Bach(才云)

什么是流水线?

在计算机中,流水线是把一个反复的过程合成为若干个子过程,使每个子过程与其余子过程并行进行的技术,也叫 Pipeline。因为这种 s工作形式与工厂中的生产流水线十分相似, 因而也被称为流水线技术。从实质上讲,流水线技术是一种工夫并行技术。以“构建镜像”过程为例:

在每一次构建镜像中,咱们都须要拉下代码仓库中的代码,进行代码编译,构建镜像,最初推往镜像仓库。在每一次代码更改过后,这一过程都是不变的。应用流水线工具能够极大的晋升这一过程的效率,只须要进行简略的配置便能够轻松的实现重复性的工作。这样的过程也被称之为 CI。

上图流程中应用的是 Jenkins。Jenkins 作为老牌流水线框架被大家所熟知。在云原生时代,Jenkins 也推出了 Jenkins X 作为基于 Kubernetes 的新一代流水线,但明天本文次要介绍诞生于云原生时代的流水线框架——Tekton。

Tekton

Tekton 是一个基于 Kubernetes 的云原生 CI/CD 开源框架,属于 CD 基金会的我的项目之一。Tekton 通过定义 CRD 的形式,让用户以灵便的自定义流水线以满足本身 CI/CD 需要。

基本概念

四个基本概念

Tekton 最次要的四个概念为:Task、TaskRun、Pipeline 以及 PipelineRun。

  • Task: Task 为构建工作,是 Tekton 中不可分割的最小单位,正如同 Pod 在 Kubernetes 中的概念一样。在 Task 中,能够有多个 Step,每个 Step 由一个 Container 来执行。
  • Pipeline: Pipeline 由一个或多个 Task 组成。在 Pipeline 中,用户能够定义这些 Task 的执行程序以及依赖关系来组成 DAG(有向无环图)。
  • PipelineRun: PipelineRun 是 Pipeline 的理论执行产物,当用户定义好 Pipeline 后,能够通过创立 PipelineRun 的形式来执行流水线,并生成一条流水线记录。
  • TaskRun: PipelineRun 被创立进去后,会对应 Pipeline 外面的 Task 创立各自的 TaskRun。一个 TaskRun 管制一个 Pod,Task 中的 Step 对应 Pod 中的 Container。当然,TaskRun 也能够独自被创立。

综上可知:Pipeline 由多个 Task 组成,每次执行对应生成一条 PipelineRun,其管制的 TaskRun 将创立理论运行的 Pod。上面以一个简略例子来展现这些概念。

首先,创立一个最简略的 Task,外面仅有一个 Step。在一个 ubuntu 镜像中执行 ls 命令。

接着创立一个 Pipeline,外面援用第一步中创立的 Task。

在 Pipeline 存在的前提下,就能够通过创立 PipelineRun 来运行 Pipeline。

这样就实现了一个最简略的 Tekton 流水线案例。每一个 PipelineRun 的创立,都会遵循 Pipeline 中的程序规定去启动 Task 的 Pod。上面引入另外一个概念 PipelineResource 来实现一个略微简单的例子,也是 DevOps 中最常见的场景:从代码仓库拉取镜像、进行代码构建、并最终将构建好的镜像推往镜像仓库。

PipelineResource

PipelineResource 代表着一系列的资源,次要承当作为 Task 的输出或者输入的作用。它有以下几种类型:

  • git:代表一个 git 仓库,蕴含了须要被构建的源代码。将 git 资源作为 Task 的 Input,会主动 clone 此 git 仓库。
  • pullRequest:示意来自配置的 url(通常是一个 git 仓库)的 pull request 事件。将 pull request 资源作为 Task 的 Input,将主动下载 pull request 相干元数据的文件,如 base/head commit、comments 以及 labels。
  • image:代表镜像仓库中的镜像,通常作为 Task 的 Output,用于生成镜像。
  • cluster:示意一个除了以后集群外的 Kubernetes 集群。能够应用 Cluster 资源在不同的集群上部署利用。
  • storage:示意 blob 存储,它蕴含一个对象或目录。将 Storage 资源作为 Task 的 Input 将主动下载存储内容,并容许 Task 执行操作。目前仅反对 GCS。
  • cloud event:会在 TaskRun z执行实现后发送事件信息(蕴含整个 TaskRun) 到指定的 URI 地址,在与第三方通信的时候非常有用。

以上为 Tekton 目前反对的六大 PipelineResource 类型,具体的配置及应用办法详见 PipelineResource 文档。

文档地址:https://github.com/tektoncd/p…

持续剖析较简单的流水线案例:从代码仓库拉取镜像、进行代码构建、并将构建好的镜像推往镜像仓库。从已有的 PipelineResource 类型可判断,能够应用 git 类型作为代码资源作为输出,再用 image 类型作为镜像资源作为输入。有了输入输出后,咱们能够间接应用 Kaniko 来构建镜像。

Kaniko 是 Google 开源的我的项目之一,可在 Kubernetes 上无需特权模式地构建 docker 镜像。

首先创立这两个 PipelineResource。在这个例子中,git-input 对应输出,image-output 对应输入。params 中的参数均为该资源类型的固定参数:如 git 中能够通过 revision 指定版本号,image 中能够通过 url 指定镜像仓库地址。

Git-input:

Image-output:

在配置 PipelineResource 时,如果应用了公有仓库,还须要配置 Service Account,详见 configuring-authentication-for-docker。

configuring-authentication-for-docker 地址:https://github.com/tektoncd/p…

产物传递

创立完 PipelineResource 后,须要在 Task 中引入它们作为输入输出。那么,这些资源是如何在 Task 间传递的呢?

在 Tekton 的分区下,咱们能够看到一个叫做 config-artifact-pvc 和一个叫做 config-artifact-bucket 的 Config Map。从命名就能够看出,这二者别离代表了产物存储的两种配置形式—— PVC 和存储桶(目前反对 GCS 和 S3)

以 PVC 为例,批改 config-artifact-pvc 须要填写两个值:size 以及 storageClassName。size 默认为 5GiB,storage class name 默认为 default。这也意味着当咱们应用 PipelineResource 进行资源传递时,会主动创立一个 5GiB 的存储卷挂载在 Task 上,供 PipelineResource 应用。

在须要进行 Task 间的资源传递时,这个存储卷会被挂载在 Task 的 /pvc 目录下。当 Task 执行实现并且须要进行资源传递(通过 inputs/outputs 指定)后,TaskRun controller 会主动增加一个拷贝文件的步骤容器,并将输入产物对立放到 /pvc/task_name/resource_name 命名标准的目录下。

下面是针对产物须要进行传递的状况下,对于目前例子而言,因为只须要一个 Task,尽管指定了 Inputs 和 Outputs,但并没有另一个 Task 来援用这些后果。因而,在这个例子中并不会去挂载 PVC。

对于 git 以及 storage 类型的 input,资源下载后会被 放在 /workspace/task_resource_name 下;对于 output 则会放在 /workspace/output/resource_name 下。image 类型的资源则会间接上传到镜像仓库。

理解了这些前置常识后,咱们能够来创立 Task 了。Kaniko 须要三个参数来实现镜像构建:Dockerfile 的地址,context 的地址以及镜像仓库的地址。在上面这个例子中,咱们大量应用了 params 以及 Tekton 中的变量替换。Params 用于在 TaskRun 和 Task 中传递参数,而变量替换的格局为 $(xxx)。应用这些变量能够让 Tekton 在运行过程中依据规定进行赋值。值得注意的是,Tekton 并不会提前去查看这些变量的内容,这就要求着咱们在写的时候须要多加留神。具体的变量编写规定详见:Tekton variables。

Tekton variables 地址:https://github.com/tektoncd/p…

有了 Task 后,就能创立 TaskRun 来执行 Task。留神,在 spec 中申明了 serviceAccountName 用于指定公有仓库的权限。

至此,一个更为简单的流水线也构建实现了。

DAG

在 Tekton 中,DAG(有向无环图)的性能是原生反对的。只须要通过申明 runAfter 及 from 便能够便当的使 Pipeline 以 DAG 形式运行。

  • from:当 Task 的 Inputs 依赖于上一个 Task 的 Outputs 时,能够通过 from 参数来指定
  • runAfter:当 Task 间没有资源依赖,但须要使一个 Task 在另外一个 Task 之后运行的话,能够应用 runAfter 来指定。

例如在下面的例子中,工作会以下程序运行:

  • lint-repotest-app 中的 Task 没有 fromrunAfter 关键字,会同时开始执行。
  • 一旦 test-app 实现,build-appbuild-frontend 都会开始同时执行,因为它们 runAftertest-app
  • deploy-all 会在 build-appbuild-frontend 都实现后才执行,因为它须要的资源 from 于这二者。

再来看看 Tekton 是怎么样来实现这段逻辑的:

在 Pipeline 的 Controller 中,一旦监听到 Pipeline 的创立,在创立对应的 TaskRun 之前,会先检测 Pipeline 中的依赖程序并构建 DAG 图:

Step 执行程序

Pipeline 中能够进行对 Task 的顺序控制,那么 Task 中呢?

在 Kubernetes 中,Pod 里的 Container 是并行启动的。而在 Tekton 中,尽管 Task 对应 Pod,Task 中的 Step 对应 Container,但 Task 中的 Step 却是程序执行的。要理解 Tekton 是怎么实现这样的顺序控制,首先咱们来看一下一个 Tekton 的 Pod。

在这个 Pod 中,除了用户须要运行的 Container,还被注入了一个 InitContainer:

这个 InitContainer copy 了一个 entrypoint 的二进制到 Pod 中。再看下用户的 container,咱们能够看到 Pod 的执行命令被 Tekton 改写了一下:

能够看到 command 被改写为了 entrypoint 命令,这个二进制包在 initContainer 中被导入,另外还有一些启动参数:

  • -post_file:指定了 Step 实现后的文件写入门路。如果 Step 失败,则写入到 {{post_file}}.err。能够看到下面的写入门路为 /tekton/tools/0,最初的这个数字即为 Step 的编号。
  • -wait_file:指定了在启动下一个 Step 之前要查看的文件门路。它将监听 {{wait_file}}{{wait_file}}.err。若有谬误则跳过执行写入 {{post_file}}.err 并返回谬误(exitCode >= 0);若无谬误则执行下一个 Step。如上例子为第一个 step,若为第二个 step,wait_ file 的地址会是 /tekton/tools/0,也就是上一个 step 的 post_file 地址。

资源管制

在 Kubernetes 中,一个 Pod 被调度须要节点满足 Pod 中的所有 Container 的资源。如下图:

这个 Pod 有 4 个容器,总共须要 9 个 CPU。Kubernetes 将把这个 Pod 调度到一个领有 9 个可用 CPU 的节点上。如果没有节点有 9 个可用 CPU,Pod 将被调度失败并无奈启动。

而对于 Tekton 而言,因为 Pod 中的 Container 会程序执行,所以只须要满足这个 Pod 中资源最大的 Container 即可。对于同一个TaskRun,Tekton 会获取最大申请,并让一个 Container 去申请这些资源,其余都设为 0。

如下,该 Pod 申请 4 个 CPU,而不是 9 个。这样的资源管制形式更为正当且所有的 Step 容器仍保留所须要的资源。

在有 LimitRange 限度 Container 必须有资源的的状况下,每个 Container 最小会设置为 LimitRange 的设置。

源码局部逻辑如下:

数据传递

除了 PipelineResource 以外,Tekton 还提供了其余数据传递的形式。

PipelineResource 仍处于 Alpha 版本,它有可能会被从新设计、替换、弃用或者齐全删除。Tekton 社区激励用户用 Task 代替 PipelineResources。

Workspace

Workspace 与 Kubernetes 中 Volume 概念简直保持一致,只不过并不是 Pod 层级的而是作用于 Tekton 资源层级的。Workspace 在 Pipeline 中应用时是一个形象的概念,理论的存储类型须要在 PipelineRun 中指定。详见:Workspaces。

Workspaces 地址:https://github.com/tektoncd/p…

Results

Tekton 提供了一个固定目录用于寄存 Task 的输入:/tekton/results

如上,该 task 将日期输入到了 /tekton/results/current-date 中。同时,也会被作为 Results 字段加到 TaskRun 的 Status 中。这样,其余的 Task 便能够通过 $(tasks..results.) 来获取到该 Task 的 results。(变量替换将会理论从 TaskRun 中获取到 Results 的值)

其余流程管制性能

条件判断

低版本能够应用 Conditions,高版本举荐应用 WhenExpressions(Conditions 将在不久后废除,齐全替换为 WhenExpressions)。WhenExpressions 由 Input、Operator、Values 三局部组成,其中 Input 能够应用 Tekton 的 Parameter 或者 Results,Operator 目前仅反对 in 和 notin:

谬误重尝

通过 retries 来指定工作失败后从新尝试的次数:

退出解决

通过 finally 指定在 pipeline 完结时执行的 task,无论 pipeline 的后果是胜利或失败。

勾销执行

要勾销以后正在执行的 PipelineRun,能够在其 Spec 中更新 Status 为勾销。当 PipelineRun 被勾销时,所有相干的 Pods 都被删除。例如:

Pipeline 暂停的逻辑与之相似,但暂停 PR 尚未合入,暂停性能也在 Tekton 往年的 Roadmap 中。

Runs

Runs 是一个进行中的 feature,Run 容许实例化和执行一个 Custom Task,这个 Custom Task 能够通过用户自定义的 controller 来执行。这对于用户来说是一个十分理论的性能,能够通过本人写的 Controller 来定义 Task 的逻辑,而不再拘泥于 Tekton 定义的 Task。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理