Tekton 的工作原理

这篇文章是基于 Tekton Pipeline 的最新版本v0.12.1版本。
快速入门请参考:云原生 CICD: Tekton Pipeline 实战 ,实战是基于版本 v0.10.x。
Pipeline CRD 与核心资源的关系
Tekton Pipelines提供了上面的CRD,其中部分CRD与k8s core中资源相对应
Task => Pod
Task.Step => Container

工作原理

(图片来自)
Tekton Pipeline 是基于 Knative 的实现,pod tekton-pipelines-controller 中有两个 Knative Controller的实现:PipelineRun 和 TaskRun。

Task的执行顺序
PipelineRun Controller 的 #reconcile()方法,监控到有PipelineRun被创建。然后从PipelineSpec的 tasks 列表,构建出一个图(graph),用于描述Pipeline中 Task 间的依赖关系。依赖关系是通过runAfter和from,进而控制Task的执行顺序。与此同时,准备PipelineRun中定义的PipelineResources。
PipelineRun中定义的参数(parameters)也会注入到PipelineSpec中:
接下来就是调用dag#GetSchedulable()方法,获取未完成(通过Task状态判断)的 Task 列表;
为 Task A 创建TaskRun,假如Task配置了Condition。会先为 condition创建一个TaskRun,只有在 condition 的TaskRun运行成功,才会运行 A 的TaskRun;否则就跳过。
Step的执行顺序
这一部分篇幅较长,之前的文章 控制 Pod 内容器的启动顺序 中提到过。
这里补充一下Kubernetes Downward API的使用,Kubernetes Downward API的引入,控制着 Task 的第一个 Step 在合适执行。
TaskRun Controller 在 reconciling 的过程中,在相应的 Pod 状态变为Running时,会将tekton.dev/ready=READY写入到 Pod 的 annotation 中,来通知第一个Step的执行。
Pod的部分内容:
自动运行的容器
这些自动运行的容器作为 pod 的initContainer会在 step 容器运行之前运行
credential-initializerworking-dir-initializerplace-scriptsplace-tools
Task/Step间的数据传递
针对不同的数据,有多种不同的选择。比如Workspace、Result、PipelineResource。对于由于Task的执行是通过Pod来完成的,而Pod会调度到不同的节点上。因此Task间的数据传递,需要用到持久化的卷。
而Step作为Pod中的容器来运行,
Workspace
工作区,可以理解为一个挂在到容器上的卷,用于文件的传递。
`persistentVolumeClaim`
引用已存在persistentVolumeClaim卷(volume)。这种工作空间,可多次使用,需要先进行创建。比如 Java 项目的 maven,编译需要本地依赖库,这样可以节省每次编译都要下载依赖包的成本。
`volumeClaimTemplate`
为每个PipelineRun或者TaskRun创建PersistentVolumeClaim卷(volume)的模板。比如一次构建需要从 git 仓库克隆代码,而针对不同的流水线代码仓库是不同的。这里就会用到volumeClaimTemplate,为每次构建创建一个PersistentVolumeClaim卷。(从0.12.0开始)
生命周期同PipelineRun或者TaskRun,运行之后释放。
相较于persistantVolumeClain类型的workspace,volumeClaimTemplate不需要在每次在PipelineRun完成后清理工作区;并发情况下可能会出现问题。
`emptyDir`
引用emptyDir卷,跟随Task生命周期的临时目录。适合在Task的Step间共享数据,无法在多个Task间共享。
`configMap`
引用一个configMap卷,将configMap卷作为工作区,有如下限制:
挂载的卷是
只读的需要提前创建
configMapconfigMap的大小限制为1MB(K8s的限制)
使用场景,比如使用maven编译Java项目,配置文件settings.xml可以使用configMap作为工作区
`secret`
用于引用secret卷,同configMap工作区一样,也有限制:
挂载的卷是
只读的需要提前创建
secretsecret的大小限制为1MB(K8s的限制)
Result
results字段可以用来配置多个文件用来存储Tasks的执行结果,这些文件保存在/tekton/results目录中。
在Pipeline中,可以通过tasks.[task-nanme].results.[result-name]注入到其他Task的参数中。
执行结果:
PipelineResource
PipelineResource在最后提,因为目前只是alpha版本,何时会进入beta或者弃用目前还是未知数。有兴趣的可以看下这里:Why Aren’t PipelineResources in Beta?
简单来说,PipelineResource可以通过其他的方式实现,而其本身也存在弊端:比如实现不透明,debug有难度;功能不够强;降低了Task的重用性等。
比如git类型的PipelineResource,可以通过workspace和git-clone Task来实现;存储类型的,也可以通过workspace来实现。
这也就是为什么上面介绍workspace的篇幅比较大。个人也偏向于使用workspace,灵活度高;使用workspace的Task重用性强。
参考
云原生 CICD: Tekton Pipeline 实战:https://atbug.com/tekton-trigger-practice
控制 Pod 内容器的启动顺序:https://atbug.com/control-process-order-of-pod-containers
Knative Controller:https://knative.dev/docs/eventing/samples/writing-receive-adapter-source/03-controller
Why Aren’t PipelineResources in Beta?:https://tekton.dev/docs/pipelines/resources/#why-aren-t-pipelineresources-in-beta
文章同步发送到公众号:云编码 (微信号:sevenfeet)。

版权声明: 本文为 InfoQ 作者【张晓辉】的原创文章。
原文链接:【http://xie.infoq.cn/article/e0e8cfde7958c822e3325209c】。文章转载请联系作者。











评论