文章目录
- 1. 官方介绍
- 2. 组件
- 2.1 Tekton Pipelines
- 2.2 部署pipeline
- 2.3 部署dashborad
- 2.3.1 task
- 2.3.2 taskrun
- 2.3.3 Pipeline
- 2.3.4 PipelineRun
- 3. 案例
- 案例1: 拉取代码并查看readme
- step1: 创建task - 拉取代码
- step2: 创建task - 查看reamde
- step3: 创建task的编排 - pipeline
- step4: 创建secrets - ssh key/username
- step5: 创建serviceaccount
- step6: 创建pipelinerun
- 案例2:构建和推送镜像
- step1: 创建task - 拉取代码
- step2: 创建task - 构建代码
- step3: 创建task - 打包镜像
- step4: 创建secret - docker 认证
- step5: 创建serviceaccount
- step6: 创建task编排 - pipeline
- step7: 创建pipelinerun
1. 官方介绍
Tekton 的前身是 Knative 项目的 build-pipeline 项目,这个项目是为了给 build 模块增加 pipeline 的功能,但是随着不同的功能加入到 Knative build 模块中,build 模块越来越变得像一个通用的 CI/CD 系统,于是,索性将 build-pipeline 剥离出 Knative,就变成了现在的 Tekton,而 Tekton 也从此致力于提供全功能、标准化的云原生 CI/CD 解决方案。
Tekton 是一个功能强大且灵活的 Kubernetes 原生开源框架,用于创建持续集成和交付(CI/CD)系统。通过抽象底层实现细节,用户可以跨多云平台和本地系统进行构建、测试和部署。
一句话总结:Tekton 是云原生的 CI/CD 框架,是云原生的的 CI/CD 解决方案。
2. 组件
Tekton 由一些列组件组成:
Tekton Pipelines
:是 Tekton 的基础,它定义了一组 Kubernetes CRD 作为构建块,我们可以使用这些对象来组装 CI/CD 流水线。Tekton Triggers
:允许我们根据事件来实例化流水线,例如,可以我们在每次将 PR/MR 合并到 GitHub/GitLab 仓库的时候触发流水线实例和构建工作。Tekton CLI
:提供了一个名为tkn
的命令行界面,它构建在 Kubernetes CLI 之上,运行和 Tekton 进行交互。Tekton Dashboard
:是Tekton Pipelines
的基于 Web 的一个图形界面,可以线上有关流水线执行的相关信息。Tekton Catalog
:是一个由社区贡献的高质量 Tekton 构建块(任务、流水线等)存储库,可以直接在我们自己的流水线中使用这些构建块。用于访问Tekton Catalog
的 Web 图形界面工具叫Tekton Hub
。Tekton Operator
:是一个 Kubernetes Operator,可以让我们在 Kubernetes 集群上安装、更新、删除 Tekton 项目。
2.1 Tekton Pipelines
参考链接:https://tekton.dev/docs/concepts/concept-model/
Tekton Pipeline中有5类对象,核心理念是通过定义yaml定义构建过程。
- task:task表示一个任务,task里可以定义一系列的steps,例如编译代码、构建镜像、推送镜像等,每个step实际由一个Pod执行。
- taskRun:task只是定义了一个模版,taskRun才真正代表了一次实际的运行,当然你也可以自己手动创建一个taskRun,taskRun创建出来之后,就会自动触发task描述的构建任务。
- PipelineResource:表示pipeline input资源,比如github上的源码,或者pipeline output资源,例如一个容器镜像或者构建生成的jar包等,目前已经弃用。
- Pipeline:一个或多个task、PipelineResource以及各种定义参数的集合。
- PipelineRun:类似task和taskRun的关系,pipelineRun也表示某一次实际运行的pipeline,下发一个pipelineRun CRD实例到kubernetes后,同样也会触发一次pipeline的构建。
2.2 部署pipeline
# install
kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
# moinitor
kubectl get pods --namespace tekton-pipelines --watch
2.3 部署dashborad
# install
kubectl apply --filename https://storage.googleapis.com/tekton-releases/dashboard/latest/release-full.yaml
# monitor
kubectl port-forward -n tekton-pipelines service/tekton-dashboard 9097:9097
# expose port
kubectl port-forward -n tekton-pipelines service/tekton-dashboard 9097:9097
pipeline和task的关系
pipeline和pipelinerun的关系
2.3.1 task
Task 就是一个任务执行模板,之所以说 Task 是一个模板是因为 task 定义中可以包含变量,Task 在真正执行的时候需要给定变量的具体值。
如果把 Tekton 的 Task 有点儿类似于定义一个函数,Task 通过 inputs.params 定义需要哪些入参,并且每一个入参还可以指定默认值。Task 的 steps 字段表示当前 task 是有哪些步骤组成的,每一个步骤具体就是基于镜像启动一个 container 执行一些操作,container 的启动参数可以通过 task 的入参使用模板语法进行配置。
Demo1:test-task.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: test
spec:params:- name: usernametype: stringdefault: "hello,cs"steps:- name: echoimage: alpinescript: |#!/bin/shecho "$(params.username)"
Demo2:task-git.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: clone-code-testdescription: This Task will clone code and search file
spec:steps:- name: clone-code-testimage: alpine/gitscript: |#!/bin/shecho "Hello World"git clone https://gitlab.com/kaixuan.wang/app.gitcd appcat README.md
也可以对demo2进行调整如下:
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: clone-code-testdescription: This Task will clone code and search file
spec:params:- name: repo-urltype: stringdefault: "https://gitlab.com/kaixuan.wang/gitops.git"steps:- name: clone-code-testimage: alpine/gitscript: |#!/bin/shecho "Hello World"git clone $(params.repo-url)ls -l gitops
# params:
# - name: repo-url
# value: git@jihulab.com:cs-test-group1/kxwang/test.git
2.3.2 taskrun
Task 定义好以后是不能执行的,就像一个函数定义好以后需要调用才能执行一样。所以需要再定义一个 TaskRun 去执行 Task。
TaskRun 主要是负责设置 Task 需要的参数,并通过 taskRef 字段引用要执行的 Task。
Demo1:
test-task-run.yaml(赋值username)
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:name: test-task-run #taskrun name
spec:taskRef:name: testparams:- name: usernamevalue: "Tekton"
test-task-2.yaml(不赋值)
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:name: test-task-run-1 #taskrun name
spec:taskRef:name: test
通过tkn工具查看
然而在实际使用过程中,我们一般很少使用TaskRun,因为它只能给一个Task 传参,Tekton提供了给多个Task同时传参的解决方案Pipeline和PipelineRun。
Demo2:taskrun-git.yaml
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:generateName: taskrun-git- # name: taskrun-git
spec:taskRef:name: clone-code
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:generateName: taskrun-git-
spec:taskRef:name: clone-code
# params:
# - name: repo-url
# value: "https://gitlab.com/test-ce/group/123.git"
2.3.3 Pipeline
一个 TaskRun 只能执行一个 Task,当需要编排多个 Task 的时候就需要用到 Pipeline。
Pipeline 是一个编排 Task 的模板。
- Pipeline 的 params 声明了执行时需要的入参。
- Pipeline 的 spec.tasks 定义了需要编排的 Task。
- Tasks 是一个数组,数组中的 task 并不是通过数组声明的顺序去执行的,而是通过 runAfter 来声明 task 执行的顺序。
Tekton controller 在解析 CRD 的时候会解析 Task 的顺序,然后根据 runAfter 设置生成的依次树依次去执行。Pipeline 在编排 Task 的时候需要给每一个 Task 传入必须的参数,这些参数的值可以来自 Pipeline 自身的 params 设置。下面是一个Demo:
pipeline.yaml
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:name: test-pipeline
spec:params:- name: usernametype: stringtasks:- name: test-1taskRef:name: testparams:- name: usernamevalue: $(params.username)
# - name: clone-code-test
# runAfter:
# - test-1
# taskRef:
# name: clone-code-test
2.3.4 PipelineRun
和 Task 一样 Pipeline 定义完成以后也是不能直接执行的,需要 PipelineRun 才能执行 Pipeline。PipelineRun 的主要作用是给 Pipeline 传入必要的入参,并执行 Pipeline。
pipelinerun.yaml
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:generateName: test-pipeline-run-
spec:pipelineRef:name: test-pipelineparams:- name: usernamevalue: "Tekton"
3. 案例
案例1: 拉取代码并查看readme
step1: 创建task - 拉取代码
安装git-clone task
kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/main/task/git-clone/0.9/git-clone.yaml
或者自己创建一个git-clone task
cat task.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: git-clone
spec:workspaces:- name: output- name: ssh-directoryparams:- name: urltype: string- name: revisiontype: stringdefault: ""steps:- name: cloneimage: "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init:v0.40.2"env:- name: PARAM_URLvalue: $(params.url)- name: PARAM_REVISIONvalue: $(params.revision)- name: WORKSPACE_OUTPUT_PATHvalue: $(workspaces.output.path)- name: WORKSPACE_SSH_PATHvalue: $(workspaces.ssh-directory.path)script: |#!/usr/bin/env shmkdir $HOME/.sshcp $WORKSPACE_SSH_PATH/* $HOME/.ssh/chmod 400 $HOME/.ssh/*set -euCHECKOUT_DIR="${WORKSPACE_OUTPUT_PATH}"/ko-app/git-init \-url="${PARAM_URL}" \-revision="${PARAM_REVISION}" \-path="${CHECKOUT_DIR}"cd "${CHECKOUT_DIR}"EXIT_CODE="$?"if [ "${EXIT_CODE}" != 0 ] ; thenexit "${EXIT_CODE}"fi
step2: 创建task - 查看reamde
cat show-readme.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: show-readme
spec:workspaces:- name: sourcesteps:- name: show-readmeimage: alpine:latestscript: |cat $(workspaces.source.path)/README.md
step3: 创建task的编排 - pipeline
cat pipeline.yaml
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:name: cat-branch-readme
spec:params:- name: repo-urltype: string- name: branch-nametype: stringworkspaces:- name: shared-data- name: git-credentialstasks:- name: fetch-repotaskRef:name: git-cloneworkspaces:- name: outputworkspace: shared-data- name: ssh-directoryworkspace: git-credentialsparams:- name: urlvalue: $(params.repo-url)- name: revisionvalue: $(params.branch-name)- name: show-readmerunAfter: ["fetch-repo"]taskRef:name: show-readmeworkspaces:- name: sourceworkspace: shared-data
step4: 创建secrets - ssh key/username
secrets-ssh.yaml
apiVersion: v1
kind: Secret
metadata:name: gitlab-sshannotations:tekton.dev/git-0: jihulab.com #不需要指定协议,如果带http://或者https://会报错
type: kubernetes.io/ssh-auth
data:ssh-privatekey: <cat ~/.ssh/id_rsa | base64 -w0>known_hosts: <cat ~/.ssh/known_hosts | base64 -w0>
创建secrets - username
secrets-basic.yaml
apiVersion: v1
kind: Secret
metadata:name: gitlab-authannotations:tekton.dev/git-0: https://jihulab.com #需要指定协议,如果不带会报错
type: kubernetes.io/basic-auth
stringData:username: kxwang@jihulab.compassword: xxxxxxx
step5: 创建serviceaccount
gitlab-sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:name: gitlab-sa
secrets:
- name: gitlab-auth
- name: gitlab-ssh
step6: 创建pipelinerun
cat pipelinerun.yaml
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:generateName: git-clone-checking-out-a-branch
spec:serviceAccountName: gitlab-sapipelineRef:name: cat-branch-readmepodTemplate:securityContext:fsGroup: 65532workspaces:- name: shared-datavolumeClaimTemplate:spec:accessModes:- ReadWriteOnceresources:requests:storage: 256MivolumeMode: Filesystem- name: git-credentialssecret:secretName: gitlab-sshparams:- name: repo-urlvalue: git@jihulab.com:cs-test-group1/kxwang/test.git- name: branch-namevalue: master
案例2:构建和推送镜像
step1: 创建task - 拉取代码
同上
step2: 创建task - 构建代码
task-build.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: build-1
spec:workspaces:- name: source # 名称params:- name: skipunittype: stringdefault: "true"steps:- name: buildimage: maven:3-jdk-8workingDir: $(workspaces.source.path)script: |#/usr/bin/env shmvn clean package -Dmaven.test.skip=$(params.skipunit)volumeMounts:- name: cachemountPath: /workspace/.m2subPath: m2-cache- name: cachemountPath: /workspace/.cachesubPath: m2-cachevolumes:- name: cacheemptyDir: {}
step3: 创建task - 打包镜像
task-package.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: package-1
spec:workspaces:- name: source # 名称params:- name: image_desttype: string- name: image_tagtype: stringdefault: "latest"- name: DockerfilePathtype: stringdefault: Dockerfile- name: Contexttype: stringdefault: .steps:- name: packageimage: docker:stableworkingDir: $(workspaces.source.path)script: |#/usr/bin/env shdocker login registry.ap-southeast-1.aliyuncs.comdocker build -t $(params.image_dest):$(params.image_tag) -f $(params.DockerfilePath) $(params.Context)docker push $(params.image_dest):$(params.image_tag)volumeMounts:- name: dockersorckmountPath: /var/run/docker.sockvolumes:- name: dockersorckhostPath:path: /var/run/docker.sock
step4: 创建secret - docker 认证
1、config.json(~/.docker/config.json)
{"auths": {"registry.ap-southeast-1.aliyuncs.com": {"auth": "d2t4XzA0MjJAMTYzLmNvbTp3a3g3MzE1MDg4MDY="}}
}
2、secret-docker.yaml
apiVersion: v1
kind: Secret
metadata:name: docker-credentialsannotations:tekton.dev/docker-0: https://registry.ap-southeast-1.aliyuncs.com
type: kubernetes.io/basic-auth
stringData:username: wkx_0422@163.compassword: 123456
step5: 创建serviceaccount
gitlab-sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:name: gitlab-sa
secrets:
- name: gitlab-auth
- name: gitlab-ssh
- name: docker-credentials
step6: 创建task编排 - pipeline
pipeline.yaml
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:name: clone-build-push-1
spec:description: |This pipeline clones a git repo, builds a Docker image with Kaniko andpushes it to a registryparams:- name: repo-urltype: string- name: image_desttype: string- name: image_tagtype: stringworkspaces:- name: shared-datatasks:# 拉取代码- name: fetch-sourcetaskRef:name: git-cloneworkspaces:- name: outputworkspace: shared-dataparams:- name: urlvalue: $(params.repo-url)# 打包- name: build-codetaskRef:name: build-1workspaces:- name: sourceworkspace: shared-datarunAfter:- fetch-source# 构建并推送镜像- name: package-imagerunAfter: ["build-code"]taskRef:name: package-1workspaces:- name: sourceworkspace: shared-dataparams:- name: image_destvalue: $(params.image_dest)- name: image_tagvalue: $(params.image_tag)
step7: 创建pipelinerun
pipelinerun.yaml
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:generateName: clone-build-push-run-
spec:serviceAccountName: gitlab-sapipelineRef:name: clone-build-push-1podTemplate:securityContext:fsGroup: 65532workspaces:- name: shared-datavolumeClaimTemplate:spec:accessModes:- ReadWriteOnceresources:requests:storage: 128Miparams:- name: repo-urlvalue: https://jihulab.com/cs-test-group1/kxwang/test.git- name: image_destvalue: registry.ap-southeast-1.aliyuncs.com/my_image_repo/demo- name: image_tagvalue: v2