开源 CI/CD 构建框架 TekTon 的深入剖析
简介
Tekton 是一个功能强大且灵活的Kubernetes 原生开源框架,用于创建持续集成和交付(CI/CD)系统。 关于Tekton, 网上可以搜到很多很多介绍文档,本文主要阐述我对Tekton的实现原理和背后的技术逻辑的一点理解。
tekton.dev
Tekton定义了Task, TaskRun, Pipeline, PipelineRun, PipelineResource 五类核心对象。Tekton通过对Task和Pipeline的抽象,我们可以定义出任意组合的pipeline模板来完成各种各样的CICD任务。通过TaskRun,PipelineRun,PipelineResource可以将这些模板套用到各个实际的项目中。
实现原理
高度抽象的结构化设计使得Tekton具有非常灵活的特性。那么Tekton是如何实现workflow的流转的呢。
Tekton利用Kubernetes的List-Watch机制,在启动时初始化了2个Controller, PipelineRunController和TaskRunController。
PipelineRunController监听PipelineRun对象的变化。在它的reconcile逻辑中,将pipeline中所有的Task构建为一张有向无环图(DAG),通过遍历DAG找到当前可被调度的Task节点创建对应的TaskRun对象。
TaskRunController监听TaskRun对象的变化。在它的reconcile逻辑中将TaskRun和对应Task转化为可执行的Pod,由kubernetes调度执行。利用Kubernetes的OwnerReference机制,pipelinerun own taskrun, taskrun own pod。pod状态变更时触发taskrun的reconcile逻辑,taskrun状态变更时触发pipelinerun的reconcile逻辑。
DAG支持
Tekton对DAG的支持相对比较简单。在Tekton中一个Pipeline就是一张DAG,Pipeline中的多个Task可是DAG中的节点。Task默认并发执行,可以通过 RunAfter 和 From 关键字控制执行顺序。
示例:
- name: lint-repo taskRef: name: pylint resources: inputs: - name: workspace resource: my-repo - name: test-app taskRef: name: make-test resources: inputs: - name: workspace resource: my-repo - name: build-app taskRef: name: kaniko-build-app runAfter: - test-app resources: inputs: - name: workspace resource: my-repo outputs: - name: image resource: my-app-image - name: build-frontend taskRef: name: kaniko-build-frontend runAfter: - test-app resources: inputs: - name: workspace resource: my-repo outputs: - name: image resource: my-frontend-image - name: deploy-all taskRef: name: deploy-kubectl resources: inputs: - name: my-app-image resource: my-app-image from: - build-app - name: my-frontend-image resource: my-frontend-image from: - build-frontend
渲染出的执行顺序为:
| | v v test-app lint-repo / \ v v build-app build-frontend \ / v v deploy-all
相比于Argo等专注在workflow的项目而言,Tekton支持的任务编排方式是非常有限的。常见的循环,递归,重试,超时等待等策略都是没有的。
- 条件判断
Tekton支持 condition 关键字来进行条件判断。Condtion只支持判断当前Task是否执行,不能作为DAG的分支条件来进行动态DAG的渲染。
* condition检查失败(exitCode != 0),task不会被执行,pipelineRun状态不会因为condition检查失败而失败。 * 多个条件之间 “与” 逻辑关系
PipelineResource在Task间数据交换
作为CICD的工具,代码在什么时候Clone到WorkSpace中,如何实现的? Tekton中抽象了PipelineResource进行任务之间的数据交换,GitResource是其中最基础的一种。用法如下。
- 声明一个Git类型的PipelineResource:
kind: PipelineResource metadata: name: skaffold-git-build-push-kaniko spec: type: git params: - name: revision value: v0.32.0 - name: url value: https://github.com/GoogleContainerTools/skaffold
- 在Task中引用这个Resource做为输入:
kind: Task metadata: name: build-push-kaniko spec: inputs: resources: - name: workspace type: git steps: - name: build-and-push image: registry.cn-shanghai.aliyuncs.com/kaniko-project-edas/executor:v0.17.1
- 代码会被clone在/workspace目录。
Tekton是如何处理这些PipelineResource的呢,这就要从Taskrun Controller如何创建Pod说起。
Tekton中一个TaskRun对应一个Pod,每个Pod有一系列init-containers和step-containers组成。init-container中完成认证信息初始化,workspace目录初始化等初始化工作。
在处理step-container时,会根据这个Task引用的资源 Append或者Insert一个step-container来处理对应的输和输出,如下图所示。
Task中Step执行顺序控制
Tekton源自Knative Build,在Knative Build中使用Init-container来串联Steps保证Steps顺序执行,在上面的分析中我们知道Tekton是用Containers来执行Steps,Pod的Containers是并行执行的,Tekton是如何保证Steps执行顺序呢?
这是一个TaskRun创建的Pod的部分描述信息,可以看到所有的Step都是被/tekton/tools/entrypoints封装起来执行的。 -wait_file指定一个文件,通过监听文件句柄,在探测到文件存在时执行被封装的Step任务。 -post_file指定一个文件,在Step任务完成后创建这个文件。通过文件序列/tekton/tools/${index}来对Step进行排序。
- args: - -wait_file - /tekton/tools/0 - -post_file - /tekton/tools/1 - -termination_path - /tekton/termination - -entrypoint - /ko-app/git-init - -- - -url - https://github.com/GoogleContainerTools/skaffold - -revision - v0.32.0 - -path - /workspace/workspace command: - /tekton/tools/entrypoint image: registry.cn-shanghai.aliyuncs.com/kaniko-project-edas/git-init:v0.10.2 name: step-git-source-skaffold-git-build-push-kaniko-rz765 - args: - -wait_file - /tekton/tools/1 - -post_file - /tekton/tools/2 - -termination_path - /tekton/termination - -entrypoint - /kaniko/executor - -- - --dockerfile=Dockerfile - --destination=localhost:5000/leeroy-web - --context=/workspace/workspace/examples/microservices/leeroy-web - --oci-layout-path=$(inputs.resources.builtImage.path) command: - /tekton/tools/entrypoint image: registry.cn-shanghai.aliyuncs.com/kaniko-project-edas/executor@sha256:565d31516f9bb91763dcf8e23ee161144fd4e27624b257674136c71559ce4493 name: step-build-and-push - args: - -wait_file - /tekton/tools/2 - -post_file - /tekton/tools/3 - -termination_path - /tekton/termination - -entrypoint - /ko-app/imagedigestexporter - -- - -images - '[{"name":"skaffold-image-leeroy-web-build-push-kaniko","type":"image","url":"localhost:5000/leeroy-web","digest":"","OutputImageDir":"/workspace/output/builtImage"}]' command: - /tekton/tools/entrypoint image: registry.cn-shanghai.aliyuncs.com/kaniko-project-edas/imagedigestexporter:v0.10.2 name: step-image-digest-exporter-lvlj9
实践
使用Tekton构建代码并部署到SAE
Serverless 应用引擎( SAE ) 是阿里云上一款面向应用的 Serverless PaaS 平台,帮助 PaaS 层用户免运维 IaaS,按需使用,按量计费,实现低门槛微服务应用上云,有效解决成本及效率问题。支持 Spring Cloud、Dubbo 和 HSF 等流行的开发框架,真正实现了 Serverless 架构和微服务架构的完美融合。
接下来将使用Tekton部署一个Spring Cloud微服务应用到SAE平台。
示例中的演示代码地址:https://github.com/alicloud-demo/spring-cloud-demo
-
前置条件
- 定义一个Git资源
apiVersion: tekton.dev/v1alpha1 kind: PipelineResource metadata: name: spring-cloud-demo spec: type: git params: - name: url value: https://github.com/alicloud-demo/spring-cloud-demo
- 定义构建和部署Task
根据SAE官方文档进行部署。
apiVersion: tekton.dev/v1alpha1 kind: Task metadata: name: build-deploy-sae spec: inputs: resources: - name: source type: git steps: - name: build-and-deploy image: maven:3.3-jdk-8 command: ["mvn", "clean", "package", "-f", "source", "toolkit:deploy", "-Dtoolkit_profile=toolkit_profile.yaml", "-Dtoolkit_package=toolkit_package.yaml", "-Dtoolkit_deploy=toolkit_deploy.yaml"] securityContext: runAsUser: 0
- 定义TaskRun运行任务
apiVersion: tekton.dev/v1alpha1 kind: TaskRun metadata: name: build-deploy-sae spec: taskRef: name: build-deploy-sae inputs: resources: - name: source resourceRef: name: spring-cloud-demo
- 导入到kubernetes中运行
kubectl apply -f source-2-service-taskrun.yaml
- 查看日志
kubectl logs build-deploy-sae-pod-85xdk step-build-and-deploy
构建日志:
部署日志:
[INFO] Start to upload [provider3-1.0-SNAPSHOT.jar] using [Sae uploader]. [INFO] [##################################################] 100.0% [INFO] Upload finished in 3341 ms, download url: [https://edas-hz.oss-cn-hangzhou.aliyuncs.com/apps/K8S_APP_ID/37adb12b-5f0c-4711-98ec-1f1e91e6b043/provider3-1.0-SNAPSHOT.jar] [INFO] Begin to trace change order: e2499b9a-6a51-4904-819c-1838c1dd62cb [INFO] PipelineName: Batch: 1, PipelineId:f029314a-88bb-450b-aa35-7cc550ff1329 [INFO] Waiting... [INFO] Waiting... [INFO] Waiting... [INFO] Waiting... [INFO] Waiting... [INFO] Waiting... [INFO] Waiting... [INFO] Waiting... [INFO] Deploy application successfully! [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 32:41 min [INFO] Finished at: 2020-04-15T10:09:39+00:00 [INFO] Final Memory: 47M/190M [INFO] ------------------------------------------------------------------------
- 验证部署结果
在SAE控制台查看变更记录:
验证应用访问:
总结
区别于传统的CICD工具(Jenkins),Tekton是一套构建CICD系统的框架。Tekton不能使你立即获得CICD的能力。但是基于Tekton可以设计出各种花式的构建部署流水线。得益于Tekton良好的抽象,这些设计出的流水线可以作为模板在多个组织,项目间共享。 Tekton源自Knative的Build-Template项目,设计之初的一个重要目标就是使人们能够共享和重用构成pipeline的组件,以及Pipeline本身。在Tekton的RoadMap中Tekton Catelog就是为了实现这一目标而提出的。
区别于Argo这种基于Kubernetes的Workflow工具,Tekton在工作流控制上的支持是比较弱的。一些复杂的场景比如循环,递归等都是不支持的。更不用说Argo在高并发和大集群调度下的性能优化。这和Tekton的定位有关,Tekton定位于实现CICD的框架,对于CICD不需要过于复杂的流程控制。大部分的研发流程可以被若干个最佳实践来覆盖。而这些最佳实践应该也必须可以在不同的组织间共享,为此Tekton设计了PipelineResource的概念。PipelineResource是Task间交互的接口,也是跨平台跨组织共享重用的组件,在PipelineResource上还可以有很多想象空间。
作者信息:九辩,阿里巴巴高级开发工程师,负责阿里云EDAS(企业级分布式应用服务)应用生命周期研发工作,长期关注云时代微服务的部署和治理工作。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
架构设计 | 分布式系统调度,Zookeeper集群化管理
一、框架简介 1、基础简介 Zookeeper基于观察者模式设计的组件,主要应用于分布式系统架构中的,统一命名服务、统一配置管理、统一集群管理、服务器节点动态上下线、软负载均衡等场景。 Linux下Zookeeper单节点安装 SpringBoot整合Zookeeper中间件 2、集群选举 Zookeeper集群基于半数机制,集群中半数以上机器存活,集群处于可用状态。所以建议Zookeeper集群安装为奇数台服务器。在集群的配置文件中并没有指定Master和Slave。在Zookeeper工作时,是有一个节点为Leader,其他则为Follower,Leader是通过内部的选举机制临时产生的。 基本描述 假设有三台服务器组成的Zookeeper集群,每个节点的myid编号依次1-3,依次启动服务器,会发现server2被选择为Leader节点。 server1启动,执行一次选举。服务器1投自己一票。此时服务器1票数一票,未达到半数以上(2票),选举无法完成,服务器1状态保持为LOOKING; server2启动,再执行一次选举。服务器1和2分别投自己一票,并交换选票信息,因为服务器2的...
- 下一篇
Arthas 征文活动第一期中奖名单揭晓!
为了让更多开发者开始用上 Arthas 这个Java 诊断神器,3 月 26 日,我们联合 JetBrains 推出第一期 Arthas 有奖征文活动,聊聊这些年你和 Arthas 之间的那些事儿。第一期征文活动于 3 月 26 日—— 4 月 26 日举办,后续征文活动将持续至 2020 年 12 月。 一石激起千层浪,在第一期活动期间我们得到了众多开发者的积极响应,闻讯赶来投稿的同学络绎不绝,截止到 4 月 26 日,第一期征文活动已结束,经过层层挑选与评估,以下为第一期征文活动的获奖情况: 最受欢迎 Top3:将在Arthas Most Valuable User福袋的基础上另送出天猫精灵一台。 优秀参与奖:凡提交满足第一期投稿要求文章的同学,将获得 Arthas Most Valuable User 福袋一份,包含淘公仔、A
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS7,CentOS8安装Elasticsearch6.8.6
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- CentOS6,CentOS7官方镜像安装Oracle11G
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- 设置Eclipse缩进为4个空格,增强代码规范
- Mario游戏-低调大师作品
- MySQL8.0.19开启GTID主从同步CentOS8