Tekton is one of CI/CD tools that we can use for building and deploying application, it provides a lightweight yet powerful and flexible cloud native CI/CD. For this sample, i am planning to demonstrate a build and deployment for a java Spring Boot application into Openshift.
First we need to create two different Openshift Namespace,
oc new-project edwin-pipeline
oc new-project edwin-deploy
So lets start with creating a new PVC for storing our build artifacts. This PVC is going to be needed betweek Task, and we’ll store those artifact under a different folder based on Pipeline’s uid variable to prevent overlapping one and another.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: tekton-pvc
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 1Gi
And a pipeline YML file, for orchestrating our build and deployment steps.
apiVersion: tekton.dev/v1alpha1
kind: Pipeline
metadata:
name: hello-world-java-build-and-deploy
spec:
params:
- name: uid
description: the uid
workspaces:
- name: task-pvc
tasks:
- name: git-clone
taskRef:
name: git-clone
params:
- name: app-git
value: https://github.com/edwin/spring-boot-hello-world
- name: uid
value: $(params.uid)
workspaces:
- name: task-pvc
workspace: task-pvc
- name: build
taskRef:
name: mvn
runAfter: ["git-clone"]
params:
- name: goal
value: "package"
- name: uid
value: $(params.uid)
workspaces:
- name: task-pvc
workspace: task-pvc
- name: test
taskRef:
name: mvn
runAfter: ["build"]
params:
- name: goal
value: "test"
- name: uid
value: $(params.uid)
workspaces:
- name: task-pvc
workspace: task-pvc
- name: integration-test
taskRef:
name: mvn
runAfter: ["build"]
params:
- name: goal
value: "test"
- name: uid
value: $(params.uid)
workspaces:
- name: task-pvc
workspace: task-pvc
- name: deploy
taskRef:
name: deploy-and-clean
runAfter: ["integration-test","test"]
params:
- name: uid
value: $(params.uid)
workspaces:
- name: task-pvc
workspace: task-pvc
Based on above Pipeline, we have several Tasks which are involved within it. Lets start with a Task to clone a code from Github.
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: git-clone
spec:
params:
- name: app-git
description: the git repo
- name: uid
description: uid
workspaces:
- name: task-pvc
mountPath: /workspace/source
steps:
- name: git-clone
command: ["/bin/sh", "-c"]
args:
- |
set -e -o
echo "git clone";
mkdir /workspace/source/$(params.uid) && cd /workspace/source/$(params.uid);
git clone $(params.app-git) /workspace/source/$(params.uid);
image: image-registry.openshift-image-registry.svc:5000/openshift/jenkins-agent-maven
And a simple Maven build Task,
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: mvn
spec:
params:
- name: goal
description: mvn goal
- name: uid
description: uid
workspaces:
- name: task-pvc
mountPath: /workspace/source
steps:
- name: mvn
command: ["/bin/sh", "-c"]
args:
- |
set -e -o
echo "mvn something";
cd /workspace/source/$(params.uid);
mvn $(params.goal) -Dmaven.repo.local=/workspace/source/m2;
image: image-registry.openshift-image-registry.svc:5000/openshift/jenkins-agent-maven
The last task involved is a task to do deployment and removing build folder,
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: deploy-and-clean
spec:
params:
- name: uid
description: uid
workspaces:
- name: task-pvc
mountPath: /workspace/source
steps:
- name: git-clone
command: ["/bin/sh", "-c"]
args:
- |
set -e -o
cd /workspace/source/$(params.uid) ;
mkdir build-folder ;
cp target/*.jar build-folder/ ;
oc login --insecure-skip-tls-verify --token=my-openshift-token --server=https://api.my-openshift-url.com:6443 ;
oc new-build --name hello-world --binary=true -n edwin-deploy --image-stream=openjdk-11 || true ;
oc start-build hello-world --from-dir=build-folder/. -n edwin-deploy --follow --wait ;
oc new-app hello-world -n edwin-deploy || true ;
oc expose svc/hello-world -n edwin-deploy || true ;
cd / ;
rm -Rf /workspace/source/$(params.uid) ;
image: image-registry.openshift-image-registry.svc:5000/openshift/jenkins-agent-maven
And the last would be a PipelineRun yaml file for running the whole Pipeline,
apiVersion: tekton.dev/v1alpha1
kind: PipelineRun
metadata:
generateName: hello-world-run
spec:
params:
- name: uid
value: $(context.pipelineRun.uid)
pipelineRef:
name: hello-world-java-build-and-deploy
workspaces:
- name: task-pvc
persistentVolumeClaim:
claimName: tekton-pvc
And run it by using below command,
oc create -f 06.pipeline-run.yml -n edwin-pipeline
Code for this sample can be found on below Github link,
https://github.com/edwin/java-app-and-tekton-pipeline-sample
We are using UBI8 – OpenJDK11 for the base image that is going to be use for running our java apps. We can import it into our OCP cluster by using below command,
oc import-image openjdk-11 --from=registry.access.redhat.com/ubi8/openjdk-11 --confirm
Finally the result will looks like this,
Thanks
ps. Openshift version used is 4.8.2, and im using Openshift’s jenkins-agent-maven Image to do all build and deployments. Feel free to use other image in case needed.