DEV Community

Cover image for Tekton CI, part I, a gentle introduction
Leandro Proença
Leandro Proença

Posted on

Tekton CI, part I, a gentle introduction

In another post I talked about CI/CD in a nutshell and its fundamentals, before going further on Tekton. In case you need, I suggest you reading that post before.

Now that we understand CI/CD practices, the importance of Cloud Delivery Foundation (CDF) as community and that Tekton is a graduated CDF project, we can deep dive into Tekton.

Let's see its internals and a brief yet complete tutorial on Tekton, integrating with Github, by building and delivering an application from development to production.


Tekton is an open-source framework for creating CI/CD systems.

Instead of using a proprietary CI/CD tool such as Github Actions, Gitlab, BitBucket or CircleCI, Tekton allows developers to easily create components that will build, test and deploy applications, using their own infrastructure.


Is this post for me ❓

  • You deploy applications using Docker, Kubernetes or similar
  • You use cloud-native design to guide you building standardized yet scalable applications in the cloud
  • Also, you build and deliver applications using proprietary CI/CD tooling in the cloud

Other than that, you want to give a try running CI/CD in your own infrastructure, maybe having some cost reduction, why not?

Then this post is for you.

Why Tekton ❓

Advantages of using Tekton as a CI/CD tool:

  • We can build reusable components and deploy them into our own infrastructure, similar to what Gitlab Runners do
  • Tekton components are simply Kubernetes Operators that extend Kubernetes functionalities, so Tekton is very friendly to those who work on Kubernetes clusters
  • The general idea is not that far from Gitlab CI, Github Actions or similar: we declare our pipeline usually using a YAML file
  • It's open-source
  • It's a graduated CDF project, which means a lot of companies are behind its maintenance, Google, Red Hat, SAP, Oracle, to name a few...

After an introduction, time to explore the building blocks of Tekton.


Installation

In the Kubernetes cluster, we can import all CRD's using kubectl. For now, let's install them using the Tekton pipeline release:

kubectl apply \
  --filename \
  https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
Enter fullscreen mode Exit fullscreen mode

Tekton components

The main components of Tektons are:

  • Steps
  • Tasks
  • Pipelines

There are more components to explore, but as for this article we'll focus on these three ones.


Steps

Steps are literally containers that run from images, and in essence we can give a name and provide an arbitrary script in the step.

Step

Nice, but how do we create a Step in Tekton?

Simply we can't. Steps are pretty much like containers in Kubernetes, and as such we should group them into a higher abstraction similar to Pods, which in Tekton is called Task.


Tasks

Tasks are collections of steps, that you define and arrange in a specific order. A Task executes as a Pod in the Kubernetes cluster.

Task

Let's create our first Task hello-task.yml that should have only one step and prints the message Hello in the STDOUT:

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: hello-task
spec:
  steps:
    - name: hello
      image: ubuntu
      script: >
        echo "Hello"
Enter fullscreen mode Exit fullscreen mode

Apply the yaml as usual in Kubernetes and check that the task was created in the cluster:

$ kubectl get tasks

NAME         AGE
hello-task   19s
Enter fullscreen mode Exit fullscreen mode

However, we have only the task definition. We should be able to run the task, which would run a Task pod.

Tekton provides the TaskRun, which is an abstraction that runs an underlying Task (hello-task-run.yml).

apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
  generateName: hello-task-
spec:
  taskRef:
    name: hello-task
Enter fullscreen mode Exit fullscreen mode

In this example, we refer the underlying Task using the taskRef field.

Now, for TaskRun we have to use the kubectl create instead of apply, because the generateName does not work with the apply command.

kubectl create -f hello-task-run.yml
Enter fullscreen mode Exit fullscreen mode

Checking the taskruns:

$ kubectl get taskruns

NAME                             SUCCEEDED   REASON                    STARTTIME   COMPLETIONTIME
hello-task-xvtgb                 True        Succeeded                 42s         28s
Enter fullscreen mode Exit fullscreen mode

And the pods:

$ kubectl get pods

NAME                                 READY   STATUS      RESTARTS   AGE
hello-task-xvtgb-pod                 1/1     Running     0          13s
Enter fullscreen mode Exit fullscreen mode

Getting the pod logs in order to see if the message Hello is echoed:

$ kubectl logs hello-task-xvtgb-pod

Hello
Enter fullscreen mode Exit fullscreen mode

Tasks are great, but if we want to build more robust CI/CD pipelines, we should group tasks into a higher abstraction, which in Tekton is called Pipelines.


Pipelines

Pipelines are collections of tasks, that you define and arrange in a specific order.

Task

Let's create our first Pipeline. In the following example, we'll have a pipeline containing 2 tasks:

  • 1 taskRef referencing to the Task previously created
  • 1 taskSpec containing the Step for the new Task
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: hello-pipeline
spec:
  tasks:
    - name: hello-task
      taskRef:
        name: hello-task
    - name: bye-task
      taskSpec:
        steps:
          - name: bye
            image: ubuntu
            script: >
              echo "Bye"
Enter fullscreen mode Exit fullscreen mode

After kubectl apply, we should see the pipeline successfully created:

$ kubectl get pipelines

NAME                  AGE
hello-pipeline        5s
Enter fullscreen mode Exit fullscreen mode

As in Tasks, Pipelines are only definitions. We need another abstraction in order to run the pipeline, which is called PipelineRun.

apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
  generateName: hello-pipeline-
spec:
  pipelineRef:
    name: hello-pipeline
Enter fullscreen mode Exit fullscreen mode

Then:

$ kubectl create -f hello-pipeline-run.yml
Enter fullscreen mode Exit fullscreen mode

Check the pipelineruns:

$ kubectl get pipelineruns

NAME                   SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
hello-pipeline-zbbcr   True        Succeeded   10s         1s
Enter fullscreen mode Exit fullscreen mode

And the pods:

$ kubectl get pods

NAME                                  READY   STATUS      RESTARTS   AGE
hello-task-xvtgb-pod                  0/1     Completed   0          25m
hello-pipeline-zbbcr-hello-task-pod   0/1     Completed   0          82s
hello-pipeline-zbbcr-bye-task-pod     0/1     Completed   0          82s
Enter fullscreen mode Exit fullscreen mode

Note that we have 2 pods for the hello-pipeline, because each Task runs as a Pod.

The hello task pod:

$ kubectl logs hello-pipeline-zbbcr-hello-task-pod 

Hello
Enter fullscreen mode Exit fullscreen mode

And the bye task pod:

$ kubectl logs hello-pipeline-zbbcr-bye-task-pod 

Bye
Enter fullscreen mode Exit fullscreen mode

Yay! 🚀


In this post we've seen an introduction to Tekton and an overview on its main components.

In the upcoming posts, we'll see the Tekton UI Dashboard and how to trigger Pipelines listening to external events such as Push/PullRequests in Github.

Stay tuned!

Top comments (0)