快速开始

本指南将通过创建一个简单的 "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(用于测试 triggers)
  3. 权限

    • 需要 cluster administrator privileges(用于配置 EventListener 自动暴露规则)
    • 需要 namespace administrator privileges(用于创建 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(测试/开发) 🚀 最容易上手

如果你刚接触 Triggers,可以先跳过这一步,直接进入 简单测试环境设置 部分,通过 port-forward 开始。等你准备好进行生产部署时,再回来配置自动暴露。

TIP

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

前置条件

在配置导出规则之前,请确保你已具备以下条件:

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

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

    • 集群中应已安装并运行一个 Ingress controller(如 NGINX、ALB 或 Traefik)
    • 你应了解将要使用的 IngressClass 名称
    • 有关创建 Ingress 的更多信息,请参见 Creating Ingresses。
  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. 为匹配规则的 EventListeners 自动创建 Ingress 资源
  3. 使用可在 UI 中展示的 webhook URL 填充 EventListener 的 status.addresses 字段
  4. 无需为每个 EventListener 手动创建和管理 Ingress 资源

这种方式提供了一种集中管理 EventListeners 暴露方式的方法,使你更容易在整个集群中维护一致的 webhook URL 模式。

选择 Ingress 配置方式

自动暴露功能支持两种配置 Ingress 以将 EventListeners 暴露到外部的方式。请选择最适合你环境的方式:

INFO

替代方案:NodePort 配置

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

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

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

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

  2. 或者使用 LoadBalancer Service 获取外部 IP 地址 更多信息请参见 Configure a Load Balancer。

  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:创建示例项目

创建 Namespace

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

关于 EventListener 的 ServiceAccount

在这个快速开始示例中,我们将使用 Tekton Triggers 系统自动创建的默认 ServiceAccount。这个 ServiceAccount 名称为 triggers-default-sa,并具有 namespace 级别的权限。

工作原理:

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

何时需要自定义 ServiceAccount:

  • 如果你需要在多个 namespace 中创建资源(跨 namespace triggers)
  • 如果你需要默认范围之外的额外权限
  • 有关自定义 ServiceAccount 配置,请参见 Setup 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 系统创建,具有在同一 namespace 内创建 TaskRuns/PipelineRuns 的权限。由于本示例中的所有资源都位于同一 namespace,因此这已经足够。自动暴露功能会根据第 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 来访问 EventListener,而无需任何 Ingress 或 DNS 设置。

选项 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":"..."}

查看结果

# 查看创建的 TaskRun
$ kubectl get taskrun -n tekton-triggers-demo
NAME              SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
hello-run-xxxxx   True        Succeeded   1m          50s

# 查看 TaskRun 日志
$ 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 的 namespace
  • 自动暴露控制器是否正在运行并已处理该 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":"..."}

查看结果

# 查看创建的 TaskRun
$ kubectl get taskrun -n tekton-triggers-demo
NAME              SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
hello-run-xxxxx   True        Succeeded   1m          50s

# 查看特定 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. 学习如何使用 Setup EventListeners 进行常见设置
  3. 配置 EventListener automatic exposure rules 以支持更高级的暴露场景
  4. 设置并使用 Gitlab events 来触发 pipelines

常见问题

  1. EventListener Pod 启动失败

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

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

    • 验证 webhook URL 是否可访问(检查 status.addresses)
    • 检查请求格式是否正确
    • 查看 EventListener Pod 日志:kubectl logs -n tekton-triggers-demo -l app=el-hello-listener
    • 验证 Ingress 是否配置正确:kubectl get ingress -n tekton-triggers-demo
  4. 未创建 TaskRun

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