Skip to content

Latest commit

 

History

History
264 lines (181 loc) · 12.3 KB

2021-05-14-bring-gitops-to-your-functions-with-argocd-part-2-the-missing-piece-tekton.md

File metadata and controls

264 lines (181 loc) · 12.3 KB
title description date image categories author_staff_member dark_background
Learn how to build your OpenFaaS Functions with Tekton
Learn how to trigger builds of your functions from GitHub using Tekton. Then connect them to Argo CD so that you can deploy as new versions are created.
2021-05-14
/images/2021-06-tekton/tekton_argocd_power.png
arkade
kubectl
argocd
tekton
gitops
openfaas-operator
helm
developer-guy
true

Learn how to trigger builds of your functions from GitHub using Tekton. Then connect them to Argo CD so that you can deploy as new versions are created.

Introduction

We talked about How we can bring GitOps principles to management of OpenFaaS functions in the previous blog post. If you haven't read it yet, you can follow this link, because it might help you to understand the all of the pieces of CI/CD pipeline we want to build here. In this guide, we'll add CI (Continious Integration) part to our pipeline by using Tekton. After that, to be able to trigger this pipeline based on GitHub events, we'll use an another component of Tekton called Tekton Trigger. We will do this demo using KinD on a kubernetes running locally. Because of we are in a private network, we have to listen events that send by GitHub to trigger our Tekton Pipeline. So we need to find a way to susbcribe those events, and this is where Tekton Triggers comes into the picture. So, we said that everyhing is in local, so, we should open our local services to the internet, GitHub in this case, to be able GitHub send events to our event listener, and this is where Inlets, a Cloud Native Tunnel, comes in to the picture. At the end of this tutorial, we'll have a pipeline like the following:

tekton_argocd_arch

Prerequisites

We have to install the following tools to be able to achieve this demo, luckily we have arkade which is an open-source Kubernetes marketplace, so we can install of the following tools by using arkade:

  • arkade (v0.7.15) Kubernetes marketplace
# Run with or without sudo
$ curl -sLS https://dl.get-arkade.dev | sudo sh
  • KinD (Kubernetes in Docker) v0.10.0

    Kubernetes is our recommendation for teams running at scale, but in this demo we will be using KinD for the sake of simplicity.

    $ arkade get kind --version=v0.10.0
  • kubectl v1.21.0

    You can control your cluster using kubectl CLI.

    $ arkade get kubectl --version=v1.21.0
  • tkn v0.18.0

    You can use tkn CLI for interacting with Tekton resources.

    $ arkade get tkn --version=v0.18.0
  • ArgoCD CLI v2.0.0

    ArgoCD CLI controls an Argo CD server. More detailed installation instructions can be found via the CLI installation documentation. Fortunately, we can install it via arkade too.

    $ arkade get argocd --version=v2.0.0

Setup

Before getting started to install Tekton and Tekton Trigger, we have to install Argo CD and OpenFaaS Operator through the Argo CD, so we can follow the steps below to install them before move on to the next step.

  1. Provision a local Kubernetes Cluster with KinD
  2. Deploy ArgoCD
  3. Deploy OpenFaaS Operator and OpenFaaS functions through ArgoCD

4. Deploy Tekton and Tekton Trigger

There are various ways to install Tekton and Tekton Trigger Trigger, one of them is Tekton Operator, and the other one is just with plain YAML manifest. We are going to deploy Tekton and Tekton Trigger with plain YAML manifest in this section.

To get more detail about Tekton Operator, please refer to this link.

Let's install Tekton.

$ kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml

Let's install Tekton Trigger.

$ kubectl apply -f https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml

We need to apply one more thing is Interceptors. An Interceptor is a "catch-all" event processor for a specific platform that runs before the TriggerBinding. It allows you to perform payload filtering, verification (using a secret), transformation, define and test trigger conditions, and implement other useful processing.

To get more detail about Interceptors, please refer to this link.

$ kubectl apply -f https://storage.googleapis.com/tekton-releases/triggers/latest/interceptors.yaml

Verify if everything is working before moving onto the next step.

$ kubectl get pods --namespace tekton-pipelines
NAME                                                 READY   STATUS    RESTARTS   AGE
tekton-pipelines-controller-5cf4d4867f-s6tqv         1/1     Running   0          5m21s
tekton-pipelines-webhook-57bfb4b4d7-7jp8c            1/1     Running   0          5m20s
tekton-triggers-controller-7cbd49fbb8-d2bgj          1/1     Running   0          4m40s
tekton-triggers-core-interceptors-5d7f674ccc-d4fq7   1/1     Running   0          2m5s
tekton-triggers-webhook-748fb7778c-mpg94             1/1     Running   0          4m40s

5. Install Tasks, Pipelines and Triggers

Tekton provides as some kind of building blocks as Custom Resources in order to build Cloud Native CI/CD pipelines, and these are the basic ones Tasks and Pipelines. Task defines steps that needs to be executed. A Task is effectively a Pod, while each step is a container within that Pod. Pipeline takes the name(s) and order of execution of TaskRun object(s). A Trigger specifies what happens when the EventListener detects an event. A Trigger specifies a TriggerTemplate, a TriggerBinding, and optionally an Interceptor.

To get more detail about them, please refer to this link for Tekton Primitives and this link for Tekton Triggers.

Let's install them but we need to first clone the repository that involves manifest files for them.

$ git clone https://github.com/developer-guy/manage-your-functions-based-on-cloud-native-ci-cd-using-tekton.git

