云原生CI/CD:Tekton之trigger组件

简介

上面背景图片用了一张手枪扳机的图片,啥意思呢?trigger对于pipeline的作用就像扳机对于手枪的作用的,读完文章再来体会这句话。
前面我们学过tekton的pipeline组件,里面可以运行自定义工作流任务,而这些工作流任务例如task和pipeline都需要对象的触发对象例如taskrun和pipelineRun。触发的方式有两种:手动kubectl apply 文件触发和client-go触发。tekton为大家选择第三种方式,使用api接口触发。这就是本讲要着重讲的tekton的另一个组件trigger。

触发器Trigger使用户能够将事件中的字段映射到资源模板中,换句话说,这允许事件既可以建模也可以将其实例化为tekton资源。对于tektoncd / pipeline,触发器使得事件中的参数轻易封装到PipelineRuns、PipelineResources等对象中

上面这张是trigger的原理图,就是使用eventListener(事件监听器)监听事件,监听到事件后由triggerbinding将json数据解析并传送到triggerTemplate,而triggertemplate根据传入参数进行解析最后实例化tekton的资源(task,taskrun,pipeline等对象),要是实例化生成taskrun和pipelineRun,那就可以实现对流水线的触发。整个过程分工明确,每个对象都能做到解耦复用,设计理念非常棒。

Trigger中的核心概念

  • TriggerTemplate:TriggerTemplate是可以用于模板化资源的资源;根据传入参数,实例化k8s中tekton的对象资源(例如task,taskrun等)
  • TriggerBinding:使用TriggerBindings可以捕获事件中的字段并将其存储为参数,将参数传入triggerTemplate。故意将TriggerBindings与TriggerTemplates分开以鼓励它们之间的重用(就是解耦)
  • EventListener:EventListener是trigger定义的CRD资源,它允许用户使用HTTP请求的方式传入事件。 EventListeners需对外开放服务,才能让事件进来。用户可以声明TriggerBindings以从事件中提取字段,并将其应用于TriggerTemplates以创建Tekton资源。此外,EventListeners允许使用事件拦截器进行轻量级的事件处理;
  • ClusterTriggerBinding:ClusterTriggerBindings与TriggerBinding相似,均用于从事件中提取字段。唯一的区别是它是集群范围的,旨在鼓励集群范围内的可重用性。您可以在任何名称空间的任何EventListener中引用ClusterTriggerBinding。

具体使用

TriggerTemplate, TriggerBinding, EventListener, ClusterTriggerBinding都是CRD对象,下面就TriggerTemplate, TriggerBinding, EventListener, ClusterTriggerBinding的使用进行介绍:

TriggerTemplate

定义:TriggerTemplate是可以模板化tekton资源的资源,TriggerTemplate可使得参数在资源模板中任何位置被使用。简而言之,triggerTempate就像定义了一个完整的函数,它定义了函数所使用的形参和函数体,triggerTemplate就等着triggerBinding传入参数,然后实例化资源对象。

看下triggerTemplate的使用,你会更清楚。

apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerTemplate #TriggerTemplate
metadata:name: pipeline-template
spec:params: #参数定义- name: gitrevisiondescription: The git revisiondefault: master- name: gitrepositoryurldescription: The git repository url- name: messagedescription: The message to printdefault: This is the default message- name: contenttypedescription: The Content-Type of the eventresourcetemplates: #资源模板, 将参数传入资源模板,实例化一个pipelinerun- apiVersion: tekton.dev/v1beta1kind: PipelineRun   metadata:generateName: simple-pipeline-run-spec:pipelineRef:name: simple-pipeline #pipelineRun所运行的pipelineparams:- name: messagevalue: $(params.message)  #这些参数都是上面定义的参数- name: contenttypevalue: $(params.contenttype) #这些参数都是上面定义的参数resources:- name: git-sourceresourceSpec:type: gitparams:- name: revisionvalue: $(params.gitrevision)#这些参数都是上面定义的参数- name: urlvalue: $(params.gitrepositoryurl)#这些参数都是上面定义的参数

与pipeline和task对象类似,TriggerTemplates并不会做任何实际的工作,而是充当应创建哪些资源的蓝图。上面的例子实例化了tekton的PipelineRun资源,你也可以创建其他tekton的资源。你可以先在集群中创建pipelineRun所使用的pipeline和task资源,毕竟pipelineRun只是对pipeline的一次调用,pipeline是可以复用的。当然,你也可以在triggertemplate中创建一套完整的task,pipeline,pipelineRun。但是这样的话就没有体会到tekton解耦的理念。反正能用就行,自己看场景发挥。

