Workspaces
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 Workspaces ?
-
Mount ConfigMap based configurations as Workspace
-
Mount a PersistenceVolume as Workspace
-
Share and Cache build artifacts
-
Use workspace in TaskRun
-
Use workspace in PipelineRun
If you are not in tutorial chapter folder, then navigate to the folder:
cd $TUTORIAL_HOME/workspaces
Why Workspace ?
In many partical usecases of Pipelines it becomes crucial for you to share the filesystem between Tasks and between Steps. The filesystem could typically hold a clone github repostiory, a ConfigMap or a secret.
A Task step and Pipeline task can share a common filesystem via a Tekton workspace
. This helps Pipelines to pick up changes from one task to another task in the Pipeline workflow.
Overview
As part of workspaces
exercies, we will be building the Java application Apache Maven. Using Java Application usecase allows us to explore all possible applications of workspaces:
-
Mount ConfigMap based configurations as Workspace
-
Mount a PersistenceVolume as Workspace
-
Share and Cache build artifacts
Prepare for using workspaces
All exercises of this chapter will be done a namespace workspace-auth-demo
, let’s create and switch to the workspace-auth-demo
namespace.
kubectl create ns workspace-auth-demo
kubectl config set-context --current --namespace workspace-auth-demo
As part of this exercise we will need to install the following external tasks and cluster tasks to be installed in the namespace:
kubectl apply -n workspace-auth-demo \
-f https://raw.githubusercontent.com/tektoncd/catalog/master/task/git-clone/0.1/git-clone.yaml \
-f https://raw.githubusercontent.com/tektoncd/catalog/master/task/maven/0.1/maven.yaml \
-f https://raw.githubusercontent.com/openshift/tektoncd-pipeline-operator/master/deploy/resources/addons/02-clustertasks/buildah/buildah-task.yaml \
-f https://raw.githubusercontent.com/tektoncd/catalog/master/task/kn/0.1/kn.yaml \
-f $TUTORIAL_HOME/workspaces/list-directory-task.yaml
Check if all the tasks are available:
tkn task ls
The command should show an output like:
NAME DESCRIPTION AGE
buildah Buildah task builds... 11 hours ago
git-clone These Tasks are Git... 11 hours ago
kn This Task performs ... 9 minutes ago
list-directory Simple directory li... 11 hours ago
maven This Task can be us... 11 hours ago
Deploy Nexus
To show maven artifact caching and using customized maven settings.xml
we will deploy Sonatype Nexus to the cluster:
kubectl apply -n workspace-auth-demo \
-f $TUTORIAL_HOME/install/utils/nexus.yaml
Wait for the nexus3 pod to come up before proceeding further with exercises:
watch kubectl -n workspace-auth-demo get pods,svc
A sucessfully running nexus3 pod should show the following services and pods:
NAME READY STATUS RESTARTS AGE
pod/nexus-75fff8bbbd-cmlxs 1/1 Running 0 3m25s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/nexus NodePort 10.100.205.22 <none> 8081:31743/TCP 3m25s
The nexus maven repository could be opened using the url:
minikube -p tektontutorial service nexus -n workspace-auth-demo --url
http://192.168.64.27:30102
In OpenShift we can use routes to expose the service if we need to access it from outside the cluster by:
oc expose svc -n workspace-auth-demo nexus
Create maven-settings ConfigMap
For us to mount the maven settings.xml
, we will create ConfigMap holding the custom maven settings.xml:
kubectl create -n workspace-auth-demo cm maven-settings \
--from-file=settings.xml=$TUTORIAL_HOME/workspaces/maven-settings.xml
configmap/maven-settings created
You can check the ConfigMap contents using the command:
kubectl get -n workspace-auth-demo cm maven-settings -o yaml \
-o jsonpath='{.data}'
The output of the above command should be same as in maven-settings.xml.
Deploy Knative Serving
As we will be deploying a Knative serverless application as part of the pipeline, that we will be running later in this chapter, lets deploy Knative to the cluster:
Do it only once per cluster |
$TUTORIAL_HOME/bin/enable_knative.sh
Wait for the serving deployment to complete without errors.
OpenShift users can install Knative by following the instructions here for installing OpenShift Serverless.
Follow the instructions for installing the Serverless Operator on the cluster and then follow the instructions for creating Knative Serving.
Check Default Storage Class
Before we create our pipeline ensure that the kubernetes cluster has a default storage class defined:
kubectl get sc
In minikube cluster it should show an output like:
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
standard (default) k8s.io/minikube-hostpath Delete Immediate false 44m
An example default storage class in Google Cloud:
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
standard (default) kubernetes.io/gce-pd Delete WaitForFirstConsumer true 2d3h
|
Create PVC
Create the PVC tekton-tutorial-sources
, which we will use as part of the exercises in this chapter and the upcoming ones.
kubectl apply -n workspace-auth-demo -f $TUTORIAL_HOME/workspaces/sources-pvc.yaml
Java Application Pipeline
The Java Application build pipeline will,
-
Git clone using
git-clone
task, the https://github.com/redhat-scholars/tekton-tutorial-greeter repo and build the springboot application -
Will use maven task, maven task require two workspaces one for source and other for maven-settings
-
Build the container image using the
buildah
task and push to the internal container registry -
Finally deploy the application onto Kubernetes using
openshift-client
task
Using PVC As Workspace
As part of this exercise we will use PersitenceVolume(PV) and PersistenceVolumeClaim(PVC) as Tekton workspace.
Git Clone TaskRun
Since we will be using the same git repo for all the exercises, lets clone it. As git clone task requires output
workspace, we will attach a PersistenceVolumeClaim to it.
Since the cluster as default Storage Class, just specifying the PersistenceVolumeClaim will bind the PVC automatically to underlying storage. We will use the PVC tekton-tutorial-sources
that we created earlier.
Let us run the git-clone
Task with the TaskRun
definition as shown below:
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
generateName: git-clone- (1)
labels: (2)
tekton.dev/task: git-clone
spec:
taskRef:
name: git-clone
params: (3)
- name: url
value: https://github.com/redhat-scholars/tekton-tutorial-greeter
- name: revision
value: master
workspaces: (4)
- name: output
persistentVolumeClaim:
claimName: tekton-tutorial-sources
1 | As its required have unqiue name for each TaskRun we use create, as that will have new names genrated using generateName prefix |
2 | Just marking this TaskRun as part of git-clone Task |
3 | The GitHub Url and revision to use, for more details check the Task |
4 | Setting the workspace output mapped to PVC tekton-tutorial-sources |
tkn task start git-clone \
--namespace=workspace-auth-demo \
--param url=https://github.com/redhat-scholars/tekton-tutorial-greeter \
--param revision=master \
--param deleteExisting=true \
--workspace name=output,claimName=tekton-tutorial-sources \
--use-param-defaults \(1)
--showlog
1 | Makes the tkn CLI to use the default values from the task definiton without prompting for values |
The workspaces can be PVC or ConfigMap, Secret or emptyDir. The pattern to specify them are as follows:
-
PVC
-
name=my-pvc,claimName=pvc1[,subPath=dir]
-
-
Secret
-
name=my-secret,secret=secret-name
-
-
Secret
-
name=my-config,config=rpg[,item=ultimav=1]
-
-
emptyDir
-
name=my-empty-dir,emptyDir=""
-
kubectl create -n workspace-auth-demo -f git-clone-taskrun.yaml
It will take few minutes for the TaskRun to start.
Watch the status of the Task run using:
View the task run logs using,
|
You can also check the PVC is bound, as the git-clone-task output workspace is bound to it:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
tekton-tutorial-sources Bound pvc-48aa86ae-ec20-4f0c-a2d0-65d906d41bed 1Gi RWO standard 6s
A successful git-clone TaskRun will show the following output:
[clone] + CHECKOUT_DIR=/workspace/output/
[clone] + '[[' false '==' true ]]
[clone] + test -z
[clone] + test -z
[clone] + test -z
[clone] + /ko-app/git-init -url https://github.com/redhat-scholars/tekton-tutorial-greeter -revision master -refspec -path /workspace/output/ '-sslVerify=true' '-submodules=true' -depth 1
[clone] {"level":"info","ts":1595778607.616774,"caller":"git/git.go:139","msg":"Successfully cloned https://github.com/redhat-scholars/tekton-tutorial-greeter @ 2e3336657cc1bbf22e3db183a517dcb0a62207b9 (grafted, HEAD, origin/master) in path /workspace/output/"}
[clone] {"level":"info","ts":1595778607.6473103,"caller":"git/git.go:180","msg":"Successfully initialized and updated submodules in path /workspace/output/"}
[clone] + cd /workspace/output/
[clone] + git rev-parse+ tr -d '\n'
[clone] HEAD
[clone] + RESULT_SHA=2e3336657cc1bbf22e3db183a517dcb0a62207b9
[clone] + EXIT_CODE=0
[clone] + '[' 0 '!=' 0 ]
[clone] + echo -n 2e3336657cc1bbf22e3db183a517dcb0a62207b9
List Directory TaskRun
As explained in the overview one of the advantages of the workspaces
is that it can be shared, lets run a simple list-directory Task to verify the same:
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
generateName: list-directory-
labels:
tekton.dev/task: list-directory
spec:
taskRef:
name: list-directory
workspaces: (1)
- name: directory
persistentVolumeClaim:
claimName: tekton-tutorial-sources
1 | Notice that we bind the same PVC to workspace directory parameter of the list-directory . |
tkn task start list-directory \
--namespace=workspace-auth-demo \
--workspace name=directory,claimName=tekton-tutorial-sources \
--use-param-defaults \
--showlog
kubectl create -n workspace-auth-demo -f list-dir-taskrun.yaml
taskrun.tekton.dev/list-directory-mbkvl created
If all went well the list directory should show the directory listing of https://github.com/redhat-scholars/tekton-tutorial-greeter.
[list-directory] total 44
[list-directory] drwxr-xr-x 3 root root 4096 Aug 17 07:46 springboot
[list-directory] -rw-r--r-- 1 root root 515 Aug 17 07:46 settings.xml
[list-directory] drwxr-xr-x 3 root root 4096 Aug 17 07:46 quarkus
[list-directory] -rw-r--r-- 1 root root 926 Aug 17 07:46 pom.xml
[list-directory] -rwxr-xr-x 1 root root 6607 Aug 17 07:46 mvnw.cmd
[list-directory] -rwxr-xr-x 1 root root 10069 Aug 17 07:46 mvnw
[list-directory] drwxr-xr-x 2 root root 4096 Aug 17 07:46 k8s
[list-directory] -rw-r--r-- 1 root root 596 Aug 17 07:46 README.md
[show-readme] # Tekton Greeter
[show-readme]
[show-readme] Project used as part of [Tekton Tutorial](https://dn.dev/tekton-tutorial) execersies.
[show-readme]
[show-readme] The application has one simple REST api at URI `/` that says "Meeow from Tekton 😺 !! 🚀".
[show-readme]
[show-readme] ## Quarkus
[show-readme]
[show-readme] [Quarkus](./quarkus)
[show-readme]
[show-readme] ### Building locally
[show-readme]
[show-readme] ```shell
[show-readme] ./mvnw clean package -pl quarkus
[show-readme] ```
[show-readme]
[show-readme] ### Running locally
[show-readme]
[show-readme] ```shell
[show-readme] java -jar quarkus/target/quarkus-app/quarkus-run.jar
[show-readme] ```
[show-readme]
[show-readme] ## SpringBoot
[show-readme]
[show-readme] [SpringBoot](./quarkus)
[show-readme]
[show-readme] ### Building locally
[show-readme]
[show-readme] ```shell
[show-readme] ./mvnw clean package -pl springboot
[show-readme] ```
[show-readme]
[show-readme] ### Running locally
[show-readme]
[show-readme] ```shell
[show-readme] java -jar springboot/target/tekton-springboot-greeter.jar
[show-readme] ```
Using ConfigMap as Workspace
As part of this exercise we will use and configure Tekton workspace
with ConfigMap.
Run maven Task
In this exercise, we will use maven-settings ConfigMap that we created earlier as one of workspace parameter maven-settings and for the source workspace paramter we use the tekton-tutorial-sources
PVC.
Let run the maven task to build the tekton-greeter project we cloned earlier.
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
generateName: maven-build-
labels:
tekton.dev/task: maven
spec:
taskRef:
name: maven
params:
- name: GOALS (1)
value:
- -B
- -pl
- springboot
- -DskipTests
- clean
- package
workspaces:
- name: maven-settings
configmap: (2)
name: maven-settings
- name: source
persistentVolumeClaim: (3)
claimName: tekton-tutorial-sources
1 | Specifying the maven goals to be run as a part of the build |
2 | Configure the maven-settings configmap to be used for maven-settings workspace |
3 | Configure the tekton-tutorial-sources PVC to be used for source workspace |
tkn task start maven \
--namespace=workspace-auth-demo \
--param GOALS='-pl,springboot,-B,-DskipTests,clean,package' \
--workspace name=maven-settings,config=maven-settings \
--workspace name=source,claimName=tekton-tutorial-sources \
--use-param-defaults \
--showlog
kubectl create -n workspace-auth-demo -f maven-taskrun.yaml
taskrun.tekton.dev/maven-build-9cjws created
View the task run logs using,
tkn tr logs -f -a $(tkn tr ls -n workspace-auth-demo | awk 'NR==2{print $1}')
A successfull run should have output like(output trimmed for brevity):
...
[mvn-goals] [INFO] Downloaded from nexus: http://nexus:8081/repository/maven-public/org/eclipse/sisu/org.eclipse.sisu.plexus/0.3.4/org.eclipse.sisu.plexus-0.3.4.jar (205 kB at 1.0 MB/s)
[mvn-goals] [INFO] Downloaded from nexus: http://nexus:8081/repository/maven-public/org/eclipse/sisu/org.eclipse.sisu.inject/0.3.4/org.eclipse.sisu.inject-0.3.4.jar (379 kB at 1.9 MB/s)
[mvn-goals] [INFO] Downloaded from nexus: http://nexus:8081/repository/maven-public/org/codehaus/plexus/plexus-classworlds/2.6.0/plexus-classworlds-2.6.0.jar (53 kB at 259 kB/s)
[mvn-goals] [INFO] Downloaded from nexus: http://nexus:8081/repository/maven-public/org/sonatype/plexus/plexus-build-api/0.0.7/plexus-build-api-0.0.7.jar (8.5 kB at 40 kB/s)
[mvn-goals] [INFO] Replacing main artifact with repackaged archive
[mvn-goals] [INFO] ------------------------------------------------------------------------
[mvn-goals] [INFO] BUILD SUCCESS
[mvn-goals] [INFO] ------------------------------------------------------------------------
[mvn-goals] [INFO] Total time: 8.572 s
[mvn-goals] [INFO] Finished at: 2020-08-17T08:20:22Z
[mvn-goals] [INFO] ------------------------------------------------------------------------
...
When the TaskRun runs for the first , it will run loner as it will maven artifacts for the first time and caches the artifacts nexus repository manager. Try running the command again to see it will run a lot quicker. |
List build target directory
tkn task start list-directory \
--namespace=workspace-auth-demo \
--param sub-dirs='springboot/target' \
--workspace name=directory,claimName=tekton-tutorial-sources \
--use-param-defaults \
--showlog
kubectl create -n workspace-auth-demo -f list-target-dir-taskrun.yaml
taskrun.tekton.dev/list-directory-xbzpq created
View the task run logs using,
tkn tr logs -f -a $(tkn tr ls -n workspace-auth-demo | awk 'NR==2{print $1}')
A successful command should show the following output:
The output(trimmed for brevity) of the command should be like:
[list-directory] total 18020
[list-directory] drwxr-xr-x 3 root root 4096 Aug 17 08:21 maven-status
[list-directory] drwxr-xr-x 3 root root 4096 Aug 17 08:21 generated-sources
[list-directory] drwxr-xr-x 3 root root 4096 Aug 17 08:21 test-classes
[list-directory] drwxr-xr-x 3 root root 4096 Aug 17 08:21 generated-test-sources
[list-directory] drwxr-xr-x 3 root root 4096 Aug 17 08:21 classes
[list-directory] -rw-r--r-- 1 root root 3748 Aug 17 08:21 tekton-springboot-greeter.jar.original
[list-directory] drwxr-xr-x 2 root root 4096 Aug 17 08:21 maven-archiver
[list-directory] -rw-r--r-- 1 root root 18421378 Aug 17 08:21 tekton-springboot-greeter.jar
...
Deploy Pipeline
Let us now apply what we learned with workspace to build and deploy the application pipeline as shown:
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: greeter-app-deploy
spec:
description: >-
The Pipeline to build and deploy the Hello World Java App
https://github.com/redhat-scholars/tekton-tutorial-greeter as Knative
Service.
params:
- description: >-
The fully qualified image name. If you are running on Minikube please
use example.com/tekton-tutorial/greeter On OpenShift, use
image-registry.openshift-image-registry.svc:5000/workspace-auth-demo/tekton-tutorial-greeter
default: image-registry.openshift-image-registry.svc:5000/workspace-auth-demo/tekton-tutorial-greeter
name: image-name (1)
type: string
- description: >-
The application framework to use, value can be either quarkus or
springboot
name: context-dir
type: string
- default: greeter
description: The Knative Service name
name: kn-service-name
type: string
- default: 'https://github.com/redhat-scholars/tekton-tutorial-greeter'
description: The GitHub Repo of the Java Application
name: github-repo-url
type: string
- default: staging
description: The GitHub revision to use
name: github-repo-revision
type: string
- name: storageDriver
type: string
description: Use storage driver type vfs if you are running on OpenShift.
default: vfs
workspaces:
- name: source (2)
- name: maven-settings (3)
tasks:
- name: clone-sources
params:
- name: url
value: $(params.github-repo-url)
- name: revision
value: $(params.github-repo-revision)
- name: deleteExisting
value: 'true'
taskRef:
kind: Task
name: git-clone
workspaces:
- name: output
workspace: source
- name: build-java-test
params:
- name: GOALS
value:
- '-pl'
- $(params.context-dir)
- '-B'
- clean
- test
runAfter:
- clone-sources
taskRef:
kind: Task
name: maven
workspaces:
- name: maven-settings
workspace: maven-settings
- name: source
workspace: source
- name: build-java-app
params:
- name: GOALS
value:
- '-pl'
- $(params.context-dir)
- '-B'
- '-DskipTests'
- clean
- package
runAfter:
- build-java-test
taskRef:
kind: Task
name: maven
workspaces:
- name: maven-settings
workspace: maven-settings
- name: source
workspace: source
- name: build-java-app-image
params:
- name: CONTEXT
value: $(params.context-dir)
- name: IMAGE
value: $(params.image-name)
- name: STORAGE_DRIVER
value: $(params.storageDriver)
- name: TLSVERIFY
value: 'false'
runAfter:
- build-java-app
taskRef:
kind: ClusterTask
name: buildah
workspaces:
- name: source
workspace: source
- name: deploy-kn-service
params:
- name: ARGS
value:
- service
- create
- $(params.kn-service-name)
- '--force'
- >-
--image=$(params.image-name)@$(tasks.build-java-app-image.results.IMAGE_DIGEST) (4)
runAfter:
- build-java-app-image
taskRef:
kind: Task
name: kn
1 | The parameters for the Pipeline |
2 | A workspace named source , we will map it to the PVC`tekton-tutorial-sources` in PipelineRun in upcoming section |
3 | A workspace named maven-settings , we will map it to ConfigMap maven-settings in the PipelineRun in upcoming section |
4 | The buildah build image task returns a output. We use the that as part of the --image parameter to kn Task |
Create the Pipeline
kubectl apply -n workspace-auth-demo -f greeter-app-deploy.yaml
pipeline.tekton.dev/greeter-app-deploy created
Create Service Account
We need to create the Service Account(SA) that is authorized to Knative Service deployments. To create the SA run:
curl -sSL \
https://raw.githubusercontent.com/tektoncd/catalog/master/task/kn/0.1/support/kn-deployer.yaml \
| yq '.metadata.namespace="workspace-auth-demo"' \
| kubectl apply -f -
The successful command should show an output like:
serviceaccount/kn-deployer-account created
clusterrole.rbac.authorization.k8s.io/kn-deployer created
clusterrolebinding.rbac.authorization.k8s.io/kn-deployer-binding created
Run the Pipeline
tkn pipeline start greeter-app-deploy \
--namespace=workspace-auth-demo \
--serviceaccount=kn-deployer-account \
--param context-dir='quarkus' \
--workspace name=maven-settings,config=maven-settings \
--workspace name=source,claimName=tekton-tutorial-sources \
--showlog
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: greeter-app-
labels:
tekton.dev/pipeline: greeter-app-deploy
spec:
serviceAccountName: kn-deployer-account (1)
pipelineRef:
name: greeter-app-deploy
params:
- name: context-dir
value: quarkus
# enable this for OpenShift
# - name: storageDriver
# value: vfs
workspaces: (2)
- name: maven-settings
configmap:
name: maven-settings
- name: source
persistentVolumeClaim:
claimName: tekton-tutorial-sources
kubectl create -n workspace-auth-demo -f greeter-app-deploy-run.yaml
pipelinerun.tekton.dev/greeter-app-7k9cw created
View the pipeline run logs using,
tkn pr logs -f -a $(tkn pr ls -n workspace-auth-demo | awk 'NR==2{print $1}')
A successful Pipelinerun should have the greeter
application up and running as shown:
kn service describe -n workspace-auth-demo greeter
The command should show an output like :
Name: greeter
Namespace: workspace-auth-demo
Age: 21s
URL: http://greeter.workspace-auth-demo.192.168.64.7.nip.io
Revisions:
100% @latest (greeter-ttyqz-1) [1] (21s)
Image: example.com/tekton-tutorial/greeter@sha256:79b8a50a6ef29dbc0df5220de5aea13b8b38b7c4cd407ad074968de8cfbd41b6 (at 79b8a5)
Conditions:
OK TYPE AGE REASON
++ Ready 13s
++ ConfigurationsReady 14s
++ RoutesReady 13s