4、Tekton入门:Tekton架构、核心组件(Pipeline、Task、Step、Resource)、安装与CLI工具使用

Tekton 是云原生 CI/CD 领域中被广泛采用的开源框架,它运行在 Kubernetes 之上,将流水线中的每一个环节都抽象为 Kubernetes 自定义资源(CRD)。与 Jenkins 等传统单体 CI 系统不同,Tekton 天然具备容器化、松耦合、可移植和声明式管理的特性。理解 Tekton 的架构与核心对象模型,是掌握云原生持续交付的关键第一步。本节将深入剖析 Tekton 的架构分层、核心组件(Pipeline、Task、Step、Resource)的职责与关系,并演示如何在集群中安装 Tekton 以及使用 tkn 命令行工具进行日常操作。

Tekton 核心对象关系与执行链路 EventListener / Trigger PipelineRun(实例化执行) 绑定 Pipeline + 注入参数/资源 Pipeline(流水线定义) 编排多个 Task 的执行顺序与依赖 TaskRun(Task 实例化执行) 每个 Task 对应一个 Pod,隔离执行环境 Task(任务定义) 包含一个或多个 Step,按顺序执行 Step(步骤) Step 1: git clone → Step 2: mvn build → Step 3: docker push PipelineResource (Git/Image) PipelineResource (Image/Cluster) PVC 工作区(Workspace)共享数据 图例 事件触发 定义对象 运行实例

上图清晰地展示了 Tekton 的核心对象模型。最上层是事件监听器(EventListener),它负责接收外部 Webhook 请求并触发流水线。向下依次是 PipelineRun(流水线运行实例)、Pipeline(流水线定义)、TaskRun(任务运行实例)、Task(任务定义)以及最底层的 Step(步骤)。左侧和右侧的 PipelineResource 分别代表输入资源(如 Git 仓库)和输出资源(如构建好的镜像)。底部的工作区(Workspace)则用于在多个 Task 之间共享数据。理解这个层级关系是使用 Tekton 的基础。

4.1 Tekton 架构分层与设计哲学

核心原理:Kubernetes 原生与声明式驱动

Tekton 并非在 Kubernetes 之上构建一个独立的服务,而是将自身完全融入 Kubernetes 生态。它通过 CRD(Custom Resource Definition)扩展了 Kubernetes API,使得 Pipeline、Task 等对象可以像 Deployment、Service 一样被声明式地创建、查询和更新。这种设计的核心优势在于:

  • 无状态控制平面:Tekton 的控制器(Controller)只负责监听资源变化并创建相应的 Pod,自身不存储构建状态,状态全部保存在 Kubernetes ETCD 中。
  • 标准化执行环境:每个 Task 的执行都对应一个 Kubernetes Pod,这意味着构建环境是隔离的、可复制的,且资源配额(CPU/内存)可以直接通过 Kubernetes 管理。
  • 可移植性:由于所有配置都是 YAML 文件,可以轻松地在不同集群(本地、公有云、混合云)之间迁移,无需修改流水线定义。
架构分层说明:Tekton 的逻辑架构可以分为三层:接口层(CLI、API、Webhook)、控制层(Tekton Controller、PipelineRun/TaskRun 控制器)和执行层(Kubernetes Pod、容器)。控制层负责解析流水线定义、处理依赖关系、管理并发和重试;执行层则真正运行用户定义的容器命令。

判断方法:如何区分定义与实例

初学者最容易混淆的是“定义”和“实例”。判断标准很简单:名称中是否带有 Run 后缀。例如,Pipeline 是静态的“图纸”,而 PipelineRun 是这张图纸被实际执行后产生的“施工记录”。每次代码提交触发流水线时,都会创建一个新的 PipelineRun 对象。同样,Task 与 TaskRun 也是这种关系。这种设计允许同一个 Pipeline 定义被多次并行执行,且每次执行的参数、状态互不干扰。

案例拆解:一次完整的构建触发链路

