快速开始

本指南将通过创建一个简单的 “Hello World” trigger 场景帮助你快速上手 Tekton Triggers,并演示其基本功能。本文档按以下步骤进行:

  1. 配置 EventListener 自动暴露规则,以便将 EventListener 对外暴露
  2. 创建 EventListener 及相关资源
  3. 从 EventListener 的状态中获取自动生成的 webhook 地址

前提条件

  1. 环境要求

    • Kubernetes 版本 1.21 或更高
    • 已安装 Tekton Operator
    • 确保已通过 Operator 安装并就绪 Tekton Triggers
  2. 所需工具

    • kubectl 命令行工具
    • curl(用于测试 trigger)
  3. 权限

    • 需要 集群管理员权限(用于配置 EventListener 自动暴露规则)
    • 需要 命名空间管理员权限(用于创建 EventListener 资源)

步骤 1:配置 EventListener 自动暴露规则

INFO

关于自动暴露特性

这是一个 Alauda 平台增强功能(不属于标准 Tekton Triggers),用于简化 EventListener 的外部访问配置。

暴露 EventListener 的三种方式:

  1. 自动暴露(Alauda 增强) ⭐ 生产环境推荐

    • 自动创建并管理 Ingress 资源
    • 通过 TektonConfig 进行集中配置
    • webhook URL 会自动填充到 EventListener 的状态中
    • 适用于拥有多个 EventListener 的生产环境
  2. 手动 Ingress(标准 Tekton 方式)

    • 你需要为每个 EventListener 手动创建 Ingress 资源
    • 可控性更强,但维护成本更高
    • 标准 Kubernetes 方式
  3. Port-Forward 或 NodePort(测试/开发) 🚀 最容易上手

    • 无需 Ingress 或 DNS 配置
    • 适合本地测试和学习
    • 如果你想快速开始,请参见 跳到简单测试设置

如果你是 Triggers 新手,可以先跳过此步骤,直接前往 简单测试设置 章节,使用 port-forward 快速开始。等准备好进行生产部署时,再回来配置自动暴露。

TIP

EventListener 自动暴露特性会根据你配置的暴露规则,自动为 EventListener 创建 Ingress 资源。这样就无需手动创建和管理 Ingress 资源。你需要先配置这些规则,EventListener 才能通过外部 URL 访问。有关详细配置说明,请参见 配置 EventListener 自动暴露规则。

前提条件

在配置暴露规则之前,请确保已满足以下前提条件:

  1. LoadBalancer 或 Gateway 配置(生产环境推荐):

    • 对于生产环境,建议使用 LoadBalancer 或 Gateway 来暴露 EventListener
    • LoadBalancer/Gateway 应已配置并可访问
    • 你应当拥有将用于 webhook 的外部域名或 IP 地址
  2. Ingress Controller(如果使用 Ingress):

    • 集群中应已安装并运行 Ingress controller(如 NGINX、ALB 或 Traefik)
    • 你应当知道将要使用的 IngressClass 名称
    • 有关创建 Ingress 的更多信息,请参见 创建 Ingress。
  3. 域名和证书(用于 HTTPS):

    • 如果使用 HTTPS,请确保已配置域名
    • 应准备好 TLS 证书(可手动创建或通过 cert-manager 获取)
INFO

