How Tekton Orchestrates Cloud‑Native CI/CD Pipelines: A Deep Dive
This article explains Tekton’s core CRDs—Task, TaskRun, Pipeline, PipelineRun, PipelineResource, and Condition—how they are implemented on Kubernetes, how pipelines are built and executed, and how to manage secrets and service accounts for secure CI/CD workflows.
Understanding Tekton’s Core Concepts
Tekton is an open‑source cloud‑native CI/CD project that defines pipelines using Kubernetes Custom Resource Definitions (CRDs). The main CRDs are Task, TaskRun, Pipeline, PipelineRun, PipelineResource, and Condition.
Task : defines a build task composed of ordered steps, each executed in a container.
TaskRun : the actual execution of a Task, creating a Pod with the required parameters.
Pipeline : a collection of Task s; the output of one can feed the input of the next.
PipelineRun : runs a Pipeline by creating the corresponding TaskRun s.
PipelineResource : defines external resources such as Git repositories or Docker images (deprecated in newer versions).
Condition : controls whether a Task runs based on a boolean check (also deprecated).
Tip : Both PipelineResource and Condition are deprecated but still appear in older Tekton versions.
The diagram shows that a pipeline consists of many tasks, each task contains multiple steps, and users can flexibly combine tasks to meet various requirements.
Implementation Details
After installing Tekton, two pods appear:
# kubectl get po -n tekton-pipelines
NAME READY STATUS RESTARTS AGE
tekton-pipelines-controller-xxxx 1/1 Running 0 2d22h
tekton-pipelines-webhook-xxxx 1/1 Running 0 2d22hThe controller pod runs the core logic. When it starts, it creates two controllers: PipelineRunController and TaskRunController. A simplified excerpt from cmd/controller/main.go illustrates this:
...
go func() {
log.Printf("Readiness and health check server listening on port %s", port)
log.Fatal(http.ListenAndServe(":"+port, mux))
}()
ctx = filteredinformerfactory.WithSelectors(ctx, v1beta1.ManagedByLabelKey)
sharedmain.MainWithConfig(ctx, ControllerLogKey, cfg,
taskrun.NewController(opts, clock.RealClock{}),
pipelinerun.NewController(opts, clock.RealClock{}),
)
...The controllers are registered via taskrun.NewController and pipelinerun.NewController, and started with sharedmain.MainWithConfig calling controller.StartAll. PipelineRunController watches PipelineRun objects, builds a directed acyclic graph (DAG) from the pipeline spec, and creates TaskRun s for schedulable tasks. The logic lives in pkg/reconciler/pipelinerun/pipelinerun.go under the reconcile method. TaskRunController watches TaskRun objects, converts each into a Pod (subject to Condition checks), and lets Kubernetes schedule it. Its reconcile method is in pkg/reconciler/taskrun/taskrun.go.
OwnerReference links the objects: a PipelineRun owns TaskRun s, which own Pods; status changes propagate upward.
When a TaskRun pod reaches the Running phase, the first step’s container is started by an entrypoint binary. The binary runs only after Tekton injects annotations (via the Kubernetes Download API) as files into the step container, allowing the entrypoint to wait for previous steps to finish.
Overall Execution Flow
User creates a PipelineRun resource. PipelineRunController builds a DAG from the pipeline spec and creates TaskRun s. TaskRunController turns each TaskRun into a Pod (subject to Condition).
The Pod runs each step defined in the task.
When the Pod completes, its status becomes Completed and updates the PipelineRun status.
PipelineResources (Deprecated)
Although deprecated, PipelineResource is still used in older versions to describe inputs such as Git URLs or Docker images. Example:
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
name: hello-world-resource
spec:
type: git
params:
- name: url
value: https://gitee.com/coolops/springboot-helloworld.gitTasks
A Task is a reusable template that can accept parameters, define resources, steps, workspaces, and results. Example task that builds a Maven project:
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: maven-build
spec:
resources:
inputs:
- name: repo
type: git
steps:
- name: build
image: maven:3.3-jdk-8
command:
- mvn
args:
- clean
- package
workingDir: /workspace/repoTask that builds and pushes a Docker image:
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: build-and-push-image
spec:
params:
- name: pathToDockerfile
type: string
default: /workspace/repo/Dockerfile
description: define Dockerfile path
- name: pathToContext
type: string
default: /workspace/repo
description: Docker build context
- name: imageRepo
type: string
default: registry.cn-hangzhou.aliyuncs.com
description: docker image repo
resources:
inputs:
- name: repo
type: git
outputs:
- name: builtImage
type: image
steps:
- name: build-image
image: docker:stable
script: |
#!/usr/bin/env sh
docker login $(params.imageRepo)
docker build -t $(resources.outputs.builtImage.url) -f $(params.pathToDockerfile) $(params.pathToContext)
docker push $(resources.outputs.builtImage.url)
volumeMounts:
- name: dockersock
mountPath: /var/run/docker.sock
volumes:
- name: dockersock
hostPath:
path: /var/run/docker.sockSteps can also specify a timeout:
steps:
- name: sleep-then-timeout
image: ubuntu
script: |
#!/usr/bin/env bash
echo "I am supposed to sleep for 60 seconds!"
sleep 60
timeout: 5sTaskRuns
A TaskRun invokes a Task with concrete parameters and resource bindings:
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
name: build-and-push-image
spec:
params:
- name: imageRepo
value: registry.cn-zhangjiakou.aliyuncs.com
taskRef:
name: build-and-push-image
resources:
inputs:
- name: repo
resourceRef:
name: hello-world-resource
outputs:
- name: builtImage
resourceRef:
name: hello-world-imagePipelines
A Pipeline orchestrates multiple tasks. Example:
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: build-and-push-image
spec:
resources:
- name: repo
type: git
- name: builtImage
type: image
tasks:
- name: build-and-push-image
taskRef:
name: build-and-push-image
resources:
inputs:
- name: repo
resource: repo
outputs:
- name: builtImage
resource: builtImageTasks can be ordered with runAfter or linked via from. Conditional execution uses when (or the deprecated condition).
- name: test-app
taskRef:
name: make-test
resources:
inputs:
- name: workspace
resource: my-repo
- name: build-app
taskRef:
name: kaniko-build
runAfter:
- test-app
resources:
inputs:
- name: workspace
resource: my-repoPipelineRuns
A PipelineRun triggers a pipeline execution and binds resources. Example using resourceSpec:
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: build-and-push-image
spec:
pipelineRef:
name: build-and-push-image
resources:
- name: repo
resourceSpec:
type: git
params:
- name: url
value: https://gitee.com/coolops/springboot-helloworld.git
- name: builtImage
resourceSpec:
type: image
params:
- name: url
value: registry.cn-hangzhou.aliyuncs.com/coolops/helloworld:latestAuthentication Management
Tekton uses Kubernetes Secret s referenced by a ServiceAccount to provide credentials for Git and Docker registries. Each secret must carry a specific annotation, e.g., tekton.dev/git-0: https://github.com or tekton.dev/docker-0: https://gcr.io. Supported secret types include kubernetes.io/basic-auth, kubernetes.io/ssh-auth, and kubernetes.io/dockerconfigjson.
Example secret for Docker registry:
apiVersion: v1
kind: Secret
metadata:
name: docker-registry-secret
annotations:
tekton.dev/docker-0: https://gcr.io
type: kubernetes.io/basic-auth
stringData:
username: <cleartext username>
password: <cleartext password>Corresponding ServiceAccount:
apiVersion: v1
kind: ServiceAccount
metadata:
name: docker-registry-sa
secrets:
- name: docker-registry-secretReference the ServiceAccount in a PipelineRun:
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: demo-pipeline
namespace: default
spec:
serviceAccountName: docker-registry-sa
pipelineRef:
name: demo-pipelineWhen multiple accounts are needed, use serviceAccountNames to assign a specific ServiceAccount to each task:
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: demo-pipeline
namespace: default
spec:
serviceAccountNames:
- taskName: build-app
serviceAccountName: gitlab-sa
- taskName: push-image
serviceAccountName: docker-registry-sa
pipelineRef:
name: demo-pipelineReferences
1. https://www.infoq.cn/article/aRAYxTo19Bd6AVBmXFQz 2. https://cloudnative.to/blog/how-tekton-works/ 3. https://tekton.dev/
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Ops Development Stories
Maintained by a like‑minded team, covering both operations and development. Topics span Linux ops, DevOps toolchain, Kubernetes containerization, monitoring, log collection, network security, and Python or Go development. Team members: Qiao Ke, wanger, Dong Ge, Su Xin, Hua Zai, Zheng Ge, Teacher Xia.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
