Tekton是一个Kubernetes原生的持续集成和交付(CI/CD)框架。它允许你通过Kubernetes自定义资源定义(CRD)声明性地创建容器化、可组合和可配置的工作负载。
Tekton Triggers是一个Tekton组件,允许你从各种来源的事件中检测和提取信息,并根据这些信息执行TaskRuns和PipelineRuns。它还可以将提取的信息传递给事件中的TaskRuns和PipelineRuns。
本文以 GitLab 为例,说明 Tekton Triggers 如何与外部服务(如 Git 存储库)集成。
前提条件
如果您想遵循本文的步骤,您必须有一个运行 Kubernetes 1.18 或更高版本的 Kubernetes 集群,并安装一个可提供外部 IP 的入口控制器。您还必须安装Tekton Pipelines和Tekton Triggers。
触发器流程
Tekton触发器允许你创建一个名为EventListener的特殊资源,它是一个Kubernetes服务,用于监听来自不同来源的HTTP请求,通常是Git仓库,包括GitLab、GitHub等托管的仓库。基于这些事件,EventListener pod会执行行动并创建Tekton资源,如TaskRun或PipelineRun。

所有Triggers资源定义都是用YAML创建的,这是Kubernetes中最常用的配置格式。不过,在编写YAML文件定义Trigger之前,必须先了解Tekton Triggers术语。
事件监听器
EventListener是一种Kubernetes服务,它监听传入的HTTP请求并执行Trigger。例如,在收到一个特定的传入请求后,该定义会执行gitlab-listener-trigger 触发器。
apiVersion: triggers.tekton.dev/v1beta1
kind: EventListener
metadata:
name: gitlab-event-listener
spec:
serviceAccountName: gitlab-listener-sa
triggers:
- triggerRef: gitlab-listener-trigger
resources:
kubernetesResource:
serviceType: NodePort
触发器决定对收到的事件做什么。它还设置了一个TriggerBinding、TriggerTemplate和可选的拦截器来运行。触发器利用拦截器来验证或修改传入的请求,然后再继续进行。
apiVersion: triggers.tekton.dev/v1beta1
kind: Trigger
metadata:
name: gitlab-listener-trigger
spec:
interceptors:
- name: "verify-gitlab-payload"
ref:
name: "gitlab"
kind: ClusterInterceptor
params:
- name: secretRef
value:
secretName: "gitlab-secret"
secretKey: "secretToken"
- name: eventTypes
value:
- "Push Hook"
bindings:
- ref: binding
template:
ref: template
拦截器
拦截器是一个在TriggerBinding之前运行的事件处理器。它还执行有效载荷过滤、验证(使用秘密)和转换;定义和测试触发条件;以及实现其他有用的处理。
默认情况下,在安装Triggers时,会安装四个核心拦截器。GitHub、GitLab、Bitbucket和CEL。安装时还包括一个Webhook拦截器,用于实现自定义业务逻辑。
GitLab拦截器
GitLab拦截器有助于验证和过滤GitLab webhooks,并按事件类型过滤传入的事件。GitLab拦截器需要一个秘密令牌。这个令牌是在GitLab中创建webhook时设置的,当请求到达时由GitLab拦截器进行验证。
apiVersion: v1
kind: Secret
metadata:
name: gitlab-secret
type: Opaque
stringData:
secretToken: "1234567"
触发器绑定(TriggerBinding
在验证和修改传入的请求后,你需要从请求中提取数值,并将它们绑定到变量上,以后可以在TriggerTemplate中使用这些变量来传递我们的Pipeline。
对于我们的例子,你只需要一个URL和一个修订。
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerBinding
metadata:
name: binding
spec:
params:
- name: gitrevision
value: $(body.checkout_sha)
- name: gitrepositoryurl
value: $(body.repository.git_http_url)
触发器模板(TriggerTemplate
TriggerTemplate是一个蓝图,当EventListener检测到一个事件时,实例化TaskRun 或PipelineRun 。
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
name: template
spec:
params:
- name: gitrevision
- name: gitrepositoryurl
resourcetemplates:
- apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
generateName: gitlab-run-
spec:
taskSpec:
resources:
inputs:
- name: source
type: git
steps:
- image: ubuntu
script: |
#! /bin/bash
ls -al $(inputs.resources.source.path)
resources:
inputs:
- name: source
resourceSpec:
type: git
params:
- name: revision
value: $(tt.params.gitrevision)
- name: url
value: $(tt.params.gitrepositoryurl)
注意,在撰写本文时,管道资源模块已被废弃,并将被来自tektoncd/catalog的git-clone任务取代。
通过配置webhook动态地安排工作负载
首先,创建一个新的命名空间,demo 。
$ kubectl create ns demo
接下来,在应用Triggers资源之前,配置所需的基于角色的访问控制(RBAC)。
$ kubectl -n demo apply -f \
"https://gist.githubusercontent.com/savitaashture/596bc4d93ff6b7606fe52aa20ba1ba14/raw/158a5ed0dc30fd1ebdac461147a4079cd6187eac/triggers-rbac.yaml"
注意:RBAC的配置根据权限的不同而不同。
应用Triggers资源。
$ kubectl -n demo apply -f \
"https://gist.githubusercontent.com/savitaashture/8aa013db1cb87f5dd1f2f96b0e121363/raw/f4f592d8c1332938878c5ab9641e350c6411e2b0/triggers-resource.yaml"
应用后,验证EventListener对象和pod的创建是否成功。
EventListener对象READY状态应该是True。
$ kubectl get el -n demo
NAME ADDRESS AVAILABLE REASON READY REASON
gitlab-event-listener http://el-gitlab-event-listener.demo.svc.cluster.local:8080 True MinimumReplicasAvailable True
EventListener Pod状态应该是Running。
$ kubectl get pods -n demo
NAME READY STATUS RESTARTS AGE
el-gitlab-event-listener-fb77ff8f7-p5wnv 1/1 Running 0 4m22s
创建ingress以获取外部IP,配置到GitLab webhook中。
$ kubectl -n demo apply -f \
"https://gist.githubusercontent.com/savitaashture/3b3554810e391477feae21bb8a9af93a/raw/56665b0a31c7a537f9acbb731b68a519be260808/triggers-ingress.yaml"
获取ingress的IP。
$ kubectl get ingress triggers-ingress-resource -n demo
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-resource * 80 6s
在GitLab中配置一个webhook。在你的GitLab仓库中,进入设置->Webhooks。
然后设置以下字段。
- URL:来自Ingress的外部IP地址,路径为
/ - 秘密令牌:1234567,这应该与上面从
triggers-resource.yaml文件中创建的秘密值相匹配
从触发器部分选择事件类型,然后选择推送事件,取消勾选启用SSL验证,并点击添加webhook。

通过推送PR测试GitLab事件
克隆你自己的GitLab仓库,进行修改,然后推送。举例来说。
$ git clone https://gitlab.com/savitaashture1/gitlabtest-triggers
$ cd gitlabtest-triggers
$ git commit -m "empty-commit" --allow-empty && git push origin main
[main 934ecba] empty-commit
Username for 'https://gitlab.com': savitaashture
Password for 'https://savitaashture@gitlab.com':
warning: redirecting to https://gitlab.com/savitaashture1/gitlabtest-triggers.git/
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 183 bytes | 183.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To https://gitlab.com/savitaashture1/gitlabtest-triggers
ff1d11e..934ecba main -> main
事件将被生成并发送到EventListener pod。你可以通过做来验证。
kubectl get pods -n demo
kubectl logs -f -n demo
通过对get 操作来验证事件的成功发送,TaskRun 。
$ kubectl -n demo get taskruns | grep gitlab-run-
gitlab-run-hvtll True Succeeded 95s 87s
通过删除命名空间demo ,清理所有由Triggers创建的资源。
$ kubectl delete ns demo
结论
Tekton Triggers 是最有用的模块之一,有助于根据用户定义的事件集动态安排工作负载。因为这个模块,我的团队能够实现端到端的CI/CD。