重要说明:

  • 自动暴露特性会根据暴露规则自动为你创建 Ingress 资源。通常你无需手动创建或修改 Ingress 资源。
  • 如果你使用带自定义端口的 LoadBalancer,请务必在 externalHosts 字段中包含端口号(例如,https://webhooks.example.com:8443)。
  • 对于开发或测试环境,也可以使用 NodePort 代替 Ingress/LoadBalancer。详情请参见 NodePort 配置示例。

通过 TektonConfig 配置暴露规则

创建或更新 TektonConfig 资源以配置暴露规则。创建文件 tektonconfig.yaml:

apiVersion: operator.tekton.dev/v1alpha1
kind: TektonConfig
metadata:
  name: config
spec:
  pipeline:
    options:
      configMaps:
        trigger-wrapper-config:
          data:
            config: |
              export-rules:
                - name: demo-webhooks
                  host: webhooks.example.com  # Replace with your domain. Ensure DNS resolution is configured (or add to /etc/hosts for testing)
                  ingressClass: nginx  # Replace with your ingress class
                  urlPathPrefix: /triggers
                  externalHosts:
                    - "https://webhooks.example.com"  # Replace with your external URL (this is what users will copy to GitHub/GitLab webhook settings)
                  namespaceSelector:
                    matchNames:
                      - "tekton-triggers-demo"  # Match your demo namespace

理解自动暴露

自动暴露特性的工作方式如下:

  1. 读取你在 TektonConfig 中配置的暴露规则
  2. 为匹配规则的 EventListener 自动创建 Ingress 资源
  3. 将 webhook URL 填充到 EventListener 的 status.addresses 字段中,并可在 UI 中显示
  4. 消除为每个 EventListener 手动创建和管理 Ingress 资源的需要

这种方式提供了一种集中化的 EventListener 暴露管理方案,便于在整个集群中维护一致的 webhook URL 模式。

选择 Ingress 配置方式

自动暴露特性支持两种 Ingress 配置方式,用于将 EventListener 对外暴露。请选择最适合你环境的方式:

INFO

替代方案:NodePort 配置

如果你没有 LoadBalancer 或 Ingress controller,或者希望在开发/测试中使用更简单的配置,也可以使用 NodePort。详情请参见 NodePort 配置示例。使用 NodePort 时不需要自动暴露特性,因为你可以直接通过节点 IP 和 NodePort 访问 EventListener。

方式 1:通用 Ingress 配置(生产环境推荐)

这种方式适用于大多数 Kubernetes 环境。你需要:

  1. 创建一个 IngressClass(如果尚不存在): 更多信息请参见 创建 Ingress。

  2. 或者使用 LoadBalancer Service 获取外部 IP 地址 更多信息请参见 配置负载均衡器。

  3. 根据你的 Ingress 设置配置暴露规则:

    • 如果使用 IngressClass:将 ingressClass 设置为你的 IngressClass 名称(例如,nginx)
    • 如果使用 LoadBalancer:从 LoadBalancer service 获取外部 IP/域名,并据此配置 host 和 externalHosts

IngressClass 的示例配置:

export-rules:
  - name: demo-webhooks
    host: webhooks.example.com  # Your domain name. Ensure DNS resolution is configured (or add to /etc/hosts for testing)
    ingressClass: nginx  # Your IngressClass name
    urlPathPrefix: /triggers
    externalHosts:
      - "https://webhooks.example.com"  # External accessible URL
WARNING

DNS 配置:当使用域名配置 host 字段时,请确保:

  • DNS 记录已正确配置,能够将域名解析到 Ingress controller 的 IP 地址
  • 在本地测试时,你可以将该域名添加到 /etc/hosts(Linux/Mac)或 C:\Windows\System32\drivers\etc\hosts(Windows)
  • 该域名必须能够被发送 webhook 的系统解析(如 GitHub、GitLab 等)

方式 2:ACP 企业集群快速开始

如果你使用的是 ACP(Alauda Container Platform)企业集群,可以利用平台内置的 gateway 快速完成配置:

  1. 获取你的 ACP 平台访问地址(例如,https://192.168.1.100)
  2. 获取你的集群名称(例如,test)
  3. 按如下方式配置暴露规则:
    • 将 host 设为空(或使用通配符 *)
    • 将 externalHosts 设置为:<ACP Platform Access Address>/clusters-rewrite/<Cluster Name>
    • 最终的 webhook URL 将是:<externalHost>/<urlPathPrefix>/<eventlistener-namespace>/<eventlistener-name>

ACP 的示例配置:

export-rules:
  - name: demo-webhooks
    host: ""  # Empty or use wildcard "*"
    ingressClass: nginx  # Use default ingress class
    urlPathPrefix: /triggers
    externalHosts:
      - "https://192.168.1.100/clusters-rewrite/test"  # ACP Platform URL + /clusters-rewrite/<cluster-name>. Final webhook: https://192.168.1.100/clusters-rewrite/test/triggers/tekton-triggers-demo/hello-listener
    namespaceSelector:
      matchNames:
        - "tekton-triggers-demo"

使用此配置后,webhook 地址将是:

https://192.168.1.100/clusters-rewrite/test/triggers/tekton-triggers-demo/hello-listener
TIP

ACP 配置公式:

  • ACP 平台 URL:https://192.168.1.100
  • 集群名称:test
  • URL Path Prefix:/triggers(可配置)
  • External Host:https://192.168.1.100/clusters-rewrite/test
  • 最终 webhook URL:https://192.168.1.100/clusters-rewrite/test/triggers/<eventlistener-namespace>/<eventlistener-name>

示例:如果 ACP 平台地址是 https://192.168.1.100,集群名称是 test,并且 urlPathPrefix 为 /triggers,那么访问地址就是 https://192.168.1.100/clusters-rewrite/test/triggers。

WARNING

重要:请将占位值(webhooks.example.com、nginx 等)替换为你的实际域名、ingress class 和 external host URL。如果你没有配置域名,可以使用空的 host 字段,并使用实际可访问的 URL 配置 externalHosts。

应用 TektonConfig

$ kubectl apply -f tektonconfig.yaml
tektonconfig.operator.tekton.dev/config created

验证配置

等待片刻让 Operator 同步配置,然后执行验证:

$ kubectl get configmap trigger-wrapper-config -n tekton-pipelines -o yaml
apiVersion: v1
data:
  config: |
    export-rules:
      - name: demo-webhooks
        host: webhooks.example.com
        ...
kind: ConfigMap
metadata:
  name: trigger-wrapper-config
  namespace: tekton-pipelines

ConfigMap 应该包含你的暴露规则配置。(注意:ConfigMap 名称 trigger-wrapper-config 是一个内部技术名称;你无需记住它,只需通过 TektonConfig 管理配置即可。)

步骤 2:创建示例项目

创建命名空间

$ kubectl create namespace tekton-triggers-demo
namespace/tekton-triggers-demo created
TIP

关于 EventListener 的 ServiceAccount

在本快速开始中,我们将使用 默认 ServiceAccount,该账户由 Tekton Triggers 系统 自动创建。这个 ServiceAccount 名为 triggers-default-sa,并具有命名空间范围的权限。

工作原理:

  • 安装 Tekton Triggers 时,系统会在每个命名空间中自动创建一个默认 ServiceAccount
  • 你可以通过以下命令找到它:kubectl get sa -n tekton-triggers-demo -l triggers.tekton.dev/default-service-account
  • 该 ServiceAccount 具有在同一命名空间内创建 TaskRuns 和 PipelineRuns 的权限
  • 无需手动配置——只需按名称引用即可:triggers-default-sa

何时需要自定义 ServiceAccount:

  • 如果你需要在多个命名空间中创建资源(跨命名空间 triggers)
  • 如果你需要超出默认范围的额外权限
  • 有关自定义 ServiceAccount 配置,请参见 设置 EventListener

步骤 3:创建 Hello World TaskRun

创建 Task

创建文件 hello-task.yaml:

apiVersion: tekton.dev/v1
kind: Task
metadata:
  name: hello-task
  namespace: tekton-triggers-demo
spec:
  params:
    - name: message
      description: Message to print
      type: string
      default: "Hello World!"
  steps:
    - name: echo
      image: alpine
      script: |
        echo "$(params.message)"

创建 Trigger Template

创建文件 trigger-template.yaml:

apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
  name: hello-template
  namespace: tekton-triggers-demo
spec:
  params:
    - name: message
      description: Message to print
      default: "Hello World!"
  resourcetemplates:
    - apiVersion: tekton.dev/v1
      kind: TaskRun
      metadata:
        generateName: hello-run-
        namespace: tekton-triggers-demo
      spec:
        taskRef:
          name: hello-task
        params:
          - name: message
            value: $(tt.params.message)

创建 Trigger Binding

创建文件 trigger-binding.yaml:

apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerBinding
metadata:
  name: hello-binding
  namespace: tekton-triggers-demo
spec:
  params:
    - name: message
      value: $(body.message)

创建 Event Listener

创建文件 event-listener.yaml:

apiVersion: triggers.tekton.dev/v1beta1
kind: EventListener
metadata:
  name: hello-listener
  namespace: tekton-triggers-demo
spec:
  # Run the following order to get ServiceAccount works for triggers within the same namespace
  # $ kubectl get sa -n ${YOUR_NS} -l triggers.tekton.dev/default-service-account -o jsonpath='{.items[0].metadata.name}'
  serviceAccountName: triggers-default-sa  # Or set to <your service account> to use a custom ServiceAccount
  triggers:
    - name: hello-trigger
      bindings:
        - ref: hello-binding
      template:
        ref: hello-template
INFO

ServiceAccount 说明:这里使用的是 自动创建 的默认 ServiceAccount(通过将 serviceAccountName 设置为 triggers-default-sa)。该 ServiceAccount 由 Tekton Triggers 系统创建,并具有在同一命名空间内创建 TaskRuns/PipelineRuns 的权限。由于本示例中的所有资源都位于同一命名空间,这已经足够。自动暴露特性会根据步骤 1 中配置的暴露规则,为该 EventListener 自动创建 Ingress。

应用配置

应用所有已创建的资源:

$ kubectl apply -f hello-task.yaml
task.tekton.dev/hello-task created

$ kubectl apply -f trigger-template.yaml
triggertemplate.triggers.tekton.dev/hello-template created

$ kubectl apply -f trigger-binding.yaml
triggerbinding.triggers.tekton.dev/hello-binding created

$ kubectl apply -f event-listener.yaml
eventlistener.triggers.tekton.dev/hello-listener created

替代方案:简单测试设置

如果你跳过了步骤 1(自动暴露配置),并且想快速测试,可以使用 port-forward 或 NodePort,无需任何 Ingress 或 DNS 配置即可访问 EventListener。

选项 A:使用 Port-Forward(最简单)

等待 EventListener 就绪

$ kubectl wait --for=condition=Ready eventlistener/hello-listener -n tekton-triggers-demo --timeout=60s
eventlistener.triggers.tekton.dev/hello-listener condition met

将本地端口转发到 EventListener

$ kubectl port-forward -n tekton-triggers-demo svc/el-hello-listener 8080:8080
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080

保持此终端窗口打开。现在可以通过 http://localhost:8080 访问 EventListener。

通过 Port-Forward 发送测试请求

打开一个新终端并执行:

$ curl -v -H 'Content-Type: application/json' -d '{"message":"Hello, Tekton!"}' http://localhost:8080
* Connected to localhost (127.0.0.1) port 8080
> POST / HTTP/1.1
> Host: localhost:8080
...
< HTTP/1.1 201 Created
{"eventListener":"hello-listener","namespace":"tekton-triggers-demo","eventID":"..."}

查看结果

# View the created TaskRun
$ kubectl get taskrun -n tekton-triggers-demo
NAME              SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
hello-run-xxxxx   True        Succeeded   1m          50s

# View TaskRun logs
$ kubectl logs -l triggers.tekton.dev/eventlistener=hello-listener -n tekton-triggers-demo
Hello, Tekton!

选项 B:使用 NodePort

如果你想在没有 Ingress 的情况下,从本机之外访问 EventListener:

将 EventListener Service 修补为 NodePort

$ kubectl patch svc el-hello-listener -n tekton-triggers-demo -p '{"spec":{"type":"NodePort"}}'
service/el-hello-listener patched

获取 NodePort

$ export NODE_PORT=$(kubectl get svc el-hello-listener -n tekton-triggers-demo -o jsonpath='{.spec.ports[0].nodePort}')
$ export NODE_IP=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="ExternalIP")].address}')