假设开发者在 GitHub 上推送代码,希望自动触发镜像构建。其内部流程如下:

  1. GitHub Webhook 将 HTTP 请求发送到 Tekton 的 EventListener Service。
  2. EventListener 中的 Interceptor 验证请求签名,并提取分支、提交 SHA 等信息。
  3. EventListener 根据绑定规则(TriggerBinding)创建 PipelineRun 对象,并注入参数(如 Git 仓库 URL、分支名)。
  4. Tekton Controller 监听到新的 PipelineRun,开始解析对应的 Pipeline 定义。
  5. Controller 按依赖顺序为每个 Task 创建 TaskRun 对象。
  6. 每个 TaskRun 控制器创建一个 Pod,Pod 内的容器依次执行 Task 中定义的 Step 命令。

这一链路中,所有步骤都是异步、事件驱动的,且每一步的状态都会实时更新到对应 CRD 的 Status 字段中。

常见误区与复盘

误区:认为 Tekton 是 Jenkins 的替代品,可以直接迁移 Job。
分析:Tekton 是“无主节点”架构,没有中央调度器,所有任务都在独立的 Pod 中运行。这导致它不适合运行需要长时间占用固定资源、或有状态的服务型任务(如持续运行的测试环境)。
复盘:在引入 Tekton 前,应梳理现有 CI 任务类型。对于短时、无状态、可并行的构建/测试任务,Tekton 是理想选择;对于需要常驻或需要复杂交互的任务,建议保留 Jenkins 或使用其他工具。

4.2 核心组件详解:Pipeline、Task、Step、Resource

核心原理:从 Step 到 Pipeline 的逐级封装

Tekton 的组件模型是层层嵌套的。最基础的单位是 Step,它定义了一个容器以及要在该容器内执行的命令。多个 Step 按顺序组成一个 Task,Task 中的所有 Step 在同一个 Pod 中运行,共享文件系统(通过 emptyDir 卷)和网络命名空间。多个 Task 按依赖关系编排成一个 Pipeline。而 PipelineResource 则是用于在 Task 之间传递输入/输出数据的抽象,例如 Git 仓库、Docker 镜像、集群凭证等。

组件 作用域 关键属性 执行单元
Step Task 内部 image, script, command, args, env 单个容器
Task Pipeline 内部 steps[], params[], resources, workspaces 一个 Pod
Pipeline 全局 tasks[], params[], workspaces, finally 多个 Pod(按序或并行)
PipelineResource 全局 type (git/image/cluster), params 数据引用

操作流程:编写一个最小化的 Task 与 Pipeline

下面通过一个实际例子来展示如何定义这些组件。假设我们需要一个任务:克隆代码并打印提交信息。

# task-clone.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: git-clone
spec:
  workspaces:
    - name: source
  steps:
    - name: clone
      image: alpine/git:latest
      script: |
        cd $(workspaces.source.path)
        git clone https://github.com/example/demo.git .
        git log -1 --oneline

上述 Task 定义了一个名为 git-clone 的任务,它声明需要一个名为 source 的工作区(Workspace),并在 alpine/git 容器中执行克隆命令。接下来,我们定义一个 Pipeline 来引用这个 Task:

# pipeline-build.yaml
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: build-and-test
spec:
  workspaces:
    - name: shared-data
  tasks:
    - name: fetch-source
      taskRef:
        name: git-clone
      workspaces:
        - name: source
          workspace: shared-data
    - name: run-tests
      taskRef:
        name: run-tests
      runAfter:
        - fetch-source
      workspaces:
        - name: source
          workspace: shared-data

在这个 Pipeline 中,fetch-source 任务首先执行,完成后 run-tests 任务才会启动。两个任务通过 shared-data 工作区共享代码目录。

案例拆解:使用 PipelineResource 传递镜像信息

在更复杂的场景中,我们需要将构建好的镜像地址传递给后续的部署任务。此时可以使用 PipelineResource 的 image 类型。

# image-resource.yaml
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: my-app-image
spec:
  type: image
  params:
    - name: url
      value: registry.example.com/my-app:latest

在 Task 中,可以通过 resources.inputs 或 resources.outputs 引用该资源。Tekton 会自动将镜像 URL 注入到容器的环境变量中,并处理镜像的拉取与推送(如果配置了凭据)。

