使用触发器对Tekton工作负载进行动态调度

301 阅读4分钟

Tekton是一个Kubernetes原生的持续集成和交付(CI/CD)框架。它允许你通过Kubernetes自定义资源定义(CRD)声明性地创建容器化、可组合和可配置的工作负载。

Tekton Triggers是一个Tekton组件,允许你从各种来源的事件中检测和提取信息,并根据这些信息执行TaskRunsPipelineRuns。它还可以将提取的信息传递给事件中的TaskRuns和PipelineRuns。

本文以 GitLab 为例,说明 Tekton Triggers 如何与外部服务(如 Git 存储库)集成。

前提条件

如果您想遵循本文的步骤,您必须有一个运行 Kubernetes 1.18 或更高版本的 Kubernetes 集群,并安装一个可提供外部 IP 的入口控制器。您还必须安装Tekton PipelinesTekton Triggers

触发器流程

Tekton触发器允许你创建一个名为EventListener的特殊资源,它是一个Kubernetes服务,用于监听来自不同来源的HTTP请求,通常是Git仓库,包括GitLab、GitHub等托管的仓库。基于这些事件,EventListener pod会执行行动并创建Tekton资源,如TaskRun或PipelineRun。

A flow chart showing the interactions among EventListener, Trigger, and ClusterInterceptor.

所有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检测到一个事件时,实例化TaskRunPipelineRun

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/cataloggit-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。

screenshot of GitLab Webhooks configurations

通过推送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。