背景
jenkins可以很好的完成流水线,那么为什么还要有Tekton呢?
jenkins的缺点
- 基于脚本的Job 配置复用率不足
当有多个作业执行同样的步骤时,脚本无法复用。只能复制之前的作业再做修改。如果脚本出现bug,还得思考还有哪些脚本复制了这段异常脚本。 - 代码调试困难
jenkins触发流水线的方式是通过shell脚本,把代码checkout下来,然后编译测试打包。脚本复杂的话调试起来困难。 - jenkins的slave是有上限的,在大型业务下有压力。
介绍
来源是Knative中的流水线build。
- 自定义:Tekton 对象是高度自定义的,可扩展性极强。平台工程师可预定义可重用模块以详细的模块目录提供,开发人员可在其他项目中直接引用。
- 可重用:Tekton 对象的可重用性强,组件只需一次定义,即可被组织内的任何人在任何流水线都可重用。使得开发人员无需重复造轮子即可构建复杂流水线。
- 可扩展性:Tekton 组件目录(Tekton Catalog)是一个社区驱动的 Tekton 组件的存储仓库。任何用户可以直接从社区获取成熟的组件并在此之上构建复杂流水线,也就是当你要构建一个流水线时,很可能你需要的所有代码和配置都可以从 TektonCatalog 直接拿下来复用,而无需重复开发。
- 标准化:Tekton 作为 Kubernetes 集群的扩展安装和运行,并使用业界公认的 Kubernetes 资源模型;Tekton 作业以Kubernetes 容器形态执行。
- 规模化支持:只需增加 Kubernetes 节点,即可增加作业处理能力。Tekton 的能力可依照集群规模随意扩充,无需重新定义资源分配需求或者重新定义流水线。
核心组件
- Pipeline:对象定义了一个流水线作业,一个 Pipeline 对象由一个或数个 Task 对象组成。
- Task: 一个可独立运行的任务,如获取代码,编译,或者推送镜像等等,当流水线被运行时,Kubernetes会为每个Task创建一个 Pod。一个 Task 由多个 Step 组成,每个 Step 体现为这个Pod 中的一个容器。
图中taskB和taskC都是runAfterA,也就是说需要等taskA执行完成后才能执行。
taskD是from B and C,也就是说要B和C都执行完成后才能执行。
输入输出资源
Pipeline 和 Task 对象可以接收 git reposity, pull request 等资源作为输入,可以将 Image,Kubernetes Cluster, Storage, CloudEvent 等对象作为输出。
自动化流水线
- 在GitHub或者gitlab上配置一个webhook,即比如在GitHub上创建了pr要通知到tekton。
- webhook发送event给el-gitlab-listener-svc再转发到el-gitlab-listener-pod。
- pod收到event后会去判断应该执行什么样的流水线作业。
- 流水线作业就是在EventListener中定义的。它定义了interceptor拦截器即需要监听什么样的作业,定义了真正执行作业的动作TriggerTemplate,还定义了Trigger中的参数Trigger Binding并进行绑定。
- TriggerTemplate中一般是一个Pipeline。
- Pipeline中有输入和输出。输入就是PipelineResource,输出就是image。
- Pipeline中有多个task。task又分为ClusterTask集群task和task。
EventListener
- 事件监听器,该对象核心属性是 interceptors 拦截器,该拦截器可监听多种类型的事件,比如监听来自 GitLab 的 Push 事件。
- 当该 EventListener 对象被创建以后,Tekton 控制器会为该 EventListener 创建 Kubernetes Pod 和 Service,并启动一个 HTTP 服务以监听 Push 事件。
- 当用户在 GitLab 项目中设置 webhook 并填写该EventListener 的服务地址以后,任何人针对被管理项目发起的 Push 操作,都会被 EventListener 捕获。
tekton部署
创建ns
k create ns tekton-pipelines
mkdir tekton
下载yaml文件
wget https://storage.googleapis.com/tekton-releases/pipeline/previous/v0.34.1/release.yaml
wget https://storage.googleapis.com/tekton-releases/triggers/previous/v0.19.1/release.yaml
wget https://storage.googleapis.com/tekton-releases/triggers/previous/v0.19.1/interceptors.yaml
wget https://storage.googleapis.com/tekton-releases/dashboard/latest/tekton-dashboard-release.yaml
修改镜像,将gcr.io镜像修改为阿里云acr镜像
tekton-triggers-release.yaml: image: "registry.cn-hangzhou.aliyuncs.com/wgh9626/trigger-controller:v0.19.1"
tekton-triggers-release.yaml: args: ["-logtostderr", "-stderrthreshold", "INFO", "-el-image", "registry.cn-hangzhou.aliyuncs.com/wgh9626/eventlistenersink:v0.19.1", "-el-port", "8080", "-el-security-context=true", "-el-events", "disable", "-el-readtimeout", "5", "-el-writetimeout", "40", "-el-idletimeout", "120", "-el-timeouthandler", "30", "-el-httpclient-readtimeout", "30", "-el-httpclient-keep-alive", "30", "-el-httpclient-tlshandshaketimeout", "10", "-el-httpclient-responseheadertimeout", "10", "-el-httpclient-expectcontinuetimeout", "1", "-period-seconds", "10", "-failure-threshold", "1"]
tekton-triggers-release.yaml: image: "registry.cn-hangzhou.aliyuncs.com/wgh9626/triggers-webhook:v0.19.1"
tekton-dashboard-release.yaml: image: registry.cn-hangzhou.aliyuncs.com/wgh9626/tektoncd-dashboard:v0.25.0
interceptors.yaml: image: "registry.cn-hangzhou.aliyuncs.com/wgh9626/triggers-interceptors:v0.19.1"
tekton-pipelines-release.yaml: image: registry.cn-hangzhou.aliyuncs.com/wgh9626/tekton:v0.34.1
tekton-pipelines-release.yaml: "-kubeconfig-writer-image", "registry.cn-hangzhou.aliyuncs.com/wgh9626/kubeconfigwriter:v0.34.1", "-git-image", "registry.cn-hangzhou.aliyuncs.com/wgh9626/git-init:v0.34.1", "-entrypoint-image", "registry.cn-hangzhou.aliyuncs.com/wgh9626/entrypoint:v0.34.1", "-nop-image", "registry.cn-hangzhou.aliyuncs.com/wgh9626/nop:v0.34.1", "-imagedigest-exporter-image", "registry.cn-hangzhou.aliyuncs.com/wgh9626/imagedigestexporter:v0.34.1", "-pr-image", "registry.cn-hangzhou.aliyuncs.com/wgh9626/pullrequest-init:v0.34.1", "-workingdirinit-image", "registry.cn-hangzhou.aliyuncs.com/wgh9626/workingdirinit:v0.34.1",
tekton-pipelines-release.yaml: "-gsutil-image", "registry.cn-hangzhou.aliyuncs.com/wgh9626/cloud-sdk:latest",
tekton-pipelines-release.yaml: "-shell-image", "registry.cn-hangzhou.aliyuncs.com/wgh9626/base:latest",
tekton-pipelines-release.yaml: image: registry.cn-hangzhou.aliyuncs.com/wgh9626/webhook:v0.34.1
部署yaml
k apply -f .
k get po -n tekton-pipelines
设置ingress
k get svc -n tekton-pipelines
cat tekton-dashboard-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tekton-ingress
namespace: tekton-pipelines
spec:
ingressClassName: nginx
rules:
- host: tekton.wghdr.top
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: tekton-dashboard
port:
number: 9097
测试task
定义task
启动ubuntu的镜像,命令是输出hello username。
cat task-hello.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: hello
spec:
steps:
- name: hello
image: ubuntu
command:
- echo
args:
- "Hello $(params.username)!"
params:
- name: username
type: string
定义taskRun,为task中的参数赋值并执行task
cat taskrun-hello.yaml
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
generateName: hello-run-
spec:
taskRef:
name: hello
params:
- name: "username"
value: "wghdr"
部署task和taskRun
k apply -f task-hello.yaml
k create -f taskrun-hello.yaml # 这里不能用apply
查看task和taskRun
k get task,taskrun
task执行成功
k get po
# 输出了hello wghdr
k logs -f hello-run-kshzw-pod