经验提醒:虽然 PipelineResource 功能强大,但 Tekton 社区已逐渐推荐使用 Workspace 替代资源传递,因为 Workspace 更灵活、更安全(不涉及敏感信息注入),且支持 PVC、ConfigMap、Secret 等多种类型。在 2023 年后的版本中,PipelineResource 已被标记为弃用状态,新项目建议直接使用 Workspace。

常见误区与复盘

误区:在 Task 中定义多个 Step 时,认为它们会并行执行。
分析:Task 中的 Step 是严格串行执行的。只有当一个 Step 的容器退出且退出码为 0 时,才会启动下一个 Step 的容器。如果需要并行,必须在 Pipeline 层面定义多个 Task,并让它们不设置 runAfter 依赖。
复盘:在设计流水线时,应优先考虑将可并行的操作拆分为独立的 Task,而不是塞进同一个 Task 的多个 Step 中。例如,单元测试和代码静态检查可以并行执行,应拆分为两个 Task。

4.3 安装 Tekton 与 tkn CLI 工具

核心原理:Operator 与 YAML 两种安装方式

Tekton 的安装分为两部分:控制平面组件(包括 Controller、Webhook、EventListener 等)和 CLI 工具(tkn)。控制平面推荐使用 Tekton Operator 进行安装,它能够自动管理版本升级和配置。对于快速体验,也可以直接应用官方发布的 YAML 文件。

操作流程:基于 Operator 的安装步骤

  1. 安装 Operator:首先需要安装 Tekton Operator 本身。
kubectl apply -f https://storage.googleapis.com/tekton-releases/operator/latest/tekton-operator.yaml
  1. 等待 Operator 就绪:检查 operator 命名空间下的 Pod 状态。
kubectl get pods -n tekton-operator --watch
  1. 创建 TektonConfig 资源:这是 Operator 的自定义资源,用于声明需要安装的组件(如 Pipeline、Dashboard、Triggers)。
cat <<EOF | kubectl apply -f -
apiVersion: operator.tekton.dev/v1alpha1
kind: TektonConfig
metadata:
  name: cluster
spec:
  profile: all
  targetNamespace: tekton-pipelines
EOF
  1. 验证安装:查看 tekton-pipelines 命名空间下的 Pod 是否全部运行。
kubectl get pods -n tekton-pipelines

CLI 工具安装与常用命令

tkn 是 Tekton 的命令行工具,可以极大提升操作效率。在 macOS 上可以使用 Homebrew 安装:

brew install tektoncd-cli

安装完成后,可以通过以下命令管理流水线资源:

命令 功能说明 示例
tkn pipeline list 列出所有 Pipeline tkn pipeline list -n my-namespace
tkn pipeline start 手动触发一个 PipelineRun tkn pipeline start build-and-test --showlog
tkn pipelinerun logs 查看 PipelineRun 的实时日志 tkn pipelinerun logs -f -n my-namespace
tkn task list 列出所有 Task tkn task list
tkn taskrun delete 删除指定的 TaskRun tkn taskrun delete --all -n my-namespace

案例拆解:使用 tkn 手动触发并监控流水线

假设我们已经创建了上一节中的 build-and-test Pipeline,现在需要手动触发一次执行,并实时查看日志。

# 触发流水线,指定工作区使用 PVC
tkn pipeline start build-and-test \
  --workspace name=shared-data,claimName=my-pvc \
  --showlog

执行后,tkn 会创建一个 PipelineRun,并持续输出日志。如果某个 Task 失败,日志会显示具体的错误信息,包括容器名称和退出码。此时,我们可以通过 kubectl get pods 查看对应的 Pod 状态,进一步排查问题。

经验提醒:在 CI 脚本中,建议使用 tkn pipelinerun logs --follow 命令来跟踪流水线日志,而不是直接使用 kubectl logs。因为 tkn 会自动处理多容器 Pod 的日志聚合,并显示 Task 之间的分隔线,可读性更好。

常见误区与复盘

误区:安装 Tekton 后,直接使用 kubectl apply 创建 Pipeline 就能立即生效。
分析:Tekton 的 Webhook 组件负责对 Pipeline 和 Task 进行参数校验和默认值注入。如果 Webhook 未就绪或配置错误,资源可能创建成功但无法被 Controller 正确处理。
复盘:在创建任何 Tekton 资源前,务必确认 tekton-pipelines 命名空间下的 tekton-pipelines-webhook Pod 处于 Running 状态。可以通过 kubectl get pods -n tekton-pipelines | grep webhook 检查。