注意:如果省略命名空间,它将解析为EventListener的命名空间。

参数:TriggerTemplates可以声明由TriggerBinding或EventListener提供的参数。参数必须具有名称,并且可以具有可选的描述和默认值。可以使用以下变量替换语法在TriggerTemplate中引用参数,其中参数的名称为:

$(params.<name>)

参数的目的是使TriggerTemplates可重用。

TriggerBinding

TriggerBindings是用于绑定事件的。使用TriggerBindings可以捕获事件中的字段并将其存储为参数。如下例:

apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerBinding
metadata:name: pipeline-binding
spec:params:- name: gitrevisionvalue: $(body.head_commit.id)- name: gitrepositoryurlvalue: $(body.repository.url)- name: contenttypevalue: $(header.Content-Type)

TriggerBindings接收从EventListener发送过来的参数,然后传入TriggerTemplates,在该模板上实例化Pod,以“侦听”各个事件。
参数:TriggerBindings可以提供传递给TriggerTemplate需要的参数。每个参数都有一个名称和一个值。
事件变量:TriggerBindings可以使用$()中包装的JSONPath表达式来访问HTTP JSON正文和标头中的值。标头中的密钥不区分大小写。
这些都是有效表达式:

$(body.key1)
$(.body.key)

这些是无效表达式:

