Tekton 流水线

Tekton 是一款云原生的 CI/CD 框架,原名 Knative Build,现为 CDF(持续交付基金会)顶级项目。Tekton 以 Kubernetes Custom Resources(CRD)形式存在,充分利用 Kubernetes 的声明式和扩展能力。

核心概念

资源 说明
Task 单个构建/操作步骤,可组合成 Pipeline
TaskRun Task 的运行时实例
Pipeline 多个 Task 的编排,支持 DAG 和并行
PipelineRun Pipeline 的运行时实例
PipelineResource 输入输出资源(Git、Image、Cluster 等)
Workspace 共享存储,Task 之间传递数据
Step Task 中的具体命令
Sidecar Task 中的辅助容器

安装 Tekton

使用 kubectl 安装


# 安装 Tekton Pipelines
kubectl apply -f https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml

# 验证安装
kubectl get pods -n tekton-pipelines

使用 Helm 安装


helm repo add Tekton https://春风化雨.github.io/tekton-helm-chart
helm repo update

helm install tekton tekton/pipelines \
  --namespace tekton-pipelines \
  --create-namespace \
  --set pipeline.rerun_approval_mode=enabled

Task 定义

基础 Task


apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: hello-world
spec:
  steps:
    - name: greet
      image: ubuntu:22.04
      command:
        - echo
      args:
        - "Hello, World!"

带参数的 Task


apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: build-app
spec:
  params:
    - name: image
      type: string
      description: "Docker image to build"
    - name: context
      type: string
      default: .
  steps:
    - name: build
      image: docker:24
      env:
        - name: DOCKER_TLS_CERTDIR
          value: ""
      command:
        - /bin/sh
      args:
        - -c
        - |
          docker build -t $(params.image) $(params.context)
    - name: push
      image: docker:24
      env:
        - name: DOCKER_TLS_CERTDIR
          value: ""
      command:
        - /bin/sh
      args:
        - -c
        - |
          docker push $(params.image)

使用 Workspace


apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: compile
spec:
  params:
    - name: maven-home
      type: string
      default: /usr/share/maven
  workspaces:
    - name: source
      description: Git clone source code
    - name: maven-cache
      description: Maven local repository
  steps:
    - name: mvn-compile
      image: maven:3.9-eclipse-temurin-17
      env:
        - name: MAVEN_OPTS
          value: -Dmaven.repo.local=/workspace/maven-cache
      command:
        - /usr/bin/mvn
      args:
        - -f
        - /workspace/source/pom.xml
        - clean
        - compile
      workingDir: /workspace/source
      volumeMounts:
        - name: maven-cache
          mountPath: /workspace/maven-cache
  volumes:
    - name: maven-cache
      emptyDir: {}

Pipeline 定义

带 DAG 的 Pipeline


apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: app-pipeline
spec:
  params:
    - name: image
      type: string
    - name: branch
      type: string
      default: main
  workspaces:
    - name: shared-data
  tasks:
    - name: fetch-repository
      taskRef:
        name: git-clone
      params:
        - name: url
          value: https://github.com/example/app.git
        - name: revision
          value: $(params.branch)
        - name: deleteExisting
          value: "true"
      workspaces:
        - name: output
          workspace: shared-data

    - name: build
      taskRef:
        name: build-image
      params:
        - name: image
          value: $(params.image)
      runAfter:
        - fetch-repository
      workspaces:
        - name: source
          workspace: shared-data

    - name: test
      taskRef:
        name: run-tests
      runAfter:
        - build
      workspaces:
        - name: source
          workspace: shared-data

    - name: deploy
      taskRef:
        name: deploy-k8s
      params:
        - name: image
          value: $(params.image)
      runAfter:
        - test

TaskRun 和 PipelineRun

手动执行 TaskRun


apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
  name: hello-world-run
spec:
  taskRef:
    name: hello-world

执行 PipelineRun


apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
  name: app-pipeline-run
spec:
  pipelineRef:
    name: app-pipeline
  params:
    - name: image
      value: registry.example.com/myapp:v1.0.0
    - name: branch
      value: main
  workspaces:
    - name: shared-data
      persistentVolumeClaim:
        claimName: shared-pvc
        readOnly: false
  serviceAccountName: tekton-robot

