内容简介:作者简介致信
研发效能领域洞察系列
蚂蚁研发效能特别整合推出 研发效能领域洞察 系列文章,带来蚂蚁金服对于研发效能领域前沿技术的思考和探索。
今年 3 月持续交付基金会(CDF)正式成立, Tekton 作为谷歌捐赠的 CDF 重要项目 ,是一组用于构建 CI/CD 系统的共享开源组件,与 Kubernetes 紧密相连。今天的内容将为大家带来 tektoncd/pipeline 项目的全方位解析。
作者简介
致信
蚂蚁金服 开发工程师
陈泽锋,花名致信,蚂蚁金服研发效能部开发工程师,主要从事 DevOps 平台构建系统的研发工作,在应用与容器的构建、构建依赖扫描与缓存、构建系统云原生化等方面具有丰富的实战经验。
01
背景
在 3 月 12 日 举办的 Linux 基金会在开源领导力峰会(Open Source Leadership Summit)上, 持续交付基金会(Continuous Delivery Foundation,CDF) 宣布成立。全新的持续交付基金会将致力于使企业在多个 CI / CD 平台上更轻松地构建和复用 DevOps 管道。
持续交付基金会的使命是 发展和维护一个开放的持续交付生态系统 ,与云原生计算基金会(CNCF)性质相同。其中,首批捐赠给 CDF 的项目包括 Jenkins、Jenkins X、Tekton 以及 Netflix 的持续交付工具 Spinnaker,其中 Tekton 为 Google 所捐赠。
紧接着,在 4.9 - 4.11 的 Google cloud next 19 大会 Next Generation CI/CD with GKE and Tekton 章节上,Tekton 的核心作者 bobcatfish 就对 tektoncd/pipeline 的设计和使用进行了介绍,并且邀请了使用 Tekton 作为底层依赖的 Jenkins-X 和 TriggerMesh 的相关负责人进行站台。感兴趣的同学可以观看 录播传送门 ¹ 。
02
Tektoncd Pipeline
通过背景了解,可以看到 Tekton 对于 CDF 中的重要性 ,下面将围绕 Tektoncd Pipeline 展开详细介绍:
What : A K8s-native Pipeline resource
1. 云原生化(Cloud Native):
-
采用声明式 API,运行在 K8s 上
-
使用容器作为 build block (Task 由一组 Step(Container) 组成)
-
将 K8s cluster 作为头等类型
2. 解耦(Decoupled):
-
Task/Pipeline 一次定义、任意 K8s 群集部署
-
组成 Pipeline 的 Task 可以单独运行
-
Git repos、Storage(Gcs、Oss)存储等资源可以在任务间轻松交换
3. 类型化(Typed):
-
意味着对于诸如 Image 之类的资源,可以轻松地在 Task 之间交换实现(目前支持 还比较弱)
How : Interacts with Tektoncd Pipeline
前置条件: 一个可运行的 K8s 集群(如本地minikube),部署 Tektoncd 参考 ²
部署步骤中 Tektoncd 已经将所有需要声明的 yaml 打包在 release.yaml,所以关键执行语句是 :
kubectl apply --filename https://storage.googleapis.com/knative-releases/build-pipeline/latest/release.yaml
部署状态检查: 当观察到 webhook 和 controller 两个容器都属于 Running 状态,则框架部署就成功了。
kubectl get pods -n tekton-pipelines
➜ [/Users/user/k8s] git:(master) kubectl get pod -n tekton-pipelines NAME READY STATUS RESTARTS AGE tekton-pipelines-controller-7b5c6fb498-xwhgh 1/1 Running 0 3d tekton-pipelines-webhook-799cb595db-7v8vs 1/1 Running 0 3d
Tektoncd Pipeline 概念介绍
如下所示,软件开发过程中,一个 pipeline 往往会包括代码版本控制、构建、单元测试、部署、自动化集成测试、部署等步骤。
对于运行在 K8s 环境下的 pipeline 而已, 从业务的角度 看各个阶段的职责本身不会有本质的变化; 从技术架构的角度看 ,基于容器的调度编排得到的 pipeline,优势慢慢显示出来的。
一方面每个阶段,也可以说一个 Task,是使用容器来表达的。 众所周知,容器对于应用运行环境的打包、逻辑隔离是杠杠的,这除了有利于每个Task职责的单一外,也有利于pipeline的稳定运行。 另一方面,则是 severless 化的架构有利于机器资源的释放、业务成本的节约。
带着问题如何配置来对该 pipeline 进行表达呢?
此时,就该引出Tektoncd 的几个核心 Api 对象了,关键对象定义分为 Task、PipelineResource、Pipeline 模板一类,还有 TaskRun、PipelineRun 等运行时配置一类。其中 TaskRun 依赖 Task( 指定 ref 或 taskSpec),PipelineRun 依赖 Pipeline(指定ref),职责描述定义如下:
Name |
职责Task |
Pipelineresource |
Task/Pipeline 入参、出参的抽象接口,默认支持 git、image、 storage、cluster 四种类型 各自有特定的必须字段,如 url、revision 等,它们通常在运行时被映射为 pod 里的一个 container |
Task |
单个任务的定义模板,其中 steps 资源映射为 K8s 的 pod 对象,包括入参出参资源的定义等 |
TaskRun |
任务实例,可通过 taskRef 对 Task 进行关联,或者直接由 taskSpec 进行注入 trigger 分为 manual / pipelineRun 两种类型 |
Pipeline |
流水线,可以按特定的顺序编排 n(>=1)个 Task,组成一个 dag(有向不循环图) |
PipelineRun |
流水线实例,可以通过 pipelineRef 对 Pipeline 进行关联 trigger 只有 manual 类型 |
Task
任务可以单独存在,也可以作为 pipeline 的一部分。每个任务都在k8s集群上作为Pod运行,每个步骤都声明了自己的容器。如下这里 steps 字段映射 k8s corev1 中的 container 数组字段,也就是说每个任务需要把执行的逻辑封装到一个 image,再指定 command 和 args。
apiVersion: tekton.dev/v1alpha1 kind: Task metadata: namespace: tekton-pipelines name: echo-hello-world spec: steps: - name: echo image: ubuntu command: - echo args: - "hello world" - name: echo-1 image: ubuntu command: - echo args: - "hello world-1"
运行效果:
➜ [/Users/user/k8s/knative/tasks] git:(master) ✗ kubectl apply -f task.yaml task.tekton.dev "echo-hello-world" created
Tips: Task 必须指定command,否则会导致 controller 获取不到 container entrypoint,进而导致拉起 task 失败。
TaskRun
这个时候,虽然我们提交了 Task 对象到 K8s 里,但是 Tektoncd 并不会拉起一个 Task 实例。
上面也有提到,Task 对象仅仅作为模板配置。接下来, 通过配置 TaskRun 来触发这个Task对象。
apiVersion: tekton.dev/v1alpha1 kind: TaskRun metadata: namespace: tekton-pipelines name: echo-hello-world-task-run spec: taskRef: name: echo-hello-world trigger: type: manual
运行效果:
➜ [/Users/user/k8s/knative/tasks] git:(master) ✗ kubectl apply -f taskrun.yaml taskrun.tekton.dev "echo-hello-world-task-run" created ➜ [/Users/user/k8s/knative/tasks] git:(master) ✗ kubectl get pod -n tekton-pipelines NAME READY STATUS RESTARTS AGE echo-hello-world-task-run-pod-15631a 0/1 Init:2/3 0 8d ➜ [/Users/user/k8s/knative/taskrun] git:(master) ✗ kubectl get pod/echo-hello-world-task-run-pod-15631a -n tekton-pipelines -o yaml apiVersion: v1 kind: Pod metadata: creationTimestamp: 2019-03-28T15:41:53Z labels: tekton.dev/task: echo-hello-world tekton.dev/taskRun: echo-hello-world-task-run name: echo-hello-world-task-run-pod-15631a namespace: tekton-pipelines ownerReferences: - apiVersion: tekton.dev/v1alpha1 blockOwnerDeletion: true controller: true kind: TaskRun name: echo-hello-world-task-run uid: 02684736-5170-11e9-80eb-b6729aa295ab resourceVersion: "646847" selfLink: /api/v1/namespaces/tekton-pipelines/pods/echo-hello-world-task-run-pod-15631a uid: 026ad82d-5170-11e9-80eb-b6729aa295ab spec: containers: - args: - -wait_file - "" - -post_file - /builder/tools/0 - -entrypoint - echo - -- - hello world command: - /builder/tools/entrypoint env: - name: HOME value: /builder/home image: ubuntu imagePullPolicy: Always name: build-step-echo resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /builder/tools name: tools - mountPath: /workspace name: workspace - mountPath: /builder/home name: home - mountPath: /var/run/secrets/kubernetes.io/serviceaccount name: default-token-4c8qb readOnly: true workingDir: /workspace - args: - -wait_file - /builder/tools/0 - -post_file - /builder/tools/1 - -entrypoint - echo - -- - hello world-1 command: - /builder/tools/entrypoint env: - name: HOME value: /builder/home image: ubuntu imagePullPolicy: Always name: build-step-echo-1 resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /builder/tools name: tools - mountPath: /workspace name: workspace - mountPath: /builder/home name: home - mountPath: /var/run/secrets/kubernetes.io/serviceaccount name: default-token-4c8qb readOnly: true workingDir: /workspace - command: - /ko-app/nop image: gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/nop@sha256:edf92a9d7e6f74cdc4a61b0ac62458d82e95e3786e479b789f41ffea67783183 imagePullPolicy: IfNotPresent name: nop resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /var/run/secrets/kubernetes.io/serviceaccount name: default-token-4c8qb readOnly: true dnsPolicy: ClusterFirst initContainers: - command: - /ko-app/creds-init env: - name: HOME value: /builder/home image: gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/creds-init@sha256:dd7e347128e0dd1f80e4e419606fa1e204bc7b98fc981d74f068c192df26c410 imagePullPolicy: IfNotPresent name: build-step-credential-initializer-z22bb resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /workspace name: workspace - mountPath: /builder/home name: home - mountPath: /var/run/secrets/kubernetes.io/serviceaccount name: default-token-4c8qb readOnly: true workingDir: /workspace - args: - -c - cp /ko-app/entrypoint /builder/tools/entrypoint command: - /bin/sh env: - name: HOME value: /builder/home image: gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/entrypoint@sha256:6eaa3e12f13089d2eab2072d5eaf789e1f2001565901b963034333f3dde21b3f imagePullPolicy: IfNotPresent name: build-step-place-tools resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /builder/tools name: tools - mountPath: /workspace name: workspace - mountPath: /builder/home name: home - mountPath: /var/run/secrets/kubernetes.io/serviceaccount name: default-token-4c8qb readOnly: true workingDir: /workspace nodeName: minikube priority: 0 restartPolicy: Never schedulerName: default-scheduler securityContext: {} serviceAccount: default serviceAccountName: default terminationGracePeriodSeconds: 30 tolerations: - effect: NoExecute key: node.kubernetes.io/not-ready operator: Exists tolerationSeconds: 300 - effect: NoExecute key: node.kubernetes.io/unreachable operator: Exists tolerationSeconds: 300 volumes: - emptyDir: {} name: tools - emptyDir: {} name: workspace - emptyDir: {} name: home - name: default-token-4c8qb secret: defaultMode: 420 secretName: default-token-4c8qb status: phase: Succeeded podIP: 172.17.0.10 qosClass: BestEffort startTime: 2019-03-28T15:41:53Z ....
上面有一段由 Tektoncd 拉起的 taskrun 对应的 pod 的 yaml 字段,从中我们可以看到:
1. 默认生成的 labels 标签,有利于我们在代码里通过调用 pod 的 list 接口,设置 label 参数来获取生成的 pod 详情:
tekton.dev/task: echo-hello-world
tekton.dev/taskRun: echo-hello-world-task-run
2. 这个 pod 包含了 initContainers 和 containers ,其中
initContainers 的镜像为 :
gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/creds-init
gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/entrypoint
containers镜像为 :
ubuntu
ubuntu
gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/nop
并且 ubuntu 镜像的参数 command 变成了 /builder/tools/entrypoint , args 有 -wait_file -post_file -entrypoint 等参数(entrypoint 包装了用户指定的 command,用 file 生成顺序来控制 steps 的执行顺序)
3. 通过 volumes 字段,还可以看到工作目录 workspace 和 /builder/home 目录等信息
看到这里,读者对单个 taskRun 生成的 pod 对象应该有了一定的了解。 (Tektoncd 通过包装 entrypoint+wait/post file 的机制来控制容器按照特定顺序执行,最后通过 nop container 输出一行日志作为任务的结束。)
Task steps 指定镜像 ubuntu 日志:
➜ [/Users/user/k8s/knative/taskrun] git:(master) ✗ kubectl logs echo-hello-world-task-run-pod-15631a -c build-step-echo -n tekton-pipelines hello world ➜ [/Users/user/k8s/knative/taskrun] git:(master) ✗ kubectl logs echo-hello-world-task-run-pod-15631a -c build-step-echo-1 -n tekton-pipelines hello world-1
nop 日志:
➜ [/Users/zefeng.czf/k8s/knative/tasks] git:(master) ✗ kubectl logs echo-hello-world-task-run-pod-15631a -n tekton-pipelines Build successful
Pipelineresource
目前为止,上面演示了一个非常简单的 Task,指定容器输出一串字符串。在实际工程中,没有入参和出参的任务几乎是不存在的。PipelinesResources 用于定义在任务间流转的 Resource, 默认支持 git、image、 storage、cluster 四中类型,各自有特定的必须字段。
git |
url git 代码库地址 revision (可选)branch或commitId,默认master targetPath (可选)下载代码库到容器里的path |
image |
url image地址 digest image (可选)签名值 |
storage |
默认只支持 gcs 的存储,如果要支持oss的等存储需要扩展一个类型出来 |
cluster |
用于 deploy 到 K8s 任意 ns 使用,因与 Build/Ci 无关,暂不梳理 |
demo
apiVersion: tekton.dev/v1alpha1 kind: PipelineResource metadata: name: git-source namespace: tekton-pipelines spec: type: git params: - name: revision value: master - name: url value: https://github.com/cccfeng/tekton-source.git # 替换你自己的代码库
如何使用定义好的 resource 呢?我们依旧需要先定一个 Task 模板:
apiVersion: tekton.dev/v1alpha1 kind: Task metadata: name: build-docker-image-from-git-source namespace: tekton-pipelines spec: inputs: resources: - name: docker-source type: git params: - name: pathToDockerFile default: Dockerfile - name: pathToContext default: /workspace/docker-source outputs: resources: - name: builtImage type: image steps: - name: build-and-pushgi image: docker.io/antblugeng/tekton-pipeline-test:buildkit # 替换自己的buildctl image command: ["/buildkit.sh"] args: - --workspace - ${inputs.params.pathToContext} - --buildkit_host - tcp://buildkitd.server.xxxx.net:1234 # 替换自己的buildkitd server域名 - --filename - ${inputs.params.pathToDockerFile} - --context - . - --dockerfile - . - --name - docker.io/antblugeng/tekton-pipeline-test:buildkit-test-0.0.1 - --push - "true"
接着定义一个 TaskRun 来触发
apiVersion: tekton.dev/v1alpha1 kind: TaskRun metadata: name: build-docker-image-from-git-source-task-run namespace: tekton-pipelines spec: serviceAccount: build-bot taskRef: name: build-docker-image-from-git-source trigger: type: manual inputs: resources: - name: docker-source resourceRef: name: git-source params: - name: pathToDockerFile value: Dockerfile - name: pathToContext value: /workspace/docker-source #configure: may change according to your source outputs: resources: - name: builtImage resourceRef: name: knative-pipeline-test-image
运行效果:
➜ [/Users/user] kubectl logs -n tekton-pipelines build-docker-image-from-git-source-task-run-pod-01b21c -c build-step-git-source-git-source-jrbxn {"level":"warn","ts":1557717305.086845,"logger":"fallback-logger","caller":"logging/config.go:65","msg":"Fetch GitHub commit ID from kodata failed: \"ref: refs/heads/master\" is not a valid GitHub commit ID"} {"level":"info","ts":1557717309.9012158,"logger":"fallback-logger","caller":"git-init/main.go:100","msg":"Successfully cloned \"https://github.com/cccfeng/tekton-source.git\" @ \"master\" in path \"/workspace/docker-source\""} ➜ [/Users/user] kubectl logs -n tekton-pipelines build-docker-image-from-git-source-task-run-pod-01b21c -c build-step-build-and-pushgi time="2019-05-13T03:15:10Z" level=info msg="found worker "ubkkw3a71vixufz3lxdislw9w", labels=map[org.mobyproject.buildkit.worker.executor:oci org.mobyproject.buildkit.worker.snapshotter:native org.mobyproject.buildkit.worker.hostname:build-docker-image-from-git-source-task-run-pod-01b21c], platforms=[linux/amd64]" time="2019-05-13T03:15:10Z" level=warning msg="skipping containerd worker, as "/run/containerd/containerd.sock" does not exist" time="2019-05-13T03:15:10Z" level=info msg="found 1 workers, default="ubkkw3a71vixufz3lxdislw9w"" time="2019-05-13T03:15:10Z" level=warning msg="currently, only the default worker can be used." time="2019-05-13T03:15:10Z" level=info msg="running server on [::]:1234" export BUILDKIT_HOST=tcp://buildkitd.server.xxxx.net:1234 buildctl build --exporter=image --frontend dockerfile.v0 --frontend-opt filename=Dockerfile --local context=. --local dockerfile=. --exporter-opt name=docker.io/antblugeng/tekton-pipeline-test:buildkit-test-0.0.1 --exporter-opt push=true #1 [internal] load .dockerignore #1 digest: sha256:f49a51af104124b84f290288c3c75d630abc40e4c9c142d7add81d4a5bc27a25 #1 name: "[internal] load .dockerignore" #1 started: 2019-05-13 03:15:13.729899957 +0000 UTC #1 completed: 2019-05-13 03:15:13.729978457 +0000 UTC #1 duration: 78.5µs #1 started: 2019-05-13 03:15:13.730257148 +0000 UTC #1 transferring context: 2B 0.1s done #1 completed: 2019-05-13 03:15:13.819507582 +0000 UTC #1 duration: 89.250434ms #2 [internal] load build definition from Dockerfile #2 digest: sha256:e8e4774ce400b75e6256d4d244ab708ca0605ec70ca1bdb12906706b2f8b9bcf #2 name: "[internal] load build definition from Dockerfile" #2 started: 2019-05-13 03:15:13.729897877 +0000 UTC #2 completed: 2019-05-13 03:15:13.729971834 +0000 UTC #2 duration: 73.957µs #2 started: 2019-05-13 03:15:13.730138087 +0000 UTC #2 completed: 2019-05-13 03:15:13.849126781 +0000 UTC #2 duration: 118.988694ms #2 transferring dockerfile: 79B 0.1s done #3 [internal] load metadata for docker.io/library/nginx:1.15.12-alpine #3 digest: sha256:3911acdeaf648ee164999d40fde38263bb1a03c0cbebb29b3932ba71048579c3 #3 name: "[internal] load metadata for docker.io/library/nginx:1.15.12-alpine" #3 started: 2019-05-13 03:15:13.85020833 +0000 UTC #3 completed: 2019-05-13 03:15:16.892017103 +0000 UTC #3 duration: 3.041808773s #4 [1/1] FROM docker.io/library/nginx:1.15.12-alpine@sha256:57a226fb6ab6823... #4 digest: sha256:187fe5addd338c7a02eaa25913f5f94242636ffe65e40af51abf0f773962ea58 #4 name: "[1/1] FROM docker.io/library/nginx:1.15.12-alpine@sha256:57a226fb6ab6823027c0704a9346a890ffb0cacde06bc19bbc234c8720673555" #4 started: 2019-05-13 03:15:16.892851886 +0000 UTC #4 completed: 2019-05-13 03:15:16.893075441 +0000 UTC #4 duration: 223.555µs #4 started: 2019-05-13 03:15:16.893252939 +0000 UTC #4 completed: 2019-05-13 03:15:16.893307047 +0000 UTC #4 duration: 54.108µs #4 cached: true #4 resolve docker.io/library/nginx:1.15.12-alpine@sha256:57a226fb6ab6823027c0704a9346a890ffb0cacde06bc19bbc234c8720673555 done #5 exporting to image #5 digest: sha256:d70d658f4575e85b83973504e7dd9ca8b44b17f3762aad0ea28cc51661d09c15 #5 name: "exporting to image" #5 started: 2019-05-13 03:15:16.893354938 +0000 UTC #5 exporting layers done #5 exporting manifest sha256:b20ab2f41ceae8a3cca2db4ff5a2e8c801d4bc35d0f86e5050d46493e62d9ca0 done #5 exporting config sha256:bfe3543077fbf17f57016f39089d53eac42d9d411fabdd06ae1c7bae8b726981 done #5 pushing layers #5 pushing layers 5.7s done #5 pushing manifest for docker.io/antblugeng/tekton-pipeline-test:buildkit-test-0.0.1 #5 completed: 2019-05-13 03:15:23.367185755 +0000 UTC #5 duration: 6.473830817s #5 pushing manifest for docker.io/antblugeng/tekton-pipeline-test:buildkit-test-0.0.1 0.7s done
可以看到 Task 先执行了 git 库的拉取动作,再执行的 buildkit 指令,打出了 imageId: docker.io/antblugeng/tekton-pipeline-test:buildkit-test-0.0.1
Pipeline
目前我们已经走通 Task/TaskRun/PipelineResource 组合的一种类型,但是单个任务表达的能力有限, Tektoncd 是如何支持 Task 之间的编排、产物之间的传递的呢? 事实上,一个 Pipeline 的定义也恰恰是由一组 Task 和 Resources(input&output)组成。
apiVersion: tekton.dev/v1alpha1 kind: Pipeline metadata: name: tutorial-pipeline namespace: tekton-pipelines spec: resources: - name: pipeline-source-repo type: git - name: pipeline-web-image type: image tasks: - name: build-skaffold-web taskRef: name: build-docker-image-from-git-source resources: inputs: - name: docker-source resource: pipeline-source-repo outputs: - name: builtImage resource: pipeline-web-image - name: deploy-web taskRef: name: deploy-using-kubectl resources: inputs: - name: pipeline-t-workspace resource: pipeline-source-repo - name: image resource: pipeline-web-image from: - build-skaffold-web params: - name: path value: /workspace/pipeline-t-workspace/deployment.yaml #configure: may change according to your source
这里 Pipeline 的 spec 字段中定义了 resources,分别为 git 和 image 类型,这是一共需要定义的入参。
在 tasks 数组里,我们可以看到 build-docker-image-from-git-source 定义了 input 和 output 两种资源,其中 input 为 git 代码库,output 为 image 类型;后一个 task deploy-web 则定义了 input 资源为 git 代码库和 image 两种。
注意:resource: web-image 下面多了一个 from 数组参数,值是上一个 pipeline task 的名称。这表示着第二个任务的 image 资源来自第一个任务的产物输出,也就是 pipeline 在执行时,会确保 deploy-web 在 build-skaffold-web 完成之后执行。
Tips:deploy-using-kubectl task 定义如下:
apiVersion: tekton.dev/v1alpha1 kind: Task metadata: namespace: tekton-pipelines name: deploy-using-kubectl spec: inputs: resources: - name: pipeline-t-workspace type: git - name: image type: image params: - name: path description: Path to the manifest to apply steps: - name: run-kubectl image: lachlanevenson/k8s-kubectl command: ["kubectl"] args: - "apply" - "-f" - "${inputs.params.path}"
PipelineRun
和 Task 一致,Pipeline 定义的是只是模板。 如果想到将 Pipeline 资源运行起来,需要定义 PipelineRun 进行触发。
apiVersion: tekton.dev/v1alpha1 kind: PipelineRun metadata: name: tutorial-pipeline-run-1 namespace: tekton-pipelines spec: serviceAccount: build-bot pipelineRef: name: tutorial-pipeline trigger: type: manual resources: - name: pipeline-source-repo resourceRef: name: git-source - name: pipeline-web-image resourceRef: name: knative-pipeline-test-image
运行效果:
code 仓库中 dockerfile 内容 :
FROM docker.io/nginx:1.15.12-alpine code仓库 deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: namespace: tekton-pipelines name: nginx-deployment spec: selector: matchLabels: app: nginx replicas: 1 template: metadata: labels: app: nginx spec: containers: - name: nginx image:docker.io/nginx:1.15.12-alpine ports: - containerPort: 80
输出日志:
➜ [/Users/zefeng.czf/k8s/knative/pipeline] git:(master) ✗ kubectl apply -f pipelinerun.yaml pipelinerun.tekton.dev "tutorial-pipeline-run-1" created tutorial-pipeline-run-1-build-skaffold-web-9jm59-pod-6f0480 0/3 Pending 0 1s tutorial-pipeline-run-1-build-skaffold-web-9jm59-pod-6f0480 0/3 Pending 0 1s tutorial-pipeline-run-1-build-skaffold-web-9jm59-pod-6f0480 0/3 Pending 0 3s tutorial-pipeline-run-1-build-skaffold-web-9jm59-pod-6f0480 0/3 Init:0/2 0 3s tutorial-pipeline-run-1-build-skaffold-web-9jm59-pod-6f0480 0/3 Init:1/2 0 4s tutorial-pipeline-run-1-build-skaffold-web-9jm59-pod-6f0480 0/3 PodInitializing 0 5s tutorial-pipeline-run-1-build-skaffold-web-9jm59-pod-6f0480 2/3 Completed 0 6s tutorial-pipeline-run-1-build-skaffold-web-9jm59-pod-6f0480 1/3 Completed 0 10s tutorial-pipeline-run-1-build-skaffold-web-9jm59-pod-6f0480 0/3 Completed 0 22s tutorial-pipeline-run-1-deploy-web-br6qm-pod-3ee8d4 0/3 Pending 0 0s tutorial-pipeline-run-1-deploy-web-br6qm-pod-3ee8d4 0/3 Pending 0 0s tutorial-pipeline-run-1-deploy-web-br6qm-pod-3ee8d4 0/3 Init:0/2 0 0s tutorial-pipeline-run-1-deploy-web-br6qm-pod-3ee8d4 0/3 Init:1/2 0 2s tutorial-pipeline-run-1-deploy-web-br6qm-pod-3ee8d4 0/3 PodInitializing 0 3s nginx-deployment-57686978c6-n4crh 0/1 Pending 0 1s nginx-deployment-57686978c6-n4crh 0/1 Pending 0 1s nginx-deployment-57686978c6-n4crh 0/1 ContainerCreating 0 1s tutorial-pipeline-run-1-deploy-web-br6qm-pod-3ee8d4 0/3 Completed 0 13s
➜ [/Users/zefeng.czf/k8s/knative/taskrun] git:(master) ✗ kubectl logs -f pod/tutorial-pipeline-run-1-deploy-web-br6qm-pod-3ee8d4 -c build-step-run-kubectl -n tekton-pipelines
deployment.apps/nginx-deployment created
K8s dashboard:
当 Pipeline 拉起时,build-skaffold-web 任务会先执行,负责code2image的逻辑;build-skaffold-web 任务运行完时,deploy-web开始执行,根据中定义的yaml地址进行 /workspace/pipeline-t-workspace/deployment.yaml 执行 kubectl apply动作。
注意授权操作,如果使用的git/docker registry是私有权限的,则需要先初始化相关的账号设置, 参考 ³。
03
项目探讨与总结
到此,我们走通了 Tektoncd 中 Task 和 Pipeline 两种实例的场景。可以很明确地洞察其中的 优劣势 :
优势:
-
Pipeline 云原生化,声明式API,底层使用k8s作为执行引擎,充分发挥 K8s 的优势;
-
资源定义、模板定义与运行实例分离,职责比较分明,有利于资源、模板等重复使用;
-
资源作为任务输入与输出,可以在任务间传递,减少性能损耗;
-
CDF + Google 的背书,社区关注度不断增高;定位为被集成方,支撑 Jenkins-X、TriggerMesh 等大牌 CI/CD产商。
劣势:
-
作为pipeline基础设施,tekton的复杂度较高,强大扩展性导致原生对象的定义稍显复杂,新手友好度稍低;
-
基于tekton的进行pipeline功能开发,要求用户适配 pipeline/task 生成、运行日志、状态等数据的采集和处理;如果只是简单使用 pipeline 编排的功能,可以直接对接到如 Jenkins-X 等上层框架上。
在蚂蚁金服, 下一代持续交付架构要面向云原生化设计 ,与此同时 tektoncd/pipeline 本身就是 cloud native 的。未来蚂蚁会将 Build/Ci/Pipeline 等底层执行节点迁移到基于 tekton体系上,利用 K8s 弹性获取资源(serverless)的能力,提高资源的利用率;
另一方面, 持续交付架构需要提供强大的任务/流水线编排能力。基于 Tektoncd 的扩展性,新的架构保障了上层业务方各式各样需求接入的灵活性。
附录
1. [录播传送门]:
https://www.youtube.com/watch?v=TQJ_pdTxZr0
2. [参考2】:
https://github.com/tektoncd/pipeline/blob/master/docs/install.md
3. [参考3]:
https://github.com/tektoncd/pipeline/blob/master/docs/auth.md
相关文章
1. [持续交付基金会成立!Jenkins,Spinnaker 等为首批捐赠项目]:
https://www.infoq.cn/article/zC*WgWdSyqsj2MKKRoFD
2. [Tektoncd Pipeline Hello World Tutorial]:
https://github.com/tektoncd/pipeline/blob/master/docs/tutorial.md
3. [Tektoncd pipeline 教程 - Kubernetes 原生 Pipeline]:
https://sealyun.com/post/tektoncd-pipeline/
如果还想要了解更多,这里有更多研发效能内容推荐:
点击查看原文:《 研发效能领域洞察 | 容器镜像构建技术存在的弊端与未来 》
长按识别二维码关注我们
封面图素材 Designed by starline / Freepik
以上所述就是小编给大家介绍的《研发效能领域洞察 | Google 捐赠 CDF tektoncd/pipeline 项目解析》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 数据全景洞察概念简介
- 洞察敏捷模型
- Gitcoin 是什么?一起来参与 COVID-19 公益捐赠!
- WordPress 捐赠插件漏洞,导致网站遭受零日攻击
- 洞察设计模式的底层逻辑
- 锤子科技 480 万门票收入捐赠给 OpenSSL 与 OpenBSD
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。