.body.key1 # INVALID - Not wrapped in $()
$({body) # INVALID - Ending curly brace absent

如果()嵌入另一个()嵌入另一个()嵌入另一个()内(json中嵌入json的情况),我们将使用最里面的$()的内容作为JSONPath表达式

$($(body.b)) -> $(body.b)
$($($(body.b))) -> $(body.b)

带点的key怎么获取?访问包含.的JSON字符,我们需要转义。例如:

# body contains a filed called "tekton.dev" e.g. {"body": {"tekton.dev": "triggers"}}
$(body.tekton\.dev) -> "triggers"

举个使用例子:

`$(body)` 代表整个Body体中的json.$(body) -> "{"key1": "value1", "key2": {"key3": "value3"}, "key4": ["value4", "value5", "value6"]}"$(body.key1) -> "value1"   获取body中key1的值$(body.key2) -> "{"key3": "value3"}"  获取body中key2的值$(body.key2.key3) -> "value3" $(body.key4[0]) -> "value4"$(body.key4[0:2]) -> "{"value4", "value5"}"# $(header) 代表事件中的header$(header) -> "{"One":["one"], "Two":["one","two","three"]}"$(header.One) -> "one"$(header.one) -> "one"$(header.Two) -> "one two three"$(header.Two[1]) -> "two"

多个绑定:在EventListener中,您可以将多个绑定指定为触发器的一部分。这使您可以创建可重用的绑定,这些绑定可以与各种触发器混合并匹配。例如,触发器具有一个绑定,该绑定提取事件信息,而另一个绑定提供部署环境信息,如下:

apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerBinding
metadata:name: event-binding
spec:params:- name: gitrevisionvalue: $(body.head_commit.id)- name: gitrepositoryurlvalue: $(body.repository.url)
---
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerBinding
metadata:name: prod-env
spec:params:- name: environmentvalue: prod
---
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerBinding
metadata:name: staging-env
spec:params:- name: environmentvalue: staging
---
apiVersion: triggers.tekton.dev/v1alpha1
kind: EventListener #在listener中组合binding和template
metadata:name: listener
spec:triggers:- name: prod-trigger  #触发器1bindings: #trigger-binding #两个绑定- name: event-binding- name: prod-envtemplate: #引用已有的templatename: pipeline-template- name: staging-trigger # 触发器2bindings:# 引用定义的trigger-binding #两个绑定- name: event-binding- name: staging-envtemplate: #引用已有的templatename: pipeline-template

关于这个例子,之后我会出个实践例子。

EventListener

EventListener也是trigger的CRD资源,它允许用户以声明方式处理带有JSON负载的基于HTTP的传入事件。用户可以声明TriggerBindings以从事件中提取字段,并将其应用于TriggerTemplates进而创建Tekton资源。此外,EventListeners允许使用事件拦截器进行轻量级的事件处理(这个之后有机会再讲)。

多租户问题

与在其他地方看到的通过kubectl或tkn进行的示例用法相比,EventListener实际上是Tekton的另一种客户端形式。特别是,基于HTTP的事件会绕过您通过kubeconfig文件和kubectl config系列命令获得的常规Kubernetes身份验证路径。所以,至少每个EventListener都需要拥有自己的ServiceAccount,并且所有接收的事件都会导致Tekton资源交互,而tekton资源交互使用的权限就是ServiceAccount所赋予的。但是,如果您需要跨各种触发器和拦截器对一组Tekton资源进行不同级别的许可,而并非所有触发器或拦截器都以相同的方式操作某些Tekton资源,那么简单的单个EventListener将无法满足要求。

多个EventListeners (每个Ns都可以有一个EventListener)

您可以创建多个EventListener对象,如果在它们自己的命名空间中创建每个EventListener,则可以轻松地为每个ServiceAccount分配不同的权限来满足您的需求。通常,创建命名空间的同时还会定义一组默认的ServiceAccounts和Secrets。

缺点:从总体上讲,带有关联的Secrets和ServiceAccounts的命名空间被证明是etcd存储底层Kubernetes中最昂贵的项目(开销比较大)。在更大的集群中,etcd的存储容量可能成为一个问题。 多个EventListener意味着必须向访问“接收器”的外部实体公开多个HTTP端口,如果您的集群和外部实体之间恰好有一个HTTP防火墙,这意味着要增加管理成本,请在防火墙中为每个服务打开端口,除非您可以使用Kubernetes Ingress充当EventListeners集合的路由抽象层。

Multiple EventListeners (一个命名空间下多个EventListeners )

每个命名空间有多个EventListener,这很可能意味着管理员需要进行更多的ServiceAccount / Secret / RBAC操作。但是,通过减少命名空间的数量,您可以节省etcd的存储成本。 多个EventListener和潜在的防火墙问题仍然存在(同样,除非您使用Ingress)

ServiceAccount per EventListenerTrigger(一个EventListenerTrigger一个serviceAccount)

能够在EventListenerTrigger上设置ServiceAccount的功能还允许获得更细粒度的权限。 您仍然必须创建其他ServiceAccounts。 但是,如果不使用Ingress,则留在1个命名空间内,并通过与其关联的“接收器”将EventListener的数量减至最少,可以将对etcd存储和端口注意事项的担心降至最低。

暴露EventListener的方式

trigger作为触发器暴露服务的方式是通过http对外提供api接口,而对外提供http的具体实现,trigger这边提供了两种:使用k8s的ingress和使用Openshift Route。

Ingress

trigger controller会为每一个建立的eventlistener创建对应的deployment,该deployment的副本数是1,你可以为该deployment创建service,而service的selector选择的标签是eventlistener: build-listener。build-listener是所创建的eventlistener的资源名称。如果你想将service暴露出去,可以使用Ingress的方式:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:name: ingress-resourcenamespace: getting-startedannotations:kubernetes.io/ingress.class: nginxnginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:rules:- http:paths:- path: /backend:serviceName: getting-started-listener-b8rqz # REPLACE WITH YOUR SERVICE NAME FROM STEP 2servicePort: 8080

如果你的触发器只在内网中使用,那么service就够了。

Using Openshift Route

trigger提供的第二种暴露事件监听器的方式是openshift,Openshift也是为了解决从集群外部(就是从除了集群节点以外的其它地方)访问服务的需求。我目前还没用,暂时不介绍用法,有兴趣的同学自行谷歌吧。

总结

以上就是trigger中的主要内容,还存在一些例如拦截器和对接github/gitlab的内容,我将放在之后的实践文章中。本篇主要介绍了tekton的trigger组件中的核心概念:TriggerTemplate, TriggerBinding, EventListener。记住下面这张图,你就能掌握trigger运行原理:

看着这张图,就想到:事件发送给eventListener 的pod,pod讲事件中的参数解析给到triggerbinding,triggerbind找到关联的triggerTemplate并把参数传入,triggerTemplate实例化tekton中的资源(即创建),以上过程实现从一个http请求到运行一个完整的工作流。

如有问题,烦请留言。

最后的最后,要是对我写的内容有兴趣,可以关注下微信公众号“云原生手记”。

云原生CI/CD:Tekton之trigger介绍相关推荐

  1. 云原生 CI/CD 框架 Tekton 初体验

    Tekton 是一款功能非常强大而灵活的 CI/CD 开源的云原生框架.Tekton 的前身是 Knative 项目的 build-pipeline 项目,这个项目是为了给 build 模块增加 pi ...

  2. 云原生CI/CD:Tekton/pipelin之pipeline概念篇

    云原生CI/CD:Tekton/pipelin之pipeline概念篇 本节介绍下tekton中pipeline概念.作为云原生的CI/CD神器在之前介绍的task和taskrun之后,还有什么强大的 ...

  3. 云原生CI/CD:tekton/pipeline之认证篇

    云原生CI/CD:tekton/pipeline之认证篇 既然说tekton/pipeline是CI/CD,必然需要用到拉取git仓库代码,仓库代码可能是私有的,看下tekton/pipeline在这 ...

  4. 开源云原生CI/CD框架Tekton国内部署方式

    Tekton 是一款功能非常强大而灵活的 CI/CD 开源的云原生框架.致力于提供全功能.标准化的云原生 CI/CD 解决方案.[本文主要是通过流水线自动化的将tekton镜像同步到腾讯云仓库,并部署 ...

  5. 云原生CI/CD框架Tekton国内部署方式

    Tekton 是一款功能非常强大而灵活的 CI/CD 开源的云原生框架.致力于提供全功能.标准化的云原生 CI/CD 解决方案.[本文主要是通过流水线自动化的将tekton镜像同步到腾讯云仓库,并部署 ...

  6. Kubernetes原生CI/CD构建框架Tekton详解

    流水线(Pipeline)是把一个重复的过程分解为若干个子过程,使每个子过程与其他子过程并行进行的技术.本文主要介绍了诞生于云原生时代的流水线框架 Tekton. 什么是流水线? 在计算机中,流水线是 ...

  7. 【 云原生 | kubernetes 】- tekton构建CI/CD流水线(二)

    ​ 上一节我们是通过创建Pipelinerun来触发流水线来进行构建,实际生产中完全自动化的实现需要借助tekton中的triggers.本文是上篇的拓展请先了解这篇文章 Tekton Trigger ...

  8. kubernetes原生ci/cd工具tekton版本升级至v0.18.1

    前言 最近没啥好写的,一直都在弄hpa的问题,也就是解决hpa没生效的问题,以及最优minReplica最小基数的问题.也已经划水了两篇博客了,所以今天就来简单记录一下之前做过的一个小任务,也就是将项 ...

  9. 明源云创CI/CD技术演进

    源宝导读:在敏捷迭代的过程中需要能够快速的把开发的代码集成打包部署到各个环节对应的环境中.为了高效稳定的完成这个工作,我们引入了DevOps实践理论,并形成了配套的CI/CD工具.本文将介绍云创的CI ...

最新文章

  1. IEEE 解除对华为的限制!
  2. PTA数据结构与算法题目集(中文)7-24
  3. Moses 里的参数(未完成)
  4. 哪里可以接到python的活干-学了Python以后,我干了很多不是人干的活
  5. c#读取Sybase中文乱码的解决办法
  6. HDU 6155 Subsequence Count (DP、线性代数、线段树)
  7. 香港小學一年級入學考試題
  8. docker 日志_Docker容器日志管理最佳实践
  9. Java ForkJoin 框架初探
  10. leetcode958. Check Completeness of a Binary Tree
  11. Oracle常规恢复的实验测试
  12. 【应用推荐】用狗屁不通文章生成器写文章
  13. SpringBoot项目启动报错
  14. 全球与中国ARM开发套件市场现状及未来发展趋势
  15. 使用Simian工具扫描重复代码
  16. GitLab The requested URL returned error: 502
  17. 文因互联 CEO 鲍捷:确保搞砸人工智能项目的十种方法
  18. C++整型int转字符串string
  19. 【广州芯享家】服务器维护过程中,你需要了解的5个小常识
  20. 图像边缘Canny算子提取

热门文章

  1. 三种方法求递归算法的时间复杂度(递推,master定理,递归树)
  2. ThreeJS FBXLoader 加载3D文件,材质消失,已解决
  3. python的全局静态变量
  4. Java中的线程状态
  5. Pytorch中KL loss
  6. Android Killer的安装和配置 -安卓逆向的必备神器
  7. ROS语音交互系统_(3)ROS中接入图灵机器人语音理解系统
  8. 芯片的本质是什么?(4)物质与数字世界接口
  9. 计算机化工应用答案,计算机化工应用习题及解答.pdf
  10. 2007年9月19日