带有 subpath 的 PipelineRun


apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
  name: app-pipeline-run
spec:
  pipelineRef:
    name: app-pipeline
  params:
    - name: image
      value: registry.example.com/myapp:v1.0.0
  workspaces:
    - name: shared-data
      volumeClaimTemplate:
        spec:
          accessModes:
            - ReadWriteOnce
          resources:
            requests:
              storage: 1Gi

Git Clone Task( Tekton Catalog)


apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: git-clone
spec:
  params:
    - name: url
      type: string
    - name: revision
      type: string
      default: main
    - name: deleteExisting
      type: string
      default: "false"
    - name: depth
      type: string
      default: "1"
  results:
    - name: commit
      description: The commit SHA
    - name: url
      description: The repository URL
  workspaces:
    - name: output
      description: The git repo will be cloned here
  steps:
    - name: clone
      image: alpine/git:v2.36.0
      script: |
        #!/bin/sh
        set -e

        cp -r $(workspaces.output.path) /workspace/source

        cd /workspace/source

        if [ "$(params.deleteExisting)" = "true" ]; then
          rm -rf .git
        fi

        git clone -o origin -b $(params.revision) --depth $(params.depth) $(params.url) .

        GIT_COMMIT_SHA=$(git rev-parse HEAD)
        echo -n "$GIT_COMMIT_SHA" > $(results.commit.path)
        echo -n "$(params.url)" > $(results.url.path)

Triggers(事件驱动)

TriggerTemplate


apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
  name: app-template
spec:
  resourcetemplates:
    - apiVersion: tekton.dev/v1beta1
      kind: PipelineRun
      metadata:
        generateName: app-pipeline-run-
      spec:
        pipelineRef:
          name: app-pipeline
        params:
          - name: image
            value: registry.example.com/myapp:$(tt.params.tag)
        workspaces:
          - name: shared-data
            persistentVolumeClaim:
              claimName: shared-pvc

TriggerBinding


apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerBinding
metadata:
  name: app-binding
spec:
  params:
    - name: tag
      value: $(body.tag)
    - name: branch
      value: $(body.ref)

EventListener


apiVersion: triggers.tekton.dev/v1beta1
kind: EventListener
metadata:
  name: app-listener
spec:
  serviceAccountName: tekton-triggers
  triggers:
    - name: app-trigger
      interceptors:
        - ref:
            name: github
          params:
            - name: secretRef
              value: webhook-secret
        - ref:
            name: cel
          params:
            - name: filter
              value: body.tag != ""
      bindings:
        - ref: app-binding
      template:
        ref: app-template

Dashboard 安装


kubectl apply -f https://storage.googleapis.com/tekton-releases/dashboard/latest/tekton-dashboard-release.yaml

# 访问 Dashboard
kubectl port-forward -n tekton-pipelines svc/tekton-dashboard 9097:9097

与 ArgoCD 集成

使用 Tekton 作为 CI,ArgoCD 作为 CD:


# Tekton Task: 构建镜像
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: build-push-image
spec:
  params:
    - name: image
      type: string
  steps:
    - name: build
      image: docker:24
      env:
        - name: DOCKER_TLS_CERTDIR
          value: ""
      script: |
        docker build -t $(params.image) .
    - name: push
      image: docker:24
      env:
        - name: DOCKER_TLS_CERTDIR
          value: ""
      script: |
        docker push $(params.image)

# ArgoCD Application: 监听镜像 Tag 变化
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp
spec:
  source:
    repoURL: https://github.com/example/k8s-manifests.git
    targetRevision: HEAD
  syncPolicy:
    automated:
      selfHeal: true

最佳实践

  • Task 原子化:每个 Task 只做一件事,便于复用
  • 使用 Workspace 共享数据:避免复制 artifact
  • 声明式参数:Pipeline 参数化,提高灵活性
  • Results 记录元数据:记录 commit SHA、镜像 digest 等
  • Triggers 实现 GitOps:事件驱动触发流水线
  • RBAC 隔离:为不同组件配置最小权限 ServiceAccount

下一步