Knative Tutorial

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

Prerequisite

The following checks ensure that each chapter exercises are done with the right environment settings.

  • Kubernetes

  • OpenShift

  • Set your local docker to use minikube docker daemon

eval $(minikube docker-env)

  • Kubernetes should be v1.12+

kubectl version

  • OpenShift CLI should be v4.1+

oc version

The output should be like

oc version
Client Version: version.Info{Major:"4", Minor:"1+", GitVersion:"v4.1.0+b4261e0", GitCommit:"b4261e07ed", GitTreeState:"clean", BuildDate:"2019-07-06T03:16:01Z", GoVersion:"go1.12.6", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"14+", GitVersion:"v1.14.6+73b5d76", GitCommit:"73b5d76", GitTreeState:"clean", BuildDate:"2019-09-23T16:18:51Z", GoVersion:"go1.12.8", Compiler:"gc", Platform:"linux/amd64"}
  • Make sure to be on knativetutorial OpenShift project

oc project -q

If you are not on knativetutorial project, then run following command to change to knativetutorial project:

oc project knativetutorial

Ensure Tekton piplines is deployed and the API is available for use

  • Kubernetes

  • OpenShift

kubectl api-resources --api-group='tekton.dev'

oc api-resources --api-group='tekton.dev'

The command show an output like:

NAME                SHORTNAMES   APIGROUP     NAMESPACED   KIND
clustertasks                     tekton.dev   false        ClusterTask
conditions                       tekton.dev   true         Condition
pipelineresources                tekton.dev   true         PipelineResource
pipelineruns        pr,prs       tekton.dev   true         PipelineRun
pipelines                        tekton.dev   true         Pipeline
taskruns            tr,trs       tekton.dev   true         TaskRun
tasks                            tekton.dev   true         Task

Verify the Tekton cli

tkn version

The command should show a result like:

Client version: 0.4.0

Ensure the pipeline Resources and Tasks are available:

tkn res ls

The command above should show an output like:

NAME                             TYPE    DETAILS
git-source                       git     url: https://github.com/redhat-developer-demos/knative-tutorial
knative-tutorial-greeter-image   image   url: localhost:5000/rhdevelopers/knative-tutorial-greeter:v0.1.1
tkn task ls

NAME        AGE
build-app   5 hours 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:

For the exercise of this chapter we need kn client task that will be used to deploy the built container image as serverless service.

The kn Task can be installed from Tekton Pipelines Catalog repository:

  • Kubernetes

  • OpenShift

Check the created tasks using the command:

tkn task ls

The Task list should now list the following two Tasks:

NAME        AGE
build-app   5 hours ago
kn          3 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 kn task that we deployed in previous step to make Pipeline that will build the application from sources and deploy the built linux container image as Knative serverless service.

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

cd $TUTORIAL_HOME/06-pipelines

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

apiVersion: tekton.dev/v1alpha1
kind: Pipeline
metadata:
  name: kn-svc-deploy
spec:
  params:
  - name: mavenMirrorUrl
    description: the maven mirror
    default: http://repo1.maven.apache.org/maven2
  resources:
  - name: appSource
    type: git
  - name: appImage
    type: image
  tasks:
   - name: build-java-app
     taskRef:
       name: build-app
     params:
      - name: contextDir
        value: apps/greeter/java/quarkus
      - name: mavenMirrorUrl
        value: "$(params.mavenMirrorUrl)"
     resources:
      inputs:
        - name: source
          resource: appSource
      outputs:
        - name: builtImage
          resource: appImage
   - name: deploy-kn-service
     taskRef:
       name: kn
     runAfter:
      - build-java-app
     resources:
      inputs:
        - name: image
          resource: appImage
     params:
      - name: ARGS
        value:
        - "service"
        - "create"
        - "greeter"
        - "--force"
        - "--image=$(inputs.resources.image.url)"

Each Pipeline has the following:

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

    • resources - the pipeline resources that will be used in the Pipeline e.g. appImage, appSource

      • name - the name of the input resource using which it can be referenced and bound via Run Pipeline

      • type - the type of the input resource, typically the pipeline resource type

