研发效能领域洞察 | Google 捐赠 CDF tektoncd/pipeline 项目解析

栏目: 编程工具 · 发布时间: 5年前

内容简介:作者简介致信

研发效能领域洞察系列

蚂蚁研发效能特别整合推出 研发效能领域洞察 系列文章,带来蚂蚁金服对于研发效能领域前沿技术的思考和探索。

今年 3 月持续交付基金会(CDF)正式成立, Tekton  作为谷歌捐赠的 CDF 重要项目 ,是一组用于构建 CI/CD 系统的共享开源组件,与 Kubernetes 紧密相连。今天的内容将为大家带来 tektoncd/pipeline 项目的全方位解析。

作者简介 

研发效能领域洞察 | Google 捐赠 CDF tektoncd/pipeline 项目解析

致信

蚂蚁金服  开发工程师

陈泽锋,花名致信,蚂蚁金服研发效能部开发工程师,主要从事 DevOps 平台构建系统的研发工作,在应用与容器的构建、构建依赖扫描与缓存、构建系统云原生化等方面具有丰富的实战经验。

研发效能领域洞察 | Google 捐赠 CDF tektoncd/pipeline 项目解析

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 所捐赠。

研发效能领域洞察 | Google 捐赠 CDF tektoncd/pipeline 项目解析

紧接着,在 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 往往会包括代码版本控制、构建、单元测试、部署、自动化集成测试、部署等步骤。

研发效能领域洞察 | Google 捐赠 CDF tektoncd/pipeline 项目解析

对于运行在 K8s 环境下的 pipeline 而已, 从业务的角度 看各个阶段的职责本身不会有本质的变化; 从技术架构的角度看 ,基于容器的调度编排得到的 pipeline,优势慢慢显示出来的。

一方面每个阶段,也可以说一个 Task,是使用容器来表达的。 众所周知,容器对于应用运行环境的打包、逻辑隔离是杠杠的,这除了有利于每个Task职责的单一外,也有利于pipeline的稳定运行。 另一方面,则是 severless 化的架构有利于机器资源的释放、业务成本的节约。

研发效能领域洞察 | Google 捐赠 CDF tektoncd/pipeline 项目解析

带着问题如何配置来对该 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: 

研发效能领域洞察 | Google 捐赠 CDF tektoncd/pipeline 项目解析

研发效能领域洞察 | Google 捐赠 CDF tektoncd/pipeline 项目解析

当 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/

如果还想要了解更多,这里有更多研发效能内容推荐:

如何通过数据赋能提升企业研发效能?

点击查看原文:《 研发洞察:如何用数据驱动效能提升? | 解密蚂蚁研发效能

蚂蚁金服是如何思考和探索下一代容器镜像构建技术的?

点击查看原文:《 研发效能领域洞察 | 容器镜像构建技术存在的弊端与未来

研发效能领域洞察 | Google 捐赠 CDF tektoncd/pipeline 项目解析

长按识别二维码关注我们

封面图素材 Designed by starline / Freepik


以上所述就是小编给大家介绍的《研发效能领域洞察 | Google 捐赠 CDF tektoncd/pipeline 项目解析》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

数学建模

数学建模

[美] Frank R.Giordano,Maurice D.Weir,William P.Fox / 机械工业出版社 / 2004-1 / 45.00元

数学建模是用数学方法解决各种实际问题的桥梁。本书分离散建模(第1~9章)和连续建模(第10~13章)两部分介绍了整个建模过程的原理,通过本书的学习,学生将**会在创造性模型和经验模型的构建、模型分析以及模型研究方面进行实践,增强解决问题的能力。 ·论证了离散动力系统,离散优化等技术对现代应用数学的发展的促进作用。 ·在创造性模型和经验模型的构建、模型分析以及模型研究中融入个人项目和小组......一起来看看 《数学建模》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

URL 编码/解码
URL 编码/解码

URL 编码/解码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换