快速开始

本指南将通过创建一个简单的 "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 配置(推荐用于生产环境):

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

    • 集群中应已安装并运行一个 Ingress controller(如 NGINXALBTraefik
    • 你应了解将要使用的 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 填充 EventListenerstatus.addresses 字段
  4. 无需为每个 EventListener 手动创建和管理 Ingress 资源

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

选择 Ingress 配置方式

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

INFO

替代方案:NodePort 配置

如果你没有 LoadBalancerIngress 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/域名,并相应配置 hostexternalHosts

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.comnginx 等)替换为你的实际域名、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 内创建 TaskRunsPipelineRuns 的权限
  • 无需手动配置——直接使用名称引用即可: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-forwardNodePort 来访问 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 地址。这些地址会填充到 EventListenerstatus.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 的错误日志