Before installing them we do some kind of initial set up for the pipelines such as granting necessary permissions by creating RBAC, creating ssh-key to be able commit and push to the repository, creating git source as PersistentVolumeClaim, creating a secrets which contains Docker Hub credentials, and ssh-key information etc.

$ cd manage-your-functions-based-on-cloud-native-ci-cd-using-tekton
$ ssh-keygen -t rsa -b 4096 -C "[email protected]"
# save as tekton / tekton.pub
# add tekton.pub contents to GitHub

$ kubectl apply -f tekton-git-ssh-secret.yaml

$ kubectl apply -f serviceaccount.yaml
$ kubectl create secret docker-registry regcred
  --docker-username=$DOCKER_USERNAME \
  --docker-password=$DOCKER_PASSWORD \
  --docker-email=$DOCKER_EMAIL --docker-server https://index.docker.io/v1/

$ kubectl apply -f git-source-pvc.yaml

Next step, deploying Tasks, Pipelines and Triggers

$ kubectl apply -f tasks/

$ kubectl apply -f pipeline/build-and-deploy-pipeline.yaml

$ kubectl apply -f triggers/

Verify if everything is working before moving onto the next step.

$ kubectl get pods
NAME                                              READY   STATUS             RESTARTS   AGE
el-github-listener-interceptor-7bc945b898-jlst8   1/1     Running            0          68s
hellofunction-7849c4cf8d-zdgm4                    0/1     InvalidImageName   0          52m

el-github-listener-interceptor-7bc945b898-jlst8 this Pod is our EventListener, we should open it to the internet to be able to get events from the Github, now we'll do port-forwarding to make it reachable from localhost, then we'll run inlets-pro to make it reachable from the internet.

But before doing that we need create some sort of secret for Github Webhook. Save this secret because we'll use that when we set up Webhook in Github for our repository.

$ export TEKTON_TUTORIAL_SECRET_TOKEN=${TEKTON_TUTORIAL_SECRET_TOKEN-$(head -c 24 /dev/random | base64)}
$ kubectl create secret generic github-secret --from-literal=secretToken=$TEKTON_TUTORIAL_SECRET_TOKEN
$ echo "TEKTON_TUTORIAL_SECRET_TOKEN: $TEKTON_TUTORIAL_SECRET_TOKEN"
xxxxx

Our event Listener needs to receive HTTP messages from X. Therefore create an inlets tunnel so that Y.

$ kubectl port-forward svc/el-github-listener-interceptor 8080 &

$ inlets-pro http client --token=$TOKEN --url=$WSS --upstream http://127.0.0.1:8080 --license-file $HOME/.inlets/LICENSE --auto-tls=false
2021/05/15 15:07:38 Starting HTTP client. Version 0.8.0-dirty - $TOKEN
2021/05/15 15:07:38 Licensed to: Batuhan Apaydın <[email protected]>, expires: 51 day(s)
2021/05/15 15:07:38 Upstream:  => http://127.0.0.1:8080
2021/05/15 15:07:38 Token: "$TOKEN"
INFO[2021/05/15 15:07:38] Connecting to proxy url="wss://$WSS"

With your $WSS and the $TEKTON_TUTORIAL_SECRET_TOKEN, create webhook from Webhook page under the Settings tab of your repository like the following:

webhook

Now everything is ready to trigger the pipeline, once we update our function code, it'll trigger the pipeline.

To see everything what's happening in your cluster is opening UI's for both Argo CD and Tekton. You can visit localhost:8443 in order to connect Argo CD UI's screen but for Tekton, you need to install Tekton Dashboard.

6. Install Tekton Dashboard

Tekton has another great project called Tekton Dashboard. Tekton Dashboard is a general purpose, web-based UI for Tekton Pipelines and Tekton triggers resources. We can easily install this to our cluster and see what's goin' on our cluster. Run the following command to install Tekton Dashboard and its dependencies:

$ kubectl apply --filename https://storage.googleapis.com/tekton-releases/dashboard/latest/tekton-dashboard-release.yaml

You can simple access to your dashboard with running the following command:

$ kubectl --namespace tekton-pipelines port-forward svc/tekton-dashboard 9097:9097
Forwarding from 127.0.0.1:9097 -> 9097
Forwarding from [::1]:9097 -> 9097

$ open http://localhost:9097

I recommend you to divide screen into two part, one for Argo CD UI and one for Tekton UI to follow the process before making any changes on your repository.

follow_process

7. Test

Finally, let's test our function, to do so, we should access the OpenFaaS Gateway component.

$ kubectl port-forward svc/gateway -n openfaas 8081:8080
Forwarding from 127.0.0.1:8081 -> 8080
Forwarding from [::1]:8081 -> 8080

$ httpie POST http://localhost:8081/function/hellofunction.default message="Hello World"
HTTP/1.1 200 OK
Content-Length: 35
Content-Type: text/plain; charset=utf-8
Date: Fri, 07 May 2021 08:35:44 GMT
X-Call-Id: 0ee19dd7-2c09-4093-9b6e-0755836afb9c
X-Duration-Seconds: 0.004628
X-Start-Time: 1620376544209429100

Body v6: {"message": "Hello World"}

Tadaaaa 🎉😋✅

Join the community

Have you got questions, comments, or suggestions? Join the community on Slack.

Would you like help to set up your OpenFaaS installation, or someone to call when things don't quite go to plan? Our OpenFaaS PRO Subscription plan gives you a say in the project roadmap, a support contact, and access to Enterprise-grade authentication with OIDC.

Acknowledgements

  • Alex Ellis for guidance, editing and providing the diagrams.

References