tasks has 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-kn-service that will be run to build the application from sources and deploy the built linux container image as knative 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-kn-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

  • resources - used to bind the Pipeline inputs and output resource to Task’s input and output resource.

  • name - the local name of the resource

  • resource - the Pipeline resource (defined under resources) name

In this demo the build-app Task needs bind two resources namely source and builtImage. The Pipeline kn-svc-deploy 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 Knative service deployment Pipeline could be created using the command:

  • Kubernetes

  • OpenShift

kubectl create -n knativetutorial -f kn-svc-deploy.yaml

oc create -n knativetutorial -f kn-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
kn-svc-deploy   4 seconds ago   ---        ---       ---        ---

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

Run Pipeline

Unlike TaskRun we will not be using YAML to trigger PipelineRun, instead we will use the Tekton cli to trigger the pipeline:

tkn pipeline start kn-svc-deploy \
 --resource="appSource=git-source" \(1)
 --resource="appImage=knative-tutorial-greeter-image" \(2)
 --serviceaccount='pipeline' (3)

1 The resources of the Pipeline could be bound via --resource option, here we bind the Pipeline appSource to pipeline resource git-source
2 Bind the Pipeline appImage to pipeline resource knative-tutorial-greeter-image
3 The service account to use with Pipeline run

If you have maven mirror available then you can modify the above command to use maven mirror:

tkn pipeline start kn-svc-deploy \
 --param="mavenMirrorUrl=http://nexus:8081/nexus/content/groups/public" \
 --resource="appSource=git-source" \(1)
 --resource="appImage=knative-tutorial-greeter-image" \(2)
 --serviceaccount='pipeline' (3)

We will use the Tekton cli to inspect the created resources:

tkn pipelinerun ls

The above command should list one PipelineRun as shown below:

NAME                      STARTED          DURATION    STATUS
kn-svc-deploy-run-4896t   4 seconds ago    ---         Running
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

To check the status of the PipelineRun use the logs command of pipelinerun like:

#list running using the command tkn pr ls
tkn pr ls
# use one task run for which you need the log from list above
tkn pr logs -f -a <pipeline-run-name> (1)

1 The -f or -a allows to tail the logs from all the containers of the pipeline tasks. For more options run tkn pr --help

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>

Invoke Service

  • Kubernetes

  • OpenShift

IP_ADDRESS="$(minikube ip):$(kubectl get svc istio-ingressgateway --namespace istio-system --output 'jsonpath={.spec.ports[?(@.port==80)].nodePort}')"

http $IP_ADDRESS 'Host:greeter.knativetutorial.example.com'

export SVC_URL=`oc get rt greeter -o yaml | yq read - 'status.url'` && \
http $SVC_URL

The http command should return a response containing a line similar to Hi greeter ⇒ '6fee83923a9f' : 1

Sometimes the response might not be returned immediately especially when the pod is coming up from dormant state. In that case, repeat service invocation.

Cleanup

Delete the pipeline service account and its related permissions:

  • Kubernetes

  • OpenShift

tkn res ls | awk 'NR!=1{print $1}' | xargs kubectl delete pipelineresources &&\
tkn task ls | awk 'NR!=1{print $1}' | xargs kubectl delete tasks &&\
tkn tr ls | awk 'NR!=1{print $1}' | xargs kubectl delete taskruns  &&\
tkn pipeline ls | awk 'NR!=1{print $1}' | xargs kubectl delete pipeline &&\
tkn pr ls | awk 'NR!=1{print $1}' | xargs kubectl delete pipelineruns &&\
kubectl delete -n knativetutorial -f pipeline-sa-role.yaml &&\
kubectl delete -n knativetutorial ksvc greeter

tkn res ls | awk 'NR!=1{print $1}' | xargs oc delete pipelineresources &&\
tkn task ls | awk 'NR!=1{print $1}' | xargs oc delete tasks &&\
tkn tr ls | awk 'NR!=1{print $1}' | xargs oc delete taskruns  &&\
tkn pipeline ls | awk 'NR!=1{print $1}' | xargs oc pipeline &&\
tkn pr ls | awk 'NR!=1{print $1}' | xargs oc delete pipelineruns &&\
oc delete -n knativetutorial -f pipeline-sa-role.yaml &&\
oc delete -n knativetutorial ksvc greeter