How to Set Up a CI/CD Pipeline with Tekton on Kubernetes on RHEL 7
Tekton is a Kubernetes-native CI/CD framework that defines pipelines as Kubernetes Custom Resource Definitions (CRDs). Unlike Jenkins, which runs as a separate server, or GitLab CI, which requires the GitLab platform, Tekton lives entirely inside your cluster and follows standard Kubernetes RBAC, secrets management, and resource scheduling. On RHEL 7, you interact with a Kubernetes cluster (installed via kubeadm, minikube, or a managed provider such as OpenShift) using kubectl and the Tekton CLI (tkn). This tutorial walks through installing Tekton Pipelines into an existing cluster, writing Task and Pipeline resources, running them with TaskRun and PipelineRun, using PipelineResources for Git and container image inputs and outputs, setting up Tekton Triggers for webhook-driven automation, and accessing the Tekton Dashboard for a visual overview of pipeline runs.
Prerequisites
- RHEL 7 node with
kubectlconfigured pointing to a running Kubernetes cluster (1.21+) - Cluster-admin permissions to install CRDs and cluster-scoped resources
- At least 2 GB of free cluster memory for Tekton controllers
- A container registry (Docker Hub, Quay.io, or a private registry) for image output
- Internet access from cluster nodes to pull Tekton images from gcr.io
Step 1: Install Tekton Pipelines on Kubernetes
Tekton Pipelines is installed by applying a single YAML manifest from the official GitHub releases:
# Install Tekton Pipelines CRDs and controllers
kubectl apply --filename
https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
# Watch the Tekton Pipelines pods come up
kubectl get pods --namespace tekton-pipelines --watch
Wait until all pods in the tekton-pipelines namespace are Running:
NAME READY STATUS RESTARTS AGE
tekton-pipelines-controller-7d96c5d4d4-xkzqj 1/1 Running 0 90s
tekton-pipelines-webhook-8569965fbd-2xrwk 1/1 Running 0 90s
Step 2: Install the Tekton CLI (tkn)
The tkn CLI provides a Tekton-aware interface for listing, triggering, and inspecting pipeline runs:
curl -LO https://github.com/tektoncd/cli/releases/download/v0.36.0/tkn_0.36.0_Linux_x86_64.tar.gz
tar xvf tkn_0.36.0_Linux_x86_64.tar.gz tkn
sudo mv tkn /usr/local/bin/
tkn version
# Client version: 0.36.0
# Pipeline version: v0.58.0
Step 3: Write a Task Resource
A Task is the atomic unit of work in Tekton — a sequence of steps, each running a container. Create a task that clones a Git repository and runs unit tests:
cat > task-run-tests.yaml <<'EOF'
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: run-python-tests
namespace: default
spec:
params:
- name: repo-url
type: string
description: Git repository URL
- name: revision
type: string
default: main
workspaces:
- name: source
description: Workspace for the cloned source code
steps:
- name: clone
image: alpine/git:v2.43.0
script: |
git clone $(params.repo-url) /workspace/source
cd /workspace/source
git checkout $(params.revision)
- name: install-deps
image: python:3.11-slim
workingDir: /workspace/source
script: |
pip install --quiet -r requirements.txt
- name: test
image: python:3.11-slim
workingDir: /workspace/source
script: |
python -m pytest tests/ -v --tb=short
EOF
kubectl apply -f task-run-tests.yaml
Verify the task was registered:
tkn task list
# NAME AGE
# run-python-tests 5 seconds ago
Step 4: Run a Task with TaskRun
A TaskRun instantiates a Task with concrete parameter values:
cat > taskrun-test.yaml <<'EOF'
apiVersion: tekton.dev/v1
kind: TaskRun
metadata:
generateName: run-python-tests-
namespace: default
spec:
taskRef:
name: run-python-tests
params:
- name: repo-url
value: https://github.com/your-org/your-repo.git
- name: revision
value: main
workspaces:
- name: source
emptyDir: {}
EOF
kubectl create -f taskrun-test.yaml
Watch the logs in real time:
tkn taskrun logs --last -f
Step 5: Define a Pipeline with Multiple Tasks
A Pipeline orchestrates multiple tasks, passing results between them and optionally running tasks in parallel:
cat > pipeline-ci.yaml <<'EOF'
apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
name: python-ci-pipeline
namespace: default
spec:
params:
- name: repo-url
type: string
- name: image-name
type: string
workspaces:
- name: shared-workspace
tasks:
- name: fetch-source
taskRef:
name: git-clone # from Tekton Catalog
params:
- name: url
value: $(params.repo-url)
- name: revision
value: main
workspaces:
- name: output
workspace: shared-workspace
- name: run-tests
runAfter:
- fetch-source
taskRef:
name: run-python-tests
params:
- name: repo-url
value: $(params.repo-url)
workspaces:
- name: source
workspace: shared-workspace
- name: build-image
runAfter:
- run-tests
taskRef:
name: kaniko # from Tekton Catalog
params:
- name: IMAGE
value: $(params.image-name):$(tasks.fetch-source.results.commit)
- name: DOCKERFILE
value: ./Dockerfile
- name: CONTEXT
value: ./
workspaces:
- name: source
workspace: shared-workspace
EOF
kubectl apply -f pipeline-ci.yaml
Step 6: Run the Pipeline with PipelineRun
cat > pipelinerun-ci.yaml <<'EOF'
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
generateName: python-ci-pipeline-run-
namespace: default
spec:
pipelineRef:
name: python-ci-pipeline
params:
- name: repo-url
value: https://github.com/your-org/your-repo.git
- name: image-name
value: quay.io/your-org/your-app
workspaces:
- name: shared-workspace
volumeClaimTemplate:
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
EOF
kubectl create -f pipelinerun-ci.yaml
# Watch all task logs
tkn pipelinerun logs --last -f
# List pipeline runs
tkn pipelinerun list
Step 7: Set Up Tekton Triggers for Webhook-Driven Pipelines
Tekton Triggers installs additional CRDs — EventListener, TriggerTemplate, and TriggerBinding — that allow HTTP webhooks (e.g., from GitHub) to automatically create PipelineRuns:
kubectl apply --filename
https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml
kubectl apply --filename
https://storage.googleapis.com/tekton-releases/triggers/latest/interceptors.yaml
kubectl get pods --namespace tekton-pipelines | grep trigger
Create a TriggerBinding that extracts parameters from a GitHub push webhook payload:
cat > trigger-binding.yaml <<'EOF'
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerBinding
metadata:
name: github-push-binding
spec:
params:
- name: repo-url
value: $(body.repository.clone_url)
- name: revision
value: $(body.after)
EOF
cat > trigger-template.yaml <<'EOF'
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
name: github-push-template
spec:
params:
- name: repo-url
- name: revision
resourcetemplates:
- apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
generateName: triggered-pipeline-run-
spec:
pipelineRef:
name: python-ci-pipeline
params:
- name: repo-url
value: $(tt.params.repo-url)
- name: image-name
value: quay.io/your-org/your-app
workspaces:
- name: shared-workspace
volumeClaimTemplate:
spec:
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 1Gi
EOF
cat > event-listener.yaml <<'EOF'
apiVersion: triggers.tekton.dev/v1beta1
kind: EventListener
metadata:
name: github-listener
spec:
serviceAccountName: tekton-triggers-sa
triggers:
- bindings:
- ref: github-push-binding
template:
ref: github-push-template
EOF
kubectl apply -f trigger-binding.yaml -f trigger-template.yaml -f event-listener.yaml
Step 8: Install and Access the Tekton Dashboard
kubectl apply --filename
https://storage.googleapis.com/tekton-releases/dashboard/latest/release.yaml
# Port-forward to access locally from RHEL 7
kubectl port-forward --namespace tekton-pipelines
service/tekton-dashboard 9097:9097 &
Open http://localhost:9097 in a browser. The dashboard shows all TaskRuns and PipelineRuns with their status, logs, and YAML definitions. For production, expose the dashboard through an Ingress controller with TLS and authentication.
Tekton brings the same declarative, YAML-driven philosophy that defines Kubernetes to the CI/CD layer, making your pipelines as observable and reproducible as your application deployments. Running entirely in-cluster means your pipeline steps have direct access to cluster secrets, service accounts, and storage without complex credential injection. From here, explore the Tekton Catalog at hub.tekton.dev for hundreds of pre-built tasks covering linting, container scanning, Helm deployment, and notification steps, saving you from writing boilerplate and letting you compose sophisticated pipelines from well-tested building blocks.