Tekton Cloud-native CI/CD – a pragmatic intro

No Comments

In this article I want to give an overview of Tekton with the goal of explaining the basics and getting you started quickly.

According to its own homepage, Tekton wants to become the standard for CI/CD. On the one hand, it offers a framework for building cloud-native CI/CD systems in Kubernetes and, on top of that, standardized tooling for these systems. Thus, it has already found its way into Jenkins X and is the basis for RedHat OpenShift Pipelines.

Developers who want to use a CI system benefit from the broad support, as existing pipelines and pipeline steps can be exchanged between Tekton CI implementations without effort.

The Tekton project uses Kubernetes as a platform and, at its core, represents the building blocks of a CI pipeline in the form of CRDs. A Custom Resource Definition (CRD) is a self-created Kubernetes object that can be used to make your own objects visible and usable within the Kubernetes API.

In Tekton, for example, objects such as a pipeline can be found that represent the same and can be configured by tasks that execute the individual process steps.

The entire configuration then takes place via manifests, as is usual with Kubernetes. The existing Kubernetes know-how comes into its own here, because in addition to configuration, introspection of the processes can also take place via this path.

The Tekton Hub is offered as a central point of contact for tasks and pipelines maintained by the community. Many building blocks can already be found there to cover the most common steps. In addition to the public hub, it is very easy to implement specific solutions once within your own organization and distribute them reliably.

In addition to the manifests, Tekton of course also provides the Kubernetes operators in the Tekton Pipelines Repository. They execute the configured steps. As is common with modern CI systems, the build steps are executed within containers.

Tekton installation

Installation is done either by applying the Kubernetes manifests from the release page or by using the Tekton Operator.

The Tekton operator is currently still in an early development phase and currently offers installation only. Instructions on how to configure the installation can be found on the help pages.

Installation via the Kubernetes manifests is very well described in the Getting Started Guide.

To quickly have a usable installation available, I recommend installing the pipeline component and the dashboard component to get a visual view of the running Tekton installation. The dashboard can be accessed from the outside via a browser.

Ready-to-run project

In the GitHub project Tekton-Demo you can find a complete installation which runs with K3d directly on the local system. The installation can be found in the README and is always up to date in the GitHub Action.

After the installation has run successfully, the cluster is a running Tekton installation with tasks and pipelines installed in the namespace tekton-pipelines.

Since it is very easy to look in the wrong namespace I would like to recommend kubectx and kubens only briefly, because kubens tekton-pipelines sets the default namespace correctly.

The dashboard is accessible via a port forward and an event listener is usable via an ingress and can also already react to events, but we will get to that in another blog article.

An example CI pipeline

After the installation, we can already get to know the main components and use them to build a "Hello, World!" – example.

A task consists of a series of steps which are executed in order. A step is a self-contained command, which in the following example is named hello, the call to echo "Hello World!". This is started and executed in a bash container, which of course can be changed to your liking.

In real use you can find commands at this point, which do a checkout, build images and much more.

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: hello
spec:
  steps:
    - name: hello
      image: bash:latest
      command:
        - echo
      args:
        - "Hello, world!"

Also a goodbye task is created, which says goodbye with a echo command on the system console.

In this small example we will create a pipeline that calls the two tasks one after the other, so that when you look at the pipeline logs you will see both the hello and the goodbye.

Very intuitively – in my opinion anyway – we create a CRD of type Pipeline and define a list of tasks there, which can be provided with dependencies among each other. In this simple example we specify via runAfter that the farewell should take place after the greeting. apiVersion: tekton.dev/v1beta1

kind: Pipeline
metadata:
  name: hello-goodbye-pipeline
spec:
  tasks:
    - name: hello
      taskRef:
        name: hello
    - name: goodbye
      runAfter:
        - hello
      taskRef:
        name: goodbye

The task defined above is linked via a taskRef so that the defined tasks are linked via it and the pipeline runs through the two steps.

Interaction with Tekton

As shown at the beginning, Tekton works by configuring and installing CRDs. These API objects can be retrieved and manipulated directly via kubectl, through which a traceable API is mapped. Installed pipelines can be retrieved easily:

# kubectl get pipelines.tekton.dev --all-namespaces -o wide
NAMESPACE          NAME                     AGE
8
tekton-pipelines   hello-goodbye-pipeline   1s
9

Furthermore it is of course possible to start a pipeline. In the repository you can find a PipelineRun which I show in the following:

apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
  generateName:  hello-goodbye-pipeline-
spec:
  pipelineRef:
    name:  hello-goodbye-pipeline

The configuration provides a prefix for the generated runs via the generateName attribute. It also provides a reference to the pipeline to be used, which we created during the installation and looked at in the course of this article.

How to start a pipeline? Now we need another API object, the PipelineRun. This object brings the necessary parameters – in our case none yet – in connection with the pipeline to be executed. As a user, we can get the status and also the log output by reference to the generated run.

Here we go:

kubectl create -n tekton-pipelines -f ./hello-goodbye-pipeline-run.yaml

And as already indicated, we retrieve all the runs:

kubectl get pipelineruns.tekton.dev --all-namespaces -o wide
NAMESPACE          NAME                             SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
8
tekton-pipelines   hello-goodbye-pipeline-v5h5l   True        Succeeded   13s         1s

Here you can see the existing status fields of this object. For black-box testing, we can therefore wait for the PipelineRun status to change to Succeeded to detect the passing of a pipeline.

In addition to the direct interaction with kubectl, Tekton offers a specialized command line interface (CLI) that interacts directly with the cluster via the currently used Kubernetes context. Many Kubernetes-based tools come with a suitable CLI to work efficiently with the platform. tkn is the corresponding Go binary which can be run on different platforms without any problems. Installation instructions can be found in the GitHub repository.

With this CLI, it is then easier to retrieve e.g. the tasks and pipelines. Here is a short example:

tkn task list --all-namespaces
tkn pipeline list --all-namespaces

These two calls show all existing tasks and pipelines in all namespaces.

The inspection of the logs is done by this command:

tkn pr logs $PIPELINE_RUN_NAME

The output of all tasks is collected and traceable here and looks like this:

[hello : hello] Hello World!

[goodbye : goodbye] Goodbye World!

Conclusion

We have now done the installation with little effort and also already created the first pipeline. By doing so, we have already achieved a lot and could now take the first look behind the scenes.

In the following articles we will create a buildpack pipeline and extend the build pipeline with a WebHook trigger from outside. This will allow Tekton to automatically build a container image when a push is made to a Git repository.

Marco is passionate about developing software. He enjoys working in teams to solve complex problems.
In the past, he has successfully modernized legacy applications to prepare them for new challenges. Taking everyone along on this journey and getting them excited about new technologies – that’s a natural part of his job.

Post by Marco Paga

Continuous Integration

GitHub Actions test a full Tekton CI installation

Continuous Integration

Tekton Triggers in practice

More content about Continuous Integration

Continuous Integration

GitLab security scanning – part 2

Continuous Integration

GitLab security scanning

Comment

Your email address will not be published.