Tekton is a powerful, Kubernetes-native framework for creating continuous integration and delivery (CI/CD) systems. In this article, we'll use real-world examples to show you how to install Tekton, create Tasks, and eventually create our own pipeline.
What's a pipeline?
Great question! In software development, pipelines are automated processes that drive software through a process of building, testing, and deploying code. Such an efficient process can help minimize human error, as well as maintain consistency in deployment. Since Tekton is cloud-native, its pipelines are containerized and don't have dependencies on other projects, mitigating potential issues and saving you time.
About Tekton
Tekton is a Knative-based framework for CI/CD pipelines, but it's unique due to its decoupled nature—meaning that one pipeline can be used to deploy to any Kubernetes cluster across multiple hybrid cloud providers. In addition, Tekton stores everything related to a pipeline as custom resources (CRs) within the cluster, allowing pieces to be used across multiple pipelines.
Installing Tekton
For this guide, we'll assume you're using Minikube for your Kubernetes cluster, although we've created a Tekton lab on OpenShift if you don't have access to Minikube. Once your cluster is running with minikube start
, install the latest version of Tekton by applying the YAML from the latest release:
kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
This command will create a tekton-pipelines
namespace, as well as other resources to finalize your Tekton install. With that namespace in mind, we can easily track the progress of our installation using the command below:
kubectl get pods --namespace tekton-pipelines --watch
Finally, to interact with Tekton through the console, we need to install the Tekton CLI, also known as tkn
. Depending on your operating system, please use the instructions from the official repository to install the latest binary executable.
Optional: Install the tutorial repo
The Red Hat OpenShift developer advocate team has created a repository to help you get started and master Tekton concepts. If you're interested in seeing more concepts and getting hands-on, feel free to clone our repo to your local directory:
git clone https://github.com/joellord/handson-tekton
Once you've cloned the tutorial repository, be sure to cd
into the folder with:
cd handson-tekton
Creating our first Task
Let's start with a simple "Hello World" Task for our introduction to Tasks. Task resources are essential building block components for creating a Pipeline, and this first Task will allow us to use a Red Hat Universal Base Image and echo a "Hello World". To begin, let's open the file 01-hello.yaml
in the /demo
folder:
apiVersion: tekton.dev/v1beta1 kind: Task metadata: name: hello spec: steps: - name: say-hello image: registry.access.redhat.com/ubi8/ubi command: - /bin/bash args: ['-c', 'echo Hello World']
You'll notice several details above, from the kind
being a Task, to the step
of "say-hello", and the args
being to simply output an echo
command to the console. Let's apply this Task to our cluster, similar to any other Kubernetes object:
kubectl apply -f ./demo/01-hello.yaml
tkn task start --showlog hello
Great work! After running this tkn
command, you'll soon see an output from the Task in the console like such:
TaskRun started: hello-run-6cgf5 Waiting for logs to be available... [say-hello] Hello World
Adding parameters to a task
An essential feature of Tasks is the ability to take in and pass parameters. If you're looking to build out various Pipelines, parameters, or params
, are instrumental. These properties are constructed of a name
and type
, but can also accept a description
and default
value. To take a better look at how parameters work, let's open up the file 02-param.yaml
in the /demo
folder:
apiVersion: tekton.dev/v1beta1 kind: Task metadata: name: hello spec: params: - name: person description: Name of person to greet default: World type: string steps: - name: say-hello image: registry.access.redhat.com/ubi8/ubi command: - /bin/bash args: ['-c', 'echo Hello $(params.person)']
Building from our "Hello World" example, we've added in a person
parameter with generic values. In addition, to access the new param, we can call it using $(params.person)
. In order to run this new Task, we can add it to our cluster and run the Task with the following command:
kubectl apply -f ./demo/02-param.yaml
tkn task start --showlog hello
Looks good! Now, it looks as if the console is asking for us to specify the parameter in the command line, similar to below:
? Value for param `person` of type `string`? (Default is `World`) Cedric TaskRun started: hello-run-z4gsw Waiting for logs to be available... [say-hello] Hello Cedric
Creating a Pipeline
Now that you understand Tasks and parameters, let's dive into creating a Pipeline. For consistency, Tasks are meant for single actions, while a Pipeline is a series of Tasks that can be run either in parallel or sequentially. For this example, we'll use the 04-tasks.yaml
file in the /demo
folder for our Pipeline:
apiVersion: tekton.dev/v1beta1 kind: Task metadata: name: say-something spec: params: - name: say-what description: What should I say default: hello type: string - name: pause-duration description: How long to wait before saying something default: 0 type: string steps: - name: say-it image: registry.access.redhat.com/ubi8/ubi command: - /bin/bash args: ['-c', 'sleep $(params.pause-duration) && echo $(params.say-what)']
With this generic Task file, which will echo
whatever it receives in its parameters, we can build our first Pipeline. With the 05-pipeline.yaml
file in the /demo
folder, we can manipulate the 04-tasks.yaml
Task twice, with different outputs:
apiVersion: tekton.dev/v1beta1 kind: Pipeline metadata: name: say-things spec: tasks: - name: first-task params: - name: pause-duration value: "2" - name: say-what value: "Hello, this is the first task" taskRef: name: say-something - name: second-task params: - name: say-what value: "And this is the second task" taskRef: name: say-something
We're now ready to apply the generic Task and the new Pipeline to our cluster, and officially start the Pipeline. Using tkn pipeline start
, we create a PipelineRun
resource automatically with a random name that will trigger our pipeline.
kubectl apply -f ./demo/04-tasks.yaml
kubectl apply -f ./demo/05-pipeline.yaml
tkn pipeline start say-things --showlog
Congrats! You'll notice the console has to output the logs from the PipelineRun.
However, the order seems to be confused.
PipelineRun started: say-things-run-ncfsq Waiting for logs to be available... [second-task : say-it] And this is the second task [first-task : say-it] Hello, this is the first task
You'll notice that the first task seems to happen after the second task, and this is due to Tekton naturally running all the tasks simultaneously.
Run in parallel or sequentially
For Tasks to run in a specific order, the runAfter
parameter is needed in the task definition of your Pipeline. Let's open up the 06-pipeline-order.yaml
file in the /demo
folder:
apiVersion: tekton.dev/v1beta1 kind: Pipeline metadata: name: say-things-in-order spec: tasks: - name: first-task params: - name: pause-duration value: "2" - name: say-what value: "Hello, this is the first task" taskRef: name: say-something - name: second-task params: - name: say-what value: "Happening after task 1, in parallel with task 3" - name: pause-duration value: "2" taskRef: name: say-something runAfter: - first-task - name: third-task params: - name: say-what value: "Happening after task 1, in parallel with task 2" - name: pause-duration value: "1" taskRef: name: say-something runAfter: - first-task - name: fourth-task params: - name: say-what value: "Happening after task 2 and 3" taskRef: name: say-something runAfter: - second-task - third-task
The runAfter
parameter is being applied to specific numbered tasks, and after applying this Pipeline to our cluster, we'll be able to see logs from each task, but ordered:
kubectl apply -f ./demo/06-pipeline-order.yaml
tkn pipeline start say-things-in-order --showlog
After running tkn
, your CLI output should be similar to this example:
PipelineRun started: say-things-in-order-run-5dklz Waiting for logs to be available... [first-task : say-it] Hello, this is the first task [second-task : say-it] Happening after task 1, in parallel with task 3 [third-task : say-it] Happening after task 1, in parallel with task 2 [fourth-task : say-it] Happening after task 2 and 3
Conclusion
Feel free to continue the demo here, and try out our guided OpenShift and Kubernetes learning here as well, which offers an interactive environment right in your browser.
Check out our video for more interactive demonstrations of many examples you've seen here!
Resources
If you want to keep learning about Tekton, start with these articles on Red Hat Developer:
- Introduction to cloud-native CI/CD with Tekton (Jan Kleinert & Joel Lord)
- The new Tekton Pipelines extension for Visual Studio Code (Denis Golovin & Lindsey Tulloch)
- Creating Pipelines with OpenShift 4.4’s new Pipeline Builder and Tekton Pipelines (Joel Lord)