# If NODE_IP is empty, use InternalIP
$ if [ -z "$NODE_IP" ]; then
  export NODE_IP=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}')
fi

$ echo "EventListener accessible at: http://$NODE_IP:$NODE_PORT"
EventListener accessible at: http://192.168.1.100:32567

通过 NodePort 发送测试请求

$ curl -v -H 'Content-Type: application/json' -d '{"message":"Hello, Tekton!"}' http://$NODE_IP:$NODE_PORT
* Connected to 192.168.1.100 (192.168.1.100) port 32567
> POST / HTTP/1.1
...
< HTTP/1.1 201 Created
{"eventListener":"hello-listener","namespace":"tekton-triggers-demo","eventID":"..."}
TIP

各方式适用场景:

  • Port-forward:本地测试、开发、学习
  • NodePort:从其他机器进行测试、开发集群
  • 自动暴露(Ingress):生产部署、外部 webhook(GitHub、GitLab 等)

步骤 4:获取 webhook 地址并测试(使用自动暴露)

等待 EventListener 就绪

# Wait for the Pod to be ready
$ kubectl get pods -n tekton-triggers-demo
NAME                                 READY   STATUS    RESTARTS   AGE
el-hello-listener-xxxxxxxxxx-xxxxx   1/1     Running   0          30s

