Tasks
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 Task ?
-
Understand how to clone your build resources using Task
-
Understand where cloned sources reside i.e. Workspace
-
Create a Task that can build the sources
-
How to run a Task
-
Use the pipeline resource with TaskRun
If you are not in tutorial chapter folder, then navigate to the folder:
cd $TUTORIAL_HOME/tasks
Tekton Task
Each Task must have the following:
-
apiVersion - The API version used by the Tekton resource; for example, tekton.dev/v1beta1.
-
kind - Identifies this resource object as a Task object.
-
metadata - Metadata that uniquely identifies the Task resource object, like name.
-
name - the unique name using which the task can be referred
-
-
spec - The configuration for a Task resource object.
-
steps - One or more sub-tasks that will be executed in the defined order. The step has all the attributes like a Pod spec
There are also a series of optional fields for a better control over the resource:
-
resources - the pipeline resources that will be used in the task e.g. git-source. This field is supported by the alpha version of Tekton API and should be avoided as is using the deprecated PipelineResource type.
-
inputs - the resources ingested by the task
-
outputs - the resources produced by the task
-
-
params - the parameters that will be used in the task steps. Each parameter has
-
name - the name of the parameter
-
description - the description of the parameter
-
default - the default value of parameter
-
-
results - The names under which Tasks write execution results.
-
workspaces - The paths to volumes needed by the Task.
-
volumes - the task can also mount external volumes using the volumes attribute.
The TaskRun could override the parameter values, if no parameter value is passed then the default value will be used. |
The parameters that were part of the $(<variable-name>)
.
Clone Source Code
The following listing shows a simple Task that clones the sources using git command and lists the sources:
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: source-lister
namespace: tektontutorial
spec:
params:
- default: 'https://github.com/redhat-scholars/tekton-tutorial-greeter'
name: url
type: string
- default: master
name: revision
type: string
- default: ''
name: subdirectory
type: string
- default: quarkus
description: The context directory within the repository for sources
name: contextDir
type: string
- default: 'false'
description: >-
defines if http.sslVerify should be set to true or false in the global
git config
name: sslVerify
type: string
results:
- description: The precise commit SHA that was fetched by this Task.
name: commit
- description: The precise URL that was fetched by this Task.
name: url
steps:
- image: 'gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init:v0.15.2'
name: clone
resources: {}
script: |
CHECKOUT_DIR="$(workspaces.source.path)/$(params.subdirectory)"
cleandir() {
# Delete any existing contents of the repo directory if it exists.
#
# We don't just "rm -rf $CHECKOUT_DIR" because $CHECKOUT_DIR might be "/"
# or the root of a mounted volume.
if [[ -d "$CHECKOUT_DIR" ]] ; then
# Delete non-hidden files and directories
rm -rf "$CHECKOUT_DIR"/*
# Delete files and directories starting with . but excluding ..
rm -rf "$CHECKOUT_DIR"/.[!.]*
# Delete files and directories starting with .. plus any other character
rm -rf "$CHECKOUT_DIR"/..?*
fi
}
/ko-app/git-init \
-url "$(params.url)" \
-revision "$(params.revision)" \
-path "$CHECKOUT_DIR" \
-sslVerify="$(params.sslVerify)"
cd "$CHECKOUT_DIR"
RESULT_SHA="$(git rev-parse HEAD)"
printf "%s" "${RESULT_SHA}" > "$(results.commit.path)"
printf "%s" "${PARAM_URL}" > "$(results.url.path)"
- name: ls-build-sources
command: ["ls", "-ltr", "/workspace/source/$(params.contextDir)"]
image: busybox
resources: {}
workingDir: /workspace/source/$(params.contextDir)
workspaces:
- description: The git repo will be cloned onto the volume backing this workspace
name: source
The sources are usually cloned to a standard path called /workspace/source/<params.contextDir>
, in this example the contextDir
having quarkus
as default value.
You can create the Task using the command as shown in the following listing:
kubectl apply -n tektontutorial -f source-lister.yaml
Verify that your task was created:
tkn task ls
NAME AGE
source-lister 37 seconds ago
Lets describe the task
resource:
tkn task describe source-lister
The command above will shown an output like:
Name: source-lister
Namespace: tektontutorial
π¨ Input Resources
No input resources
π‘ Output Resources
No output resources
β Params
NAME TYPE DESCRIPTION DEFAULT VALUE
β url string <a href="https://github.com/redhat-scholars/tekton-tutorial-greeter" class="bare">https://github.com/redhat-scholars/tekton-tutorial-greeter</a>
β revision string master
β subdirectory string
β contextDir string The context directo... quarkus
β sslVerify string defines if http.ssl... false
π Results
NAME DESCRIPTION
β commit The precise commit ...
β url The precise URL tha...
π Workspaces
NAME DESCRIPTION
β source The git repo will b...
π¦Ά Steps
β clone
β ls-build-sources
π Taskruns
No taskruns
Since we have not run the Task yet, the command shows No taskruns. You can use the tkn
CLI tool to run the Task, pass parameters and input sources.
Use the
|
Since we just have to pass the GitHub repo for the source-lister, run the following command to start the TaskRun
:
tkn task start source-lister --showlog #Show the logs while running the Task
The command might ask your to confirm any default values, in this task we have a parameter called
Be sure press Enter to start the TaskRun after providing inputs to the prompts. Also, when prompted the name for the workspace, type
|
The command should show an output like:
? Value for param `contextDir` of type `string`? (Default is `quarkus`) quarkus
? Value for param `sslVerify` of type `string`? (Default is `false`) false
Please give specifications for the workspace: source
? Name for the workspace : source
? Value of the Sub Path :
? Type of the Workspace : emptyDir
? Type of EmptyDir :
TaskRun started: source-lister-run-pqx9r
Waiting for logs to be available...
[clone] + CHECKOUT_DIR=/workspace/source/
[clone] + /ko-app/git-init -url https://github.com/redhat-scholars/tekton-tutorial-greeter -revision master -path /workspace/source/ '-sslVerify=false'
[clone] {"level":"info","ts":1646396392.4501123,"caller":"git/git.go:157","msg":"Successfully cloned https://github.com/redhat-scholars/tekton-tutorial-greeter @ d9291c456db1ce29177b77ffeaa9b71ad80a50e6 (grafted, HEAD, origin/master) in path /workspace/source/"}
[clone] {"level":"info","ts":1646396392.5134826,"caller":"git/git.go:198","msg":"Successfully initialized and updated submodules in path /workspace/source/"}
[clone] + cd /workspace/source/
[clone] + git rev-parse HEAD
[clone] + RESULT_SHA=d9291c456db1ce29177b77ffeaa9b71ad80a50e6
[clone] + printf '%s' d9291c456db1ce29177b77ffeaa9b71ad80a50e6
[clone] + printf '%s' https://github.com/redhat-scholars/tekton-tutorial-greeter
[ls-build-sources] total 20
[ls-build-sources] drwxr-sr-x 4 root 10007200 4096 Mar 4 12:19 src
[ls-build-sources] -rw-r--r-- 1 root 10007200 4322 Mar 4 12:19 pom.xml
[ls-build-sources] -rw-r--r-- 1 root 10007200 380 Mar 4 12:19 README.md
[ls-build-sources] -rw-r--r-- 1 root 10007200 87 Mar 4 12:19 Dockerfile
The container images used by the steps need to be downloaded therefore the first execution of the task will take some time before it starts logging the output to the terminal. |
Remember a Task is running as a pod therefore you can watch your pod to see task lifecycle: Init, PodInitializing, Running, and finally Completed as seen in the following listing:
While the task is running open a new terminal and run:
watch kubectl get pods
The command should show an output like:
NAME READY STATUS AGE
source-lister-run-6xpgx-pod-c7dc67 0/2 Init:0/2 9s
...
NAME READY STATUS AGE
source-lister-run-6kt8d-pod-67b326 0/2 Completed 41s
Watching logs
If the Task ran successfully you will notice the following logs in your terminal (lines truncated for brevity):
TaskRun started: source-lister-run-pqx9r
Waiting for logs to be available...
...
[clone] + CHECKOUT_DIR=/workspace/source/
[clone] + /ko-app/git-init -url https://github.com/redhat-scholars/tekton-tutorial-greeter -revision master -path /workspace/source/ '-sslVerify=false'
[clone] {"level":"info","ts":1646396392.4501123,"caller":"git/git.go:157","msg":"Successfully cloned https://github.com/redhat-scholars/tekton-tutorial-greeter @ d9291c456db1ce29177b77ffeaa9b71ad80a50e6 (grafted, HEAD, origin/master) in path /workspace/source/"}
[clone] {"level":"info","ts":1646396392.5134826,"caller":"git/git.go:198","msg":"Successfully initialized and updated submodules in path /workspace/source/"}
[clone] + cd /workspace/source/
[clone] + git rev-parse HEAD
[clone] + RESULT_SHA=d9291c456db1ce29177b77ffeaa9b71ad80a50e6
[clone] + printf '%s' d9291c456db1ce29177b77ffeaa9b71ad80a50e6
[clone] + printf '%s' https://github.com/redhat-scholars/tekton-tutorial-greeter
[ls-build-sources] {"level":"info","ts":1585065132.8109465,"logger":"fallback-logger","caller":"logging/config.go:69","msg":"Fetch GitHub commit ID from kodata failed: \"KO_DATA_PATH\" does not exist or is empty"}
[ls-build-sources] total 36
[ls-build-sources] drwxr-xr-x 3 root root 4096 Mar 24 15:52 src
[ls-build-sources] -rw-r--r-- 1 root root 3472 Mar 24 15:52 pom.xml
[ls-build-sources] -rw-r--r-- 1 root root 6609 Mar 24 15:52 mvnw.cmd
[ls-build-sources] -rwxr-xr-x 1 root root 10078 Mar 24 15:52 mvnw
[ls-build-sources] -rw-r--r-- 1 root root 671 Mar 24 15:52 Dockerfile.jvm
[ls-build-sources] -rw-r--r-- 1 root root 188 Mar 24 15:52 Dockerfile
The logs are the consolidated logs from all the Task step containers. You can identify the source of the log i.e the step that has generated the logs using the text within the square brackets []
of each log line.
e.g.
Logs starting with [ls-build-sources] are from the container that is responsible for running the Task step i.e. ls-build-sources
.
Know the workspace directory
In the example above, there is a log which shows the git clone
command that cloned the application sources to the /workspace/source
directory. The workspace directory is where your Task/Pipeline sources/build artifacts will be cloned and generated. The source
is a sub-path, under which Tekton cloned the application sources. It is usually the name of the resources → inputs → Resource of type Git.
Cluster Task
The tasks are by default tied to namespace i.e their visibility is restricted to the namespace where they were created. E.g. the source-lister
that we created and ran earlier is tied to tektontutorial.
To check lets create a new namespace called clustertask-demo
:
kubectl create namespace clustertask-demo
kubectl config set-context --current --namespace clustertask-demo
Listing the tasks in the clustertask-demo
will not show any Tasks as shown in the command output below.
tkn task ls
No Tasks found
The reason that there are no Tasks found us that, we have not created any ClusterTask
yet. If the Task
is not of a ClusterTask
type then we will not be able to run the Task in namespaces other than where it was deployed. Try running our source-lister
task from within clustertask-demo
:
tkn task start source-lister --showlog
The command should fail with following output:
Error: Task name source-lister does not exist in namespace clustertask-demo
Let us now create a very simple ClusterTask called echoer as shown in the below listing:
apiVersion: tekton.dev/v1beta1
kind: ClusterTask (1)
metadata:
name: echoer
spec:
steps:
- image: alpine
script: | (2)
#!/bin/sh
echo 'Meeow!! from Tekton πΊπ'
1 | The kind ClusterTask makes the task available in all namespaces. |
2 | The step can also be shell script π |
kubectl apply -n clustertask-demo -f echoer.yaml
List and Describe ClusterTasks
tkn clustertask ls
You have to use clustertask command to list all cluster tasks
|
The comand should return an output like, with one ClusterTask echoer
:
NAME DESCRIPTION AGE
echoer 18 minutes ago
Let us decribe ClusterTask echoer
:
tkn clustertask describe echoer
The comand should return an output like:
Name: echoer
π¨ Input Resources
No input resources
π‘ Output Resources
No output resources
β Params
No params
π Results
No results
π Workspaces
No workspaces
π¦Ά Steps
β unnamed-0
π Taskruns
No taskruns
If you compare the output above with source-lister Task, the one big difference with respect to definition is the missing |
Run ClusterTask echoer
Lets run the task in the current namesapce clustertask-demo
:
tkn clustertask start echoer --showlog
TaskRun started: echoer-run-75n6g
Waiting for logs to be available...
[unnamed-0] Meeow!! from Tekton πΊπ
Run ClusterTask echoer
in other namespace(s)
Let us now shift back to tektontutorial
and run the echoer
task again:
kubectl config set-context --current --namespace=tektontutorial
Context "tektontutorial" modified.
tkn clustertask start echoer --showlog
The command should produce an identical output as shown in above.
Points to Ponder
-
Tasks are namespace bound i.e. available only in namespace(s) where they were created
-
Tasks resources are interacted using
tkn task
command and its options -
ClusterTasks are available across the cluster i.e. in any namesapce(s) of the cluster
-
ClusterTasks resources are interacted using
tkn clustertask
command and its options
Build Cloud Native Application
All the Tekton Tasks that we created and ran so far had only one Step
, but the Tekton Tasks can have more than one Step
.
Lets take an example of building a Cloud Native Java Application, at minimum the Task
need to do the following:
-
Clone the application from git.
-
Build the Application from sources using build tool like Apache Maven or Gradle
-
Build and push the container image to remote container registry like Quay.io or Docker Hub
The task build-app
is used to build the Java application that is part of the tutorial. The Task can be split into following three Steps
:
-
As a step one(
clone
) the application will be cloned from tekton-tutorial master branch -
Then the step two (
build-sources
) builds the application using Apache Maven -
The last step (
build-image-push
) uses the application artifacts generated by previous step, and builds the linux container image using buildah and the Dockerfile. The resulted linux container image will be pushed to the container registry.
The following section explains the three Task Steps
. The Deploy a task will finally deploy all these three steps together as one single build-app
task.
Task Workspace and Parameters
workspaces:
- name: source (1)
description: The git repo will be cloned onto the volume backing this workspace
params:
- name: contextDir (2)
description: the context dir within source
default: springboot
- name: mavenMirrorUrl
description: the maven mirrror url
default: https://repo.maven.apache.org/maven2/
- name: destinationImage (3)
description: the fully qualified image name
default: ""
- name: dockerFile(4)
description: the docker file to used for building the application
default: Dockerfile
- name: tlsVerify (5)
description: tls verify
type: string
default: "false"
- name: url
default: https://github.com/redhat-scholars/tekton-tutorial-greeter
- name: revision
default: master
- name: subdirectory
default: ""
- name: sslVerify
description: defines if http.sslVerify should be set to true or false in the global git config
type: string
default: "false"
- name: storageDriver
type: string
description: Use storage driver type vfs if you are running on OpenShift.
default: overlay
1 | The workspace shared by all the steps of this task and will cause the TektonPipelines to download the sources to workspace/source directory. |
2 | contextDir - specifies the directory under the sources, which will be the context for the Task |
3 | destinationImage - the linux container image name that will be built as part of this Task. Defaults to the outputs.resources.builtImage.url |
4 | dockerFile - the Dockerfile that will be used to build the image |
5 | tlsVerify - enable or disable TLS when pushing the image to remote registry |
Step#1 - Clone application resources
- name: clone
image: 'gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init:v0.15.2'
script: |
CHECKOUT_DIR="$(workspaces.source.path)/$(params.subdirectory)"
cleandir() {
# Delete any existing contents of the repo directory if it exists.
#
# We don't just "rm -rf $CHECKOUT_DIR" because $CHECKOUT_DIR might be "/"
# or the root of a mounted volume.
if [[ -d "$CHECKOUT_DIR" ]] ; then
# Delete non-hidden files and directories
rm -rf "$CHECKOUT_DIR"/*
# Delete files and directories starting with . but excluding ..
rm -rf "$CHECKOUT_DIR"/.[!.]*
# Delete files and directories starting with .. plus any other character
rm -rf "$CHECKOUT_DIR"/..?*
fi
}
/ko-app/git-init \
-url "$(params.url)" \
-revision "$(params.revision)" \
-path "$CHECKOUT_DIR" \
-sslVerify="$(params.sslVerify)"
cd "$CHECKOUT_DIR"
RESULT_SHA="$(git rev-parse HEAD)"
Step#2 - Build Application Sources
- name: build-sources
image: docker.io/maven:3.6.3-openjdk-8-slim
workingDir: "/workspace/source/$(params.contextDir)" (1)
command: (2)
- mvn
args: (3)
- -DskipTests
- clean
- package
env: (4)
- name: user.home
value: /home/tekton
1 | the working dir or the context directory within the sources from where the build command(s) will be run |
2 | the build command to run |
3 | the maven build command arguments |
4 | The environment variables that will be set within the step container |
Step#3 - Build and Push Application Linux Container Image
- name: build-and-push-image
image: quay.io/lordofthejars/buildah
# minikube
# image: quay.io/buildah/stable
script: |
#!/usr/bin/env bash
buildah --storage-driver=$STORAGE_DRIVER bud --layers -t $DESTINATION_IMAGE $CONTEXT_DIR
buildah --storage-driver=$STORAGE_DRIVER push $DESTINATION_IMAGE docker://$DESTINATION_IMAGE
env:
- name: DESTINATION_IMAGE
value: "$(params.destinationImage)"
- name: CONTEXT_DIR
value: "/workspace/source/$(params.contextDir)"
- name: STORAGE_DRIVER
value: "$(params.storageDriver)"
# enable the following lines only for Minikube
# securityContext: (1)
# runAsUser: 0
# privileged: true
volumeMounts: (2)
- name: varlibc
mountPath: /var/lib/containers
1 | Running buildah inside container needs to a set of privileges. When running in Minikube, these should be set as part of security context. |
2 | The buildah tool saves the built linux container layers in the local file system at /var/lib/containers , which can then be used in other steps or to push the image to remote registry. |
Having see the three individual steps of the build-app
task, the following snippet shows all three chained together:
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: build-app
spec:
workspaces:
- name: source
description: The git repo will be cloned onto the volume backing this workspace
params:
- name: contextDir
description: the context dir within source
default: springboot
- name: mavenMirrorUrl
description: the maven mirrror url
default: https://repo.maven.apache.org/maven2/
- name: destinationImage
description: the fully qualified image name
default: ""
- name: dockerFile
description: the docker file to used for building the application
default: Dockerfile
- name: tlsVerify
description: tls verify
type: string
default: "false"
- name: url
default: https://github.com/redhat-scholars/tekton-tutorial-greeter
- name: revision
default: master
- name: subdirectory
default: ""
- name: sslVerify
description: defines if http.sslVerify should be set to true or false in the global git config
type: string
default: "false"
- name: storageDriver
type: string
description: Use storage driver type vfs if you are running on OpenShift.
default: vfs
steps:
- image: 'gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init:v0.15.2'
name: clone
resources: {}
script: |
CHECKOUT_DIR="$(workspaces.source.path)/$(params.subdirectory)"
cleandir() {
# Delete any existing contents of the repo directory if it exists.
#
# We don't just "rm -rf $CHECKOUT_DIR" because $CHECKOUT_DIR might be "/"
# or the root of a mounted volume.
if [[ -d "$CHECKOUT_DIR" ]] ; then
# Delete non-hidden files and directories
rm -rf "$CHECKOUT_DIR"/*
# Delete files and directories starting with . but excluding ..
rm -rf "$CHECKOUT_DIR"/.[!.]*
# Delete files and directories starting with .. plus any other character
rm -rf "$CHECKOUT_DIR"/..?*
fi
}
/ko-app/git-init \
-url "$(params.url)" \
-revision "$(params.revision)" \
-path "$CHECKOUT_DIR" \
-sslVerify="$(params.sslVerify)"
cd "$CHECKOUT_DIR"
RESULT_SHA="$(git rev-parse HEAD)"
- name: build-sources
image: docker.io/maven:3.6.3-jdk-11-slim
command:
- mvn
args:
- -DskipTests
- clean
- install
env:
- name: user.home
value: /home/tekton
workingDir: "/workspace/source/$(params.contextDir)"
- name: build-and-push-image
image: quay.io/buildah/stable
script: |
#!/usr/bin/env bash
buildah --storage-driver=$STORAGE_DRIVER --tls-verify=$(params.tlsVerify) bud --layers -t $DESTINATION_IMAGE $CONTEXT_DIR
buildah --storage-driver=$STORAGE_DRIVER --tls-verify=$(params.tlsVerify) push $DESTINATION_IMAGE docker://$DESTINATION_IMAGE
env:
- name: DESTINATION_IMAGE
value: "$(params.destinationImage)"
- name: CONTEXT_DIR
value: "/workspace/source/$(params.contextDir)"
# needed for OpenShift buildah run as vfs is the default storage driver
- name: STORAGE_DRIVER
value: "$(params.storageDriver)"
workingDir: "/workspace/source/$(params.contextDir)"
volumeMounts:
- name: varlibc
mountPath: /var/lib/containers
volumes:
- name: varlibc
emptyDir: {}
Deploy a task
Make sure we are in the tektontutorial
:
kubectl config set-context --current --namespace=tektontutorial
kubectl config view --minify | grep namespace
Output should be like:
namespace: tektontutorial
The application build task could be created using the command:
kubectl apply -n tektontutorial -f build-app-task.yaml
We will use the Tekton cli to inspect the created resources
tkn task ls
The above command should list one Task as shown below:
NAME AGE
build-app 12 seconds ago
source-lister 7 minutes ago
|
TaskRun
The TaskRun is used to run a specific task independently. In the following section we will run the build-app
task created in the previous step.
The application build task(build-app
) could be run using the command:
tkn task start -n tektontutorial build-app \(1)
--param contextDir='springboot' \(2)
--param destinationImage='example.com/rhdevelopers/tekton-tutorial-greeter' \(3)
--showlog(4)
tkn task start -n tektontutorial build-app \(1)
--param contextDir='springboot' \(2)
--param destinationImage='image-registry.openshift-image-registry.svc:5000/tektontutorial/tekton-tutorial-greeter' \(3)
--param storageDriver='vfs' \
--showlog(4)
1 | The task that need to be run, in this case build-app |
2 | The directory inside repository where to do the build |
3 | The image repository URL where we want to push the image into. |
4 | Keep following the build logs |
It will take few seconds for the TaskRun to show status as Running
as it needs to download the container images.
|
Watch TaskRun logs
To check the status of the TaskRun use the logs
command of taskrun like:
tkn tr ls
NAME STARTED DURATION STATUS
build-app-run-tsqrf 2 minutes ago --- Running
echoer-run-gx6wp 40 minutes ago 15 seconds Succeeded
source-lister-run-6t2mj 1 hour ago 14 seconds Succeeded
source-lister-run-nbpvz 1 hour ago 28 seconds Succeeded
# use one task run for which you need the log from list above
tkn tr logs -f -a build-app-run-tsqrf (1)
1 | The -f or -a allows to tail the logs from all the containers of the task. For more options run tkn tr --help |
TaskRun Containers
Each task step will be run within a container of its own. You can list the containers of the build pod like:
kubectl get pods --selector=tekton.dev/task=build-app
e.g. For a build-app TaskRun pod build-app-run-lj7sm-pod-s74bp
kubectl get pod build-app-run-lj7sm-pod-s74bp \
-o jsonpath="{range .spec.containers[*] }{.name}{'\n'}{end}"
The command should show an output like:
step-clone
step-maven-build
step-build-and-push-image
As noted from the output each container will be prefixed by step-
followed by the step-name from that of the Task definition.
Apart from your step pods there will also be other Tekton pods that will be added to each TaskRun based on the input and output resources. e.g step-git-source-git-source-2lqtx, step-image-digest-exporter-52lh6
If you see the TaskRun status as Failed
or Error
use the following command to check the reason for error:
tkn taskrun describe <taskrun-name>
Test Task output
Lets try running the image build using the build-app
task:
kubectl apply -n tektontutorial -f $TUTORIAL_HOME/kubernetes/demo-greeter.yaml
Wait for the demo-greeter
to be up and running:
watch kubectl get pods -n tektontutorial
Lets try checking the application:
SVC_URL=$(minikube -p tektontutorial -n tektontutorial service demo-greeter --url)
kubectl apply -n tektontutorial -f $TUTORIAL_HOME/kubernetes/demo-greeter.yaml
Wait for the demo-greeter
to be up and replace the image:
oc set image deploy/demo-greeter *='image-registry.openshift-image-registry.svc:5000/tektontutorial/tekton-tutorial-greeter
And now let’s expose the service via a route:
oc expose svc -n tektontutorial demo-greeter
SVC_URL=$(oc get route demo-greeter -o yaml -o jsonpath='{.spec.host}')
http --body $SVC_URL
The above command should show an output like Meeow!! from Tekton πΊπ
Step Template
When there is a need to have similar container configuration across all steps of a Task, we can have them defined in the stepTemplate. The Task steps will then inherit them implicitly in all steps. In the example above we define the resources and securityContext for all the steps using the stepTemplate. Also if you notice in the example above we can also override the stepTemplate at the step level. That gives a unique flexibility to tweak the settings at step level.
With the current build-app
task, we see the following configuration in build—push-image
:
securityContext:
privileged: true
runAsUser: 0
volumeMounts:
- name: varlibc
mountPath: /var/lib/containers
We can move the above step configuration into a stepTemplate as shown in the following updated build-app
task:
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: build-app
spec:
stepTemplate:
# securityContext:
# runAsUser: 0
# privileged: true
volumeMounts:
- name: varlibc
mountPath: /var/lib/containers
workspaces:
- name: source
description: The git repo will be cloned onto the volume backing this workspace
params:
- name: contextDir
description: the context dir within source
default: springboot
- name: mavenMirrorUrl
description: the maven mirrror url
default: https://repo.maven.apache.org/maven2/
- name: destinationImage
description: the fully qualified image name
default: ""
- name: dockerFile
description: the docker file to used for building the application
default: Dockerfile
- name: tlsVerify
description: tls verify
type: string
default: "false"
- name: url
default: https://github.com/redhat-scholars/tekton-tutorial-greeter
- name: revision
default: master
- name: subdirectory
default: ""
- name: sslVerify
description: defines if http.sslVerify should be set to true or false in the global git config
type: string
default: "false"
- name: storageDriver
type: string
description: Use storage driver type vfs if you are running on OpenShift.
default: vfs
steps:
- image: 'gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init:v0.21.0'
name: clone
resources: {}
script: |
CHECKOUT_DIR="$(workspaces.source.path)/$(params.subdirectory)"
cleandir() {
# Delete any existing contents of the repo directory if it exists.
#
# We don't just "rm -rf $CHECKOUT_DIR" because $CHECKOUT_DIR might be "/"
# or the root of a mounted volume.
if [[ -d "$CHECKOUT_DIR" ]] ; then
# Delete non-hidden files and directories
rm -rf "$CHECKOUT_DIR"/*
# Delete files and directories starting with . but excluding ..
rm -rf "$CHECKOUT_DIR"/.[!.]*
# Delete files and directories starting with .. plus any other character
rm -rf "$CHECKOUT_DIR"/..?*
fi
}
/ko-app/git-init \
-url "$(params.url)" \
-revision "$(params.revision)" \
-path "$CHECKOUT_DIR" \
-sslVerify="$(params.sslVerify)"
cd "$CHECKOUT_DIR"
RESULT_SHA="$(git rev-parse HEAD)"
- name: build-sources
image: docker.io/maven:3.6.3-jdk-11-slim
command:
- mvn
args:
- -DskipTests
- clean
- install
env:
- name: user.home
value: /home/tekton
workingDir: "/workspace/source/$(params.contextDir)"
- name: build-and-push-image
image: quay.io/buildah/stable
script: |
#!/usr/bin/env bash
buildah --storage-driver=$STORAGE_DRIVER --tls-verify=$(params.tlsVerify) bud --layers -t $DESTINATION_IMAGE $CONTEXT_DIR
buildah --storage-driver=$STORAGE_DRIVER --tls-verify=$(params.tlsVerify) push $DESTINATION_IMAGE docker://$DESTINATION_IMAGE
env:
- name: DESTINATION_IMAGE
value: "$(params.destinationImage)"
- name: CONTEXT_DIR
value: "/workspace/source/$(params.contextDir)"
- name: STORAGE_DRIVER
value: "$(params.storageDriver)"
volumes:
- name: varlibc
emptyDir: {}
Apply new Task updates
Now you can apply the task as shown:
kubectl apply -n tektontutorial -f build-app-task-step-template.yaml
Now try running build-app
Task again:
tkn task start -n tektontutorial build-app \
--param contextDir='springboot' \
--param destinationImage='example.com/rhdevelopers/tekton-tutorial-greeter' \
--showlog(1)
tkn task start -n tektontutorial build-app \
--param contextDir='springboot' \
--param destinationImage='image-registry.openshift-image-registry.svc:5000/tektontutorial/tekton-tutorial-greeter'\
--param storageDriver='vfs' \
--showlog(1)
When you examine the TaskRun pods should notice stepTemplate
added to all the step containers including build-sources
.
List the pods that were part of the TaskRun for Task build-app
:
kubectl get pods --selector=tekton.dev/task=build-app
Check securityContext
Assuming the build-app-run pod to be build-app-run-dnbwp-pod-4hcvr
:
kubectl get pod -n tektontutorial build-app-run-dnbwp-pod-4hcvr \
-o=jsonpath="{range .spec.containers[*]}{.name}{'\n'}\
{'\t'}{'Privileged: '}{.securityContext.privileged}{'\t'}{'User: '}{.securityContext.runAsUser}{'\n'}{end}"
The command should an output like :
step-clone
Privileged: User:
step-build-sources
Privileged: User:
step-build-and-push-image
Privileged: User:
As you noticed that all steps have inherited the securityContext
from the StepTemplate
, making the step container to run in privileged
mode with user 0
Check volumeMounts
kubectl get pod -n tektontutorial build-app-run-dnbwp-pod-4hcvr \
-o=jsonpath="{range .spec.containers[*]}{.name}{'\n'}{'\t'}{'Mount Path: '}{.volumeMounts[?(@.name=='varlibc')].mountPath} {'\n'}{end}"
The command should an output like :
step-clone
Mount Path: /var/lib/containers
step-build-sources
Mount Path: /var/lib/containers
step-build-and-push-image
Mount Path: /var/lib/containers
As you noticed that all steps have inherited the mountPath
from the StepTemplate
.
The Task steps can override the stepTemplate values. |