Pipelines

Currently, there is an incompatibility between Tekton pipelines webhook and Minikube. Please expect no logs when running tkn commands .

At the end of this chapter you will be able to :

  • Understand what is a Pipeline ?

  • Add Tasks from Catalog

  • Create a Pipeline

  • Execute a Pipeline to build and deploy a Knative service

If you are not in tutorial chapter folder, then navigate to the folder:

cd $TUTORIAL_HOME/pipelines

Ensure the Tasks are available:

tkn task ls

The command should show a output like:

NAME            DESCRIPTION   AGE
build-app                     20 minutes ago
source-lister                 22 minutes ago

If you don’t see the output as above please ensure you have completed all the exercises of Chapter 2 and Chapter 3 before proceeding further.

Add Tasks from catalog

The Tekton Pipelines catalog allows you to reuse the catalog from community repositories. Here is list of repositories which from where you can add tasks:

Since there is no kubectl task available in Tekton Pipelines Catalog repository, we can use the OpenShift client task to deploy the app:

Check the created tasks using the command:

tkn task ls

The Task list should now list the following two Tasks:

NAME               DESCRIPTION              AGE
build-app                                   21 minutes ago
openshift-client   This task runs comm...   6 seconds ago
source-lister                               23 minutes ago

Create a Pipeline

Using a Pipeline we can run multiple Task together in a user defined sequence or order.

Let us use the build-app task that we created in previous chapter and openshift-client task that we deployed in previous step to make Pipeline that will build the application from sources and deploy the built linux container image.

The following snippet shows what a Tekton Pipeline YAML looks like:

apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: svc-deploy
spec:
  params:
    - name: contextDir
      description: the context directory from where to build the application
    - name: destinationImage
      description: the fully qualified image name
    - name: storageDriver
      description: Use storage driver type vfs if you are running on OpenShift.
      type: string
      default: overlay
  workspaces:
    - name: workspace
  tasks:
    - name: build-java-app
      taskRef:
        name: build-app
      workspaces:
        - name: source
          workspace: workspace
      params:
        - name: contextDir
          value: $(params.contextDir)
        - name: destinationImage
          value: $(params.destinationImage)
        - name: storageDriver
          value: $(params.storageDriver)
    - name: deploy-kubernetes-service
      taskRef:
        name: openshift-client
      runAfter:
        - build-java-app
      params:
        - name: SCRIPT
          value: |
            kubectl create deployment greeter --port=8080 --image=$(params.destinationImage)
            kubectl expose deployment/greeter --port=8080 --target-port=8080 --type=NodePort

Each Pipeline has the following:

  • name - the unique name using which the Pipeline can be referred

  • params - the pipeline params that will be used in the Pipeline e.g. contextDir, destinationImage

  • workspaces - the workspaces shared by the tasks in the Pipeline.

  • tasks - one or more Tasks that needs to be executed as part of the Pipeline

In this example we have two Tasks build-java-app and deploy-kubernetes-service that will be run to build the application from sources and deploy the built linux container image as kubernetes service.

By default all Tasks of the Pipeline runs in parallel, you can control the execution via runAfter attribute. In this example we make the deploy-kubernetes-service to run after the build-java-app.

Each Task in the Pipeline has

  • taskRef - the reference to an existing defined task via name

  • params - the Task parameters to define or override

    • name - the name of the parameter

    • value - the value of the parameter

In this demo the build-app Task needs bind two resources namely source and builtImage. The Pipeline deploy-kubernetes-service defines two resources appSource and appImage that can be configured via Run Pipeline.

The binding between the Pipeline resource and Task resources is done via the task’s resources attribute. In this demo we bind appSourcesource and appImagebuiltImage.

Only pipeline resources of same type can be bound. e.g. resource of type git with git or image with image

Deploy Pipeline

The Kubernetes service deployment Pipeline could be created using the command:

kubectl apply -n tektontutorial -f svc-deploy.yaml

We will use the Tekton cli to inspect the created resources

tkn pipeline ls

The above command should list one Pipeline as shown below:

NAME            AGE             LAST RUN   STARTED   DURATION   STATUS
svc-deploy   4 seconds ago   ---        ---       ---        ---

Use the command help via tkn pipeline --help to see more options

Run Pipeline

A Kubernetes Service Account is required to deploy applications in to a Kubernetes namespace. The following resource defines a service account called pipeline in namespace tektontutorial, which will have needed permissions in the tektontutorial namespace to perform Tekton tasks.

kubectl apply -n tektontutorial -f $TUTORIAL_HOME/kubernetes/pipeline-sa-role.yaml
OpenShift Pipelines creates and uses the pipeline SA by default.

Run the following command to start the pipeline:

  • Minikube

  • OpenShift

tkn pipeline start -n tektontutorial svc-deploy \
  --param contextDir='springboot' \(1)
  --param destinationImage='example.com/rhdevelopers/tekton-tutorial-greeter' \(2)
  --serviceaccount='pipeline' \(3)
  --showlog (4)
tkn pipeline start -n tektontutorial svc-deploy \
  --param contextDir='springboot' \(1)
  --param destinationImage='image-registry.openshift-image-registry.svc:5000/tektontutorial/tekton-tutorial-greeter' \(2)
  --showlog(3)
1 Bind the Pipeline contextDir to context directory from where to build the application.
2 Bind the Pipeline destinationImage to a specified value.
3 The service account to use with Pipeline run. This is needed only for Minikube.
4 Show the logs when running the pipeline.

It will take few seconds for the PipelineRun to show status as Running as it needs to download the container images.

  • Use the command help via tkn pipelinerun --help

  • Use pr as shorcut for pipelinerun commands e.g to list pipelinerun run the command tkn pr ls

If you see the PipelineRun status as Failed or Error use the following command to check the reason for error:

tkn pipelinerun describe <pipelinerun-name>

The successful Pipeline run would have created a Kubernetes deployment and service called greeter:

kubectl get deploy,svc -n tektontutorial -l=app=greeter
NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/greeter   1/1     1            1           9m31s

NAME              TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/greeter   NodePort   10.96.251.232   <none>        8080:31918/TCP   9m31s

Invoke Service

Get the service URL,

  • Minikube

  • OpenShift

SVC_URL=$(minikube -p tektontutorial -n tektontutorial greeter --url)

In OpenShift you can use the routes like:

oc expose svc greeter
SVC_URL=$(oc get route greeter  -o yaml -o jsonpath='{.spec.host}')

Run the service,

http --body $SVC_URL

The http command should return a response containing a line similar to Meeow!! from Tekton πŸ˜ΊπŸš€

Cleanup

Clean the completed/failed Task and Pipeline run pods

$TUTORIAL_HOME/bin/cleanup.sh