# Wait for EventListener to be ready
$ kubectl wait --for=condition=Ready eventlistener/hello-listener -n tekton-triggers-demo --timeout=60s
eventlistener.triggers.tekton.dev/hello-listener condition met

获取自动生成的 webhook 地址

自动暴露特性会根据步骤 1 中配置的暴露规则自动生成外部 webhook 地址。这些地址会填充到 EventListener 的 status.addresses 字段中:

# Get the first webhook address from status.addresses
$ export EL_URL=$(kubectl get el hello-listener -n tekton-triggers-demo -o jsonpath='{.status.addresses[0].url}')

# Or view all available addresses
$ kubectl get el hello-listener -n tekton-triggers-demo -o jsonpath='{.status.addresses[*].url}' | tr ' ' '\n'
https://webhooks.example.com/triggers/tekton-triggers-demo/hello-listener
https://backup.webhooks.example.com/triggers/tekton-triggers-demo/hello-listener
TIP

地址格式:webhook 地址遵循以下模式:<externalHost>/<urlPathPrefix>/<eventlistener-namespace>/<eventlistener-name>

例如:https://webhooks.example.com/triggers/tekton-triggers-demo/hello-listener

如果 status.addresses 为空,请检查:

  • 你配置的暴露规则是否与 EventListener 的命名空间匹配
  • 自动暴露控制器是否正在运行并已处理该 EventListener
  • 查看控制器日志:kubectl logs -n tekton-pipelines -l app=tektoncd-enhancement-controller