4.4 实战:构建一个完整的 CI 流水线

核心原理:结合 Workspace 与参数化

为了将上述概念串联起来,我们构建一个真实的 CI 场景:代码提交后,自动执行测试、构建镜像并推送。我们将使用 Workspace 来共享代码,使用参数来动态指定镜像标签。

操作流程:定义 Task 与 Pipeline

第一步:定义测试 Task

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: run-tests
spec:
  workspaces:
    - name: source
  steps:
    - name: run-tests
      image: maven:3.8-openjdk-11
      script: |
        cd $(workspaces.source.path)
        mvn test

第二步:定义构建镜像 Task

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: build-image
spec:
  params:
    - name: image-url
      type: string
  workspaces:
    - name: source
  steps:
    - name: build-and-push
      image: gcr.io/kaniko-project/executor:latest
      args:
        - "--dockerfile=$(workspaces.source.path)/Dockerfile"
        - "--context=$(workspaces.source.path)"
        - "--destination=$(params.image-url)"

第三步:编排 Pipeline

apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: ci-pipeline
spec:
  params:
    - name: image-tag
      type: string
      default: "latest"
  workspaces:
    - name: shared-workspace
  tasks:
    - name: fetch-source
      taskRef:
        name: git-clone
      workspaces:
        - name: source
          workspace: shared-workspace
    - name: run-tests
      taskRef:
        name: run-tests
      runAfter: [fetch-source]
      workspaces:
        - name: source
          workspace: shared-workspace
    - name: build-image
      taskRef:
        name: build-image
      runAfter: [run-tests]
      params:
        - name: image-url
          value: "registry.example.com/my-app:$(params.image-tag)"
      workspaces:
        - name: source
          workspace: shared-workspace

案例拆解:执行与结果验证

使用 tkn 启动该流水线,并指定镜像标签:

tkn pipeline start ci-pipeline \
  --param image-tag=v1.0.0 \
  --workspace name=shared-workspace,claimName=ci-pvc \
  --showlog

执行过程中,可以观察到三个 Task 依次运行。如果测试失败,build-image 任务不会执行,流水线状态变为 Failed。如果全部成功,最终镜像 registry.example.com/my-app:v1.0.0 会被推送到仓库。

关键参数说明:在上述 Pipeline 中,$(params.image-tag) 是 Tekton 的变量替换语法。Tekton 会在运行时将参数值注入到 Task 的 args 或 env 中。这种参数化机制使得同一个 Pipeline 可以复用,只需在触发时传入不同的参数即可。

常见误区与复盘

误区:在 Task 的 Step 中直接使用 docker build 命令。
分析:在 Kubernetes Pod 中,默认没有 Docker Daemon 可用。直接调用 docker 命令会报错“Cannot connect to the Docker daemon”。
解决方案:推荐使用 Kaniko 或 Buildah 等无守护进程的镜像构建工具。Kaniko 在用户空间运行,不需要特权模式,更适合容器环境。
复盘:在设计镜像构建 Task 时,应优先选择 Kaniko 作为执行器,并确保 Dockerfile 中的基础镜像可以被 Kaniko 访问(可能需要配置镜像仓库凭证)。

4.5 总结与最佳实践

本节从 Tekton 的架构设计出发,详细拆解了 Pipeline、Task、Step、Resource 四个核心组件的职责与关系,并通过实际案例演示了安装、配置和运行流水线的完整流程。Tekton 的强大之处在于其与 Kubernetes 的深度集成,使得 CI/CD 流水线具备了云原生的弹性、可观测性和可移植性。

核心要点回顾:
  • 对象层级:Pipeline → Task → Step,Run 对象是定义对象的实例化。
  • 数据共享:优先使用 Workspace 而非 PipelineResource 进行数据传递。
  • 工具链:tkn CLI 是日常操作和调试的必备工具。
  • 镜像构建:在容器内构建镜像时,使用 Kaniko 或 Buildah 替代 Docker Daemon。