共计 5925 个字符,预计需要花费 15 分钟才能阅读完成。
Tekton
什么是 Tekton
Tekton 的前身是 Knative 的子项目 build-pipeline,主要用来给 Kantive 的 build 模块增加 pipeline 功能。之后独立出来,Tekton 的目标是一个通用的 CI/CD 工具。这是一种常见的产品孵化机制。
目前,私有云市场占有率比较高的 CICD 工具对 Kubernetes 都有所支持,比如 Jenkins、GitLab CI。但是,这些工具只是将 Kubernetes 作为其扩展的一个方面,Kubernetes 作为新的基础设施,需要原生的 CICD 方案。
另一方面,Jenkins 的子项目 JenkinsX 也开始默认使用 Tekton 作为 CI 引擎。使用云原生一等公民 CRD + Controller 实现的 Tekton ,无疑有机会成为云原生的主流编排引擎。
基础对象
Task
Task就是一个任务模板,Task的定义中可以包含变量,在真正执行的时候需要给变量赋值。
Task通过input.params定义入参,每一个入参还可以指定默认值,在每一个step中可以$(params.A)引用变量。steps字段表示当前Task有哪些步骤组成,每一个step都会通过定义一个container来执行具体的操作。
Task主要包括以下元素:
-
Parameters:用于定义params参数
-
Resources:定义输入、输出资源,老版本由PipelineResources定义,不过在新版本中PipelineResources将被弃用
-
Steps:定义具体的操作步骤
-
Workspaces:定义工作区,Task可以共享工作区
-
Results:定义结果输出,可以用于展示或者给另外的Task使用
apiVersion: tekton.dev/v1beta1 kind: Task metadata: name: maven-build spec: resources: inputs: - name: repo type: git steps: - name: build image: maven:3.3-jdk-8 command: - mvn clean package workingDir: /workspace/repo
TaskRuns
Task在定义好之后,并不会被执行,就像我们定义了一个函数,如果没被调用的话,这个函数就不会被执行一样。而TaskRun就可以就好似调用方,用它来执行Task里的具体内容。
TaskRun会设置Task需要的参数,并通过taskRef字段来引用Task,如下:
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
name: build-and-push-image
spec:
params:
- name: imageRepo
value: registry.cn-zhangjiakou.aliyuncs.com
taskRef:
name: build-and-push-image # 关联定义好的task
resources:
inputs:
- name: repo # 指定输入的仓库资源
resourceRef:
name: hello-word-resource
outputs: # 指定输出的镜像资源
- name: builtImage
resourceRef:
name: hello-word-image
通过如上的定义,就将build-and-push-image的Task进行关联,并且通过resources定义Task需要的sources参数,然后通过parms来定义参数,该参数会替代掉Task中的默认参数。
在实际中,基本不会去定义TaskRun,除非自己去测试某个Task是否正常。
Pipelines
一个TaskRun只能执行一个Task,当我们需要同时编排许多Task的时候,就需要使用Pipeline了,就像使用Jenkinsfile来编排不同的任务一样。
Pipeline是一个编排Task的模板,通过spec.params来声明执行时需要的入参,通过spec.tasks来编排具体的task,除此之外还可以通过runAfter来控制Task的先后顺序。
先定义一个简单的Pipeline,如下
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: build-and-push-image
spec:
resources:
- name: repo
type: git
- name: builtImage
type: image
tasks:
# 构建并推送 Docker 镜像
- name: build-and-push-image
taskRef:
name: build-and-push-image
resources:
inputs:
- name: repo # Task 输入名称
resource: repo # Pipeline 资源名称
outputs:
- name: builtImage
resource: builtImage
上面定义的Pipeline关联了build-and-push-image
Task,该Task所需要的输入输出参数,通过Pipeline的spec.resources
定义,这里的spec.resources
依然依赖PipelineResources中定义的具体资源。
上面提到过,如果要在Pipeline中控制Task顺序,则要使用runAfter参数,如下:
- name: test-app
taskRef:
name: make-test
resources:
inputs:
- name: workspace
resource: my-repo
- name: build-app
taskRef:
name: kaniko-build
runAfter:
- test-app
resources:
inputs:
- name: workspace
resource: my-repo
PipelineRuns
Pipeline和Task一样,单纯的定义完并不会运行,Pipeline需要借助PipelineRun来完成真正的执行。
PipelineRun会自动为Pipeline中定义的Task创建对应的TaskRun。
下面定义一个简单的PipelineRun。
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: build-and-push-image
spec:
pipelineRef:
name: build-and-push-image
resources:
- name: repo
resourceRef:
name: demo-git
- name: builtImage
resourceRef:
name: harbor-image
其中spec.pipelineRef
用来关联定义的Pipeline,spec.resources
用来给Pipeline传递参数。
安装
Tekton
由于官方使用的镜像是 gcr 的镜像,所以正常情况下我们是获取不到的,如果你的集群由于某些原因获取不到镜像,可以使用下面的资源清单文件,我已经将镜像替换成了 Docker Hub 上面的镜像:
$ Tekton kubectl apply -f https://raw.githubusercontent.com/honest1y/kubernetes_yaml/master/devops/tekton/install.yaml
namespace/tekton-pipelines created
podsecuritypolicy.policy/tekton-pipelines created
clusterrole.rbac.authorization.k8s.io/tekton-pipelines-controller-cluster-access created
clusterrole.rbac.authorization.k8s.io/tekton-pipelines-controller-tenant-access created
clusterrole.rbac.authorization.k8s.io/tekton-pipelines-webhook-cluster-access created
role.rbac.authorization.k8s.io/tekton-pipelines-controller created
role.rbac.authorization.k8s.io/tekton-pipelines-webhook created
serviceaccount/tekton-pipelines-controller created
serviceaccount/tekton-pipelines-webhook created
....
configmap/config-artifact-bucket created
configmap/config-artifact-pvc created
configmap/config-defaults created
configmap/feature-flags created
configmap/config-leader-election created
configmap/config-logging created
configmap/config-observability created
deployment.apps/tekton-pipelines-controller created
service/tekton-pipelines-controller created
deployment.apps/tekton-pipelines-webhook created
service/tekton-pipelines-webhook created
# 镜像处理
grep -Eo "gcr.io([^\" ]*)" tekton-pipeline-release.yaml | awk '{print "docker pull "$0}' > pull.sh
grep -Eo "gcr.io([^\" ]*)" tekton-pipeline-release.yaml | awk -F"@" '{origin = $0;gsub("gcr.io/","",$1);print "docker tag " origin " my-registry.cn-beijing.cr.aliyuncs.com/gcrio/"$1 ";\ndocker push my-registry.cn-beijing.cr.aliyuncs.com/gcrio/" $1}' > tag.push.sh
source pull.sh
source push.sh
# 替换镜像源地址
sed -i "s/gcr.io/my-registry.cn-beijing.cr.aliyuncs.com\/gcrio/g" tekton-pipeline-release.yaml
上面的资源清单文件安装后,会创建一个名为 tekton-pipelines
的命名空间,在该命名空间下面会有大量和 tekton 相关的资源对象,我们可以通过在该命名空间中查看 Pod 并确保它们处于 Running 状态来检查安装是否成功:
$ kubectl get po -n tekton-pipelines
NAME READY STATUS RESTARTS AGE
tekton-pipelines-controller-848c885459-4hdjt 1/1 Running 0 50s
tekton-pipelines-webhook-7dc48bc5f7-xm424 1/1 Running 0 49s
我们安装完Tekton之后,可以看到安装的CRD如下
$ k get crd | grep tekton
clusterinterceptors.triggers.tekton.dev 2023-02-02T13:52:02Z
clustertasks.tekton.dev 2023-02-02T12:57:38Z
clustertriggerbindings.triggers.tekton.dev 2023-02-02T13:52:02Z
customruns.tekton.dev 2023-02-02T12:57:39Z
eventlisteners.triggers.tekton.dev 2023-02-02T13:52:02Z
extensions.dashboard.tekton.dev 2023-02-02T11:57:02Z
interceptors.triggers.tekton.dev 2023-02-02T13:52:03Z
pipelineresources.tekton.dev 2023-02-02T12:57:40Z
pipelineruns.tekton.dev 2023-02-02T12:57:39Z
pipelines.tekton.dev 2023-02-02T12:57:39Z
resolutionrequests.resolution.tekton.dev 2023-02-02T12:57:39Z
runs.tekton.dev 2023-02-02T12:57:40Z
taskruns.tekton.dev 2023-02-02T12:57:40Z
tasks.tekton.dev 2023-02-02T12:57:40Z
CLI
Tekton 安装完成后,我们还可以选择是否安装 CLI 工具,有时候可能 Tekton 提供的命令行工具比 kubectl 管理这些资源更加方便,当然这并不是强制的,我这里是 Mac 系统,所以可以使用常用的 Homebrew
工具来安装:
$ brew tap tektoncd/tools
$ brew install tektoncd/tools/tektoncd-cli
安装完成后可以通过如下命令验证 CLI 是否安装成功:
$ Tekton tkn version
Client version: 0.29.1
Dashboard
$ kubectl apply --filename https://raw.githubusercontent.com/honest1y/kubernetes_yaml/master/devops/tekton/dashboard.yaml
Ingress
$ kubectl apply -f https://raw.githubusercontent.com/honest1y/kubernetes_yaml/master/devops/tekton/ingress.yaml