WARNING

网络访问:请确保你用于测试的外部 host URL 可访问。如果你是在集群内部进行测试,可能需要改用 port-forward 或直接访问内部 service 地址。

验证 webhook 域名可访问性

在发送测试请求之前,请先验证你的 webhook 域名是否可访问:

# Test if the webhook URL is accessible
# Replace the URL with your actual webhook address from status.addresses
curl -I $EL_URL

# Or test with a simple GET request (some webhook endpoints may not support GET, but this helps verify connectivity)
curl -v $EL_URL
WARNING

重要:请确保基于 LoadBalancer/Gateway 配置的 webhook 域名可被外部系统访问。如果你要在 GitHub、GitLab 或其他外部系统中配置 webhook,它们必须能够访问该 URL。请检查:

  • DNS 记录是否正确配置
  • LoadBalancer/Gateway 是否已正确配置并可访问
  • 防火墙规则是否允许入站流量
  • TLS 证书是否有效(如果使用 HTTPS)

向 webhook 发送测试请求

$ curl -v -H 'Content-Type: application/json' -d '{"message":"Hello, Tekton!"}' $EL_URL
* Connected to webhooks.example.com (xx.xx.xx.xx) port 443
> POST /triggers/tekton-triggers-demo/hello-listener HTTP/1.1
> Host: webhooks.example.com
...
< HTTP/1.1 201 Created
{"eventListener":"hello-listener","namespace":"tekton-triggers-demo","eventID":"..."}

查看结果

# View the created TaskRun
$ kubectl get taskrun -n tekton-triggers-demo
NAME              SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
hello-run-xxxxx   True        Succeeded   1m          50s

# View logs of the specific TaskRun
$ kubectl logs -l eventlistener=hello-listener -n tekton-triggers-demo
Hello, Tekton!

清理资源

测试完成后,你可以删除已创建的资源:

$ kubectl delete namespace tekton-triggers-demo
namespace "tekton-triggers-demo" deleted

下一步

现在你已经成功创建并测试了一个基础 Tekton Triggers 示例,可以继续:

  1. 探索 Tekton Triggers 的概念
  2. 学习如何使用 设置 EventListeners 进行常见配置
  3. 为更高级的暴露场景配置 EventListener 自动暴露规则
  4. 设置并使用 GitLab events 来触发 pipelines

常见问题

  1. EventListener Pod 启动失败

    • 检查默认 ServiceAccount 是否具有足够的命名空间范围权限
    • 验证 EventListener 资源是否已正确配置
    • 查看 EventListener Pod 日志:kubectl logs -n tekton-triggers-demo -l app=el-hello-listener
  2. webhook 地址(status.addresses)为空

    • 验证你配置的暴露规则是否与 EventListener 的命名空间匹配
    • 检查自动暴露控制器是否正在运行:kubectl get pods -n tekton-pipelines -l app=tektoncd-enhancement-controller
    • 查看控制器日志,确认是否存在匹配或配置错误
    • 确保 namespaceSelector.matchNames 中的命名空间与 EventListener 的命名空间一致
  3. Trigger 无响应

    • 验证 webhook URL 是否可访问(检查 status.addresses)
    • 检查请求格式是否正确
    • 查看 EventListener Pod 日志:kubectl logs -n tekton-triggers-demo -l app=el-hello-listener
    • 验证共享 Ingress 是否已正确配置(它创建于 Tekton 系统命名空间中,并以暴露规则命名,而不是按每个 EventListener 单独创建):kubectl get ingress -n tekton-pipelines
  4. 未创建 TaskRun

    • 确认 TriggerTemplate 配置正确
    • 检查 TriggerBinding 中的参数映射
    • 查看 EventListener Pod 的错误日志