Tekton Pipelines on OpenShift (Part 1)

Image for post
Image for post

This article is part 1 of the series where we will build a pipeline to build and deploy an application on OpenShift.

In Part 1, we will build a pipeline that will fetch the code from the GitHub repository, build an image, and deploy it on OpenShift & In Part 2 we will automate the triggering of the pipeline using Tekton Triggers on a GitHub Event.

We will be using an existing application created by alexdevero which is a meme generator.

I have forked this and modified it so that it can be dockerized and deployed on a cluster. You can get it from sm43/react-meme-generator-ts.

Prerequisites:

  • Kubernetes Cluster
    I will be using an OpenShift Cluster. You can get one from https://try.openshift.com or install an OpenShift Cluster on your local machine i.e CRC.
    You can use any Kubernetes cluster for installing, running, and managing the pipeline using UI which we will see in a bit.
  • kubectl/oc
    CLI to access the cluster.
  • tkn
    Tetkon CLI to interact with Tekton resource.

Let’s get started.

Login into you OpenShift Cluster and install RedHat OpenShift Pipeline Operator from Operator Hub.

Image for post
Image for post

Once Installed you can go and check-in openshift-pipelines namespace that the Pipelines and Triggers are deployed as Pods.

Now, let's clone the repository which has the application and the deployment files.

git clone https://github.com/SM43/react-meme-generator-ts.gitcd react-meme-generator-ts/

Let’s understand what we are going to do. So, we have an App which is a meme generator developed in react. There is Dockerfile which will be used to create a docker image from the code.
You can also create an image and run locally using docker/podman.

podman build -t meme-generator . && \
podman run --rm -p 8080:8080 localhost/meme-generator

Once the image is built and committed, access the application at http://localhost:8080.

Now, we have dockerfile to create a image, we will use this in our pipeline.
Our pipeline looks as below

---
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: build-and-deploy
spec:
params:
- name: repository
type: string
- name: image
type: string
- name: manifest-dir
type: string
- name: deployment-name
type: string
workspaces:
- name: shared-workspace
tasks:
- name: fetch-repository
taskRef:
name: git-clone
workspaces:
- name: output
workspace: shared-workspace
params:
- name: url
value: $(params.repository)
- name: subdirectory
value: ""
- name: deleteExisting
value: "true"
- name: build-image
taskRef:
name: buildah
runAfter:
- fetch-repository
workspaces:
- name: source
workspace: shared-workspace
params:
- name: IMAGE
value: $(params.image)
- name: TLSVERIFY
value: "false"
- name: deploy
taskRef:
name: oc-apply-deployment
workspaces:
- name: source
workspace: shared-workspace
params:
- name: new-image
value: $(params.image)
- name: deployment-name
value: $(params.deployment-name)
runAfter:
- build-image

There are 3 stages:
1. fetch-repository which uses git-clone task and clone the repository in the workspace. In this stage, we pass git URL to the task and the pvc (workspace) where the repository will be cloned. This same workspace will be used by next Task to access the code.

2. build-image which uses buildah task to create an docker image from the code cloned in workspace and push the image to the registry. In this stage we pass the workspace where the code is cloned and the registry+image reference where the image will be pushed.

3. deploy which uses the oc-apply-deployment task to deploy the image used to the registry using the manifest files in the repository. We pass the image name, deployment-name and workspace where the code is cloned. By default the task will look for manifestink8s directory which is there in the repository.
If we have a directory with different name then we can pass the name as a param to the Task.

The first 2 tasks git-clone(0.1) and buildah(0.1) are from the tektoncd/catalog. We will directly install it from there. Use the below code and paste it in the terminal to install the Tasks.

kubectl apply -f \
https://raw.githubusercontent.com/tektoncd/catalog/master/task/git-clone/0.1/git-clone.yaml \
&& \
kubectl apply -f \
https://raw.githubusercontent.com/tektoncd/catalog/master/task/buildah/0.1/buildah.yaml

Check the installed Tasks using the below command

> ~ > tkn task ls
NAME DESCRIPTION AGE
buildah Buildah task builds... 7 seconds ago
git-clone These Tasks are Git... 12 seconds ago

The third task is a custom task created, you can use any other task from the catalog as per your wish.

Make sure you are in the react-meme-generator-ts directory.
The pipeline directory has 4 files :
- First will create a PVC which will be used as a workspace for cloning the repository and then the other Tasks will access this workspace.
- Second will install the Task which deploys the image using the manifest in k8s directory. If the image is changed then it will patch the existing deployment with the new image.
- Third will install the Pipeline.
- Fourth will create a new instance of PipelineRun which executes the pipeline.
If you take a look at the PipelineRun, you would be able to see that it has params to mention the GitHub URL, the image name, the deployment name.
You can edit as you want.
Apply the files using the below command:

kubectl apply -f pipeline/

Check the installed pipeline using

> ~ > tkn p ls
NAME AGE LAST RUN STARTED DURATION STATUS
build-and-deploy 7 seconds ago --- --- --- ---

Check the PipelineRun started

> ~ > tkn pr ls
NAME STARTED DURATION STATUS
build-and-deploy-run 10 seconds ago --- Running

We are using the OpenShift Internal Registry to push the Image. If you see in PipelineRun, the image mentioned is

image-registry.openshift-image-registry.svc:5000/default/meme-generator:latest

This is configured for the default namespace. If you are in a different namespace make sure you replace default with the namespace you are in.

You can also use an external registry like DockerHub or Quay to push the Image. You need to create a registry secret and give permission to pipeline the service account to access that secret with permission to pull and push.

pipeline service account is created when we install Pipelines using the Operator from Operator Hub.

You can check out the progress of Pipeline from the OpenShift Console, going to Developer tab and clicking on Pipelines.

Image for post
Image for post

You can also check the logs from the command line using tkn.

tkn pr ls

This will list the PipelineRuns.
To follow the logs, use the below command

tkn pr logs -f build-and-deploy-run

In k8s, there 3 files deployment, service, and route. In the final stage of the pipeline, the task will apply these files and create a deployment for the application, will expose the app using a NodePort Service, and create a route to access the app.

Once the pipeline is completed, you would be able to see a pod created in Topology. Click on the pod and use the route created to access the Application.

Image for post
Image for post

We have successfully created a Pipeline that builds an image and deploys it on the Cluster. Currently, we are manually invoking the Pipeline, in the next article, we will configure Tekton Trigger which will trigger the Pipeline on a GitHub Event for ex. after a pull request is merged the Pipeline will start and deploy the new changes on the Cluster.

Part 2 coming soon... :)

Written by

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store