Tekton is a Kubernetes-native open-source framework for building continuous integration and delivery (CI/CD) pipelines. Unlike Jenkins or GitLab CI, Tekton runs entirely as Kubernetes Custom Resource Definitions (CRDs), meaning every pipeline, task, and run is a Kubernetes object you manage with kubectl — no separate CI server to maintain. This cloud-native approach gives you full portability across any Kubernetes cluster: on-premises, managed, or bare-metal. This guide covers installing Tekton Pipelines on a Kubernetes cluster running on Red Hat Enterprise Linux 9, writing reusable Tasks, assembling them into a Pipeline that clones a Git repository, builds a Docker image, and deploys to the cluster, and monitoring runs through the Tekton Dashboard.
Prerequisites
- RHEL 9 server with a running Kubernetes cluster (k3s, kubeadm, or OpenShift) and
kubectlconfigured kubectlversion 1.24 or later with cluster-admin privileges- A container registry (Docker Hub, Quay.io, or private) with push credentials
- A Git repository containing a
Dockerfileat the repository root - At least 2 CPU cores and 4 GB RAM available in the cluster for pipeline pods
Step 1 — Install Tekton Pipelines
Tekton Pipelines is installed by applying a single manifest that creates all required CRDs, RBAC objects, and the pipeline controller and webhook deployments in the tekton-pipelines namespace.
kubectl apply --filename
https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
# Wait for the controller and webhook to become ready
kubectl wait --for=condition=ready pod
--selector=app=tekton-pipelines-controller
--namespace=tekton-pipelines
--timeout=120s
kubectl get pods --namespace tekton-pipelines
Step 2 — Understand Core Tekton Concepts
Before writing YAML, understand the four key abstractions. A Task is a reusable unit of work composed of ordered Steps, each running in its own container. A TaskRun instantiates a Task with concrete parameter values and executes it. A Pipeline chains multiple Tasks together, optionally passing outputs as inputs between them. A PipelineRun instantiates a Pipeline and triggers the full execution. Create a Kubernetes Secret to hold your container registry credentials:
kubectl create secret docker-registry registry-credentials
--docker-server=https://index.docker.io/v1/
--docker-username=YOUR_USERNAME
--docker-password=YOUR_PASSWORD
--docker-email=YOUR_EMAIL
kubectl create serviceaccount pipeline-sa
kubectl patch serviceaccount pipeline-sa
-p '{"secrets":[{"name":"registry-credentials"}]}'
Step 3 — Write a Task to Build a Docker Image
The following Task uses kaniko — a daemonless Docker image builder — to build and push an image from a cloned workspace. Save it as task-build-image.yaml and apply it to the cluster.
# task-build-image.yaml
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: build-and-push
spec:
params:
- name: image
description: Full image name including tag
- name: context
default: "."
workspaces:
- name: source
steps:
- name: build-push
image: gcr.io/kaniko-project/executor:latest
args:
- --context=$(workspaces.source.path)/$(params.context)
- --destination=$(params.image)
- --dockerfile=$(workspaces.source.path)/Dockerfile
volumeMounts:
- name: docker-config
mountPath: /kaniko/.docker
volumes:
- name: docker-config
secret:
secretName: registry-credentials
items:
- key: .dockerconfigjson
path: config.json
kubectl apply -f task-build-image.yaml
Step 4 — Assemble a Multi-Stage Pipeline
This Pipeline chains three tasks: the Tekton Catalog’s git-clone task, the custom build-and-push task, and a simple kubectl deploy step. Tasks share data through a PersistentVolumeClaim-backed workspace.
# Install the git-clone task from Tekton Hub
kubectl apply -f
https://api.hub.tekton.dev/v1/resource/tekton/task/git-clone/0.9/raw
# pipeline.yaml
cat <<EOF | kubectl apply -f -
apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
name: build-deploy-pipeline
spec:
params:
- name: repo-url
- name: image-name
workspaces:
- name: shared-workspace
tasks:
- name: clone
taskRef:
name: git-clone
workspaces:
- name: output
workspace: shared-workspace
params:
- name: url
value: $(params.repo-url)
- name: build
runAfter: [clone]
taskRef:
name: build-and-push
workspaces:
- name: source
workspace: shared-workspace
params:
- name: image
value: $(params.image-name)
- name: deploy
runAfter: [build]
taskSpec:
steps:
- name: kubectl-apply
image: bitnami/kubectl:latest
script: |
kubectl set image deployment/myapp app=$(params.image-name)
--record
params:
- name: image-name
value: $(params.image-name)
EOF
Step 5 — Run the Pipeline and Monitor Progress
Create a PersistentVolumeClaim for the shared workspace, then submit a PipelineRun to trigger execution. Use tkn CLI or kubectl to tail logs.
# Create the workspace PVC
kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pipeline-workspace-pvc
spec:
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 1Gi
EOF
# Submit a PipelineRun
kubectl create -f - <<EOF
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
generateName: build-deploy-run-
spec:
pipelineRef:
name: build-deploy-pipeline
params:
- name: repo-url
value: https://github.com/YOUR_ORG/YOUR_REPO.git
- name: image-name
value: docker.io/YOUR_USERNAME/myapp:latest
workspaces:
- name: shared-workspace
persistentVolumeClaim:
claimName: pipeline-workspace-pvc
EOF
# Follow logs (install tkn CLI from https://github.com/tektoncd/cli)
tkn pipelinerun logs --last -f
Step 6 — Install the Tekton Dashboard
The Tekton Dashboard provides a web UI for browsing PipelineRuns, TaskRuns, and logs without requiring CLI access.
kubectl apply --filename
https://storage.googleapis.com/tekton-releases/dashboard/latest/release.yaml
# Port-forward to access the dashboard locally
kubectl port-forward --namespace tekton-pipelines
service/tekton-dashboard 9097:9097 &
# Open http://localhost:9097 in your browser
Conclusion
You now have a fully functional Tekton CI/CD pipeline running natively on Kubernetes that clones source code, builds a container image with kaniko, and deploys it to the cluster — all without a dedicated CI server. The key strength of Tekton is composability: Tasks are independently versioned and reusable across Pipelines, and the Tekton Hub at hub.tekton.dev provides hundreds of community-maintained Tasks for common operations. For production, store PipelineRun triggers in a TriggerTemplate and EventListener to automatically launch pipelines on Git push events, and configure a ClusterTask to make your Tasks available cluster-wide across all namespaces.
Next steps: How to Set Up Argo CD for GitOps on Kubernetes on RHEL 9, How to Install Jenkins on Kubernetes with Helm on RHEL 9, and How to Configure GitHub Actions Self-Hosted Runners on RHEL 9.