Get Started with Keptn Development locally - Part 2

Meha Bhalodiya
7 min readAug 9, 2022

--

In the last article, I’ve shown you how to install a Kubernetes cluster locally on your machine and then install Keptn into it or actually what we did is we installed Keptn control plane into it and in this article, we’re going to make use of this to do some development using Keptn or actually developing Keptn.

For this, you will need an IDE of your choice. I often use Visual Studio Code. In addition to that, you should also have a skaffold installed. I will quickly show you how to do that.

Note: The below command is for Linux x86_64 (amd64).

curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64 && \
sudo install skaffold /usr/local/bin/

I will just do that in my terminal (it wants my password; should be fine),

oem@meha:~$ curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64 && \
> sudo install skaffold /usr/local/bin/
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 63.1M 100 63.1M 0 0 308k 0 0:03:29 0:03:29 --:--:-- 686k
[sudo] password for oem:

Now I should have the skaffold installed.

oem@meha:~$ skaffold version
v1.39.1

We will see how the skaffold is being used later in this article.

The next thing you want to verify is that you are connected to your Keptn cluster and that it’s up and running using keptn status as we’re connected to our local cluster; it’s printing the IP address. So everything seems to be working fine!

oem@meha:~$ keptn status
Starting to authenticate
Successfully authenticated against http://localhost:8080/api
Bridge URL: http://localhost:8080/bridge

Now, what you really want is you want to clone (assuming you have some familiarity with GitHub) the Keptn repository so. I usually clone it using HTTPS, you can also clone it using SSH, just use whatever you usually do.

oem@meha:~$ git clone https://github.com/keptn/keptn.git

As you can see cloning will take quite some time and you need a good internet connection because the repository is rather big. Now we can change the directory into the Keptn folder and you just get the whole thing here like the same on a repo by ls -l command.

oem@meha:~$ cd keptn
oem@meha:~/keptn$ ls -l
total 304
-rw-rw-r-- 1 oem oem 2174 Jun 21 23:00 ADOPTERS.md
drwxrwxr-x 12 oem oem 4096 Jul 26 13:46 api
drwxrwxr-x 4 oem oem 4096 Jul 26 13:46 approval-service
drwxrwxr-x 2 oem oem 4096 Jun 21 23:00 assets
drwxrwxr-x 7 oem oem 4096 Jul 26 13:46 bridge
-rw-rw-r-- 1 oem oem 130276 Jul 26 13:46 CHANGELOG.md
drwxrwxr-x 5 oem oem 4096 Jul 26 13:46 cli
-rw-rw-r-- 1 oem oem 1833 Jul 26 13:46 codecov.yml
-rw-rw-r-- 1 oem oem 69 Jun 21 23:00 CODE_OF_CONDUCT.md
-rw-rw-r-- 1 oem oem 1715 Jun 21 23:00 CODEOWNERS
drwxrwxr-x 2 oem oem 4096 Jul 26 13:46 configuration-service
-rw-rw-r-- 1 oem oem 13742 Jul 26 13:46 CONTRIBUTING.md
-rw-rw-r-- 1 oem oem 5112 Jul 26 13:46 CONTRIBUTORS.md
drwxrwxr-x 5 oem oem 4096 Jul 26 13:46 distributor
drwxrwxr-x 3 oem oem 4096 Jun 21 23:00 docs
drwxrwxr-x 2 oem oem 4096 Jul 26 13:46 gh-actions-scripts
-rw-rw-r-- 1 oem oem 4190 Jun 21 23:00 GOVERNANCE.md
drwxrwxr-x 8 oem oem 4096 Jul 26 13:46 helm-service
drwxrwxr-x 4 oem oem 4096 Jul 26 13:46 installer
drwxrwxr-x 6 oem oem 4096 Jul 26 13:46 jmeter-service
-rw-rw-r-- 1 oem oem 11347 Jun 21 23:00 LICENSE
drwxrwxr-x 5 oem oem 4096 Jul 26 13:46 lighthouse-service
-rw-rw-r-- 1 oem oem 1683 Jun 21 23:00 MAINTAINERS
drwxrwxr-x 10 oem oem 4096 Jul 26 13:46 mongodb-datastore
-rw-rw-r-- 1 oem oem 4751 Jul 26 13:46 README.md
drwxrwxr-x 2 oem oem 4096 Jun 21 23:00 releasenotes
drwxrwxr-x 5 oem oem 4096 Jul 26 13:46 remediation-service
drwxrwxr-x 11 oem oem 4096 Jul 26 13:46 resource-service
drwxrwxr-x 6 oem oem 4096 Jul 26 13:46 secret-service
-rw-rw-r-- 1 oem oem 173 Jun 21 23:00 SECURITY.md
drwxrwxr-x 14 oem oem 4096 Jul 26 13:46 shipyard-controller
drwxrwxr-x 2 oem oem 4096 Jun 21 23:00 specification
drwxrwxr-x 11 oem oem 4096 Jul 26 13:46 statistics-service
drwxrwxr-x 6 oem oem 4096 Jun 21 23:00 test
-rw-rw-r-- 1 oem oem 1753 Jun 21 23:00 VERSIONING.MD
-rw-rw-r-- 1 oem oem 6 Jul 26 13:46 VERSION.txt
drwxrwxr-x 5 oem oem 4096 Jul 26 13:46 webhook-service

If you don’t want to develop straight away from the keptn folder, you need to go into a separate folder. So for instance, let’s say you want to fix a bug in the lighthouse-service or you implement the feature in lighthouse-service .

What you want to do is, you want to open your IDE in that folder. So this is really a mono repo and you should open the IDE in the folder that you’re at and I’m using Visual Studio Code. I’m just opening it using:

oem@meha:~/keptn$ cd lighthouse-service/
oem@meha:~/keptn/lighthouse-service$ code .

Spoiler Alert: I do have some plugins already installed.

I’m using some pre-installed plugins. Basically, whenever you open a source code file, it will suggest to you; Hey! there is a plug-in for Go you should install it or Hey! there’s a plug-in for Dockerfile you should install.

Now what I want to do is, I want to change something in main.go , and let’s just say (inside the main() function):

fmt.Printf("We are starting with Keptn Development.")

Note: Apparently fmt is not imported in main.go. So yeah, it will auto import it. However, that’s an advantage of Visual Studio Code with the proper plugins.

Now how do we actually deploy this change to our Kubernetes cluster where Keptn is running? So, if you look at the cluster in the namespace keptn ,

oem@meha:~$ kubectl get pods -n keptn
NAME READY STATUS RESTARTS AGE
api-gateway-nginx-575b669549-vvlwx 1/1 Running 0 20m
api-service-587459fb-d2zn6 1/1 Running 0 20m
approval-service-694569596-wrpg7 1/1 Running 0 20m
bridge-fb8564c8f-x27nf 1/1 Running 0 20m
helm-service-59c88584c9-gkbbs 2/2 Running 0 20m
jmeter-service-77fd6d7967-b5h6v 2/2 Running 0 20m
keptn-mongo-74bf4c476f-789mr 1/1 Running 0 20m
keptn-nats-0 2/2 Running 0 20m
lighthouse-service-89c5687bb-lsfkm 1/1 Running 0 20m
mongodb-datastore-667685bc5d-bqwg7 1/1 Running 0 20m
remediation-service-65df9f98bd-5nd52 1/1 Running 0 20m
resource-service-7c98c668c-w6snh 1/1 Running 0 20m
secret-service-7798f4f484-xfvk7 1/1 Running 0 20m
shipyard-controller-859bcb5dd5-2jp46 1/1 Running 0 20m
statistics-service-7b995b9477-hdh2h 2/2 Running 0 20m
webhook-service-766b556b87-w5d5b 1/1 Running 0 20m

there is a lighthouse-service and it has been running for 20 minutes and this is the part that we want to replace. Now, you could build Dockerfile and deploy it to some registry and then hope that everything works, but I think this is not needed!

You could just use a skaffold. What skaffold is doing is, it will build the Dockerfile that is linked (see the code snippet below) and it will deploy it using kubectl by deploying the manifest in the deploy/service.yaml .

# skaffold.yamlapiVersion: skaffold/v2beta22
kind: Config
build:
local:
useBuildkit: true
artifacts:
- image: keptndev/lighthouse-service
docker:
dockerfile: Dockerfile
target: production
deploy:
kubectl:
defaultNamespace: keptn
manifests:
- deploy/service.yaml

You should be able to just go into your terminal and execute,

skaffold run --tail

Note: Use --tail so you get the log output.

It starts building the Dockerfile . Further, it will try to deploy it to our cluster.

What we now need is the lighthouse-service image that we’ve built to be up and running because what I want is, I want to see our “We are starting with Keptn Development.” message. You can have a look at a snapshot of my terminal below:

oem@meha:~/keptn/lighthouse-service$ skaffold run --tail
Generating tags...
- keptndev/lighthouse-service -> keptndev/lighthouse-service:0.16.0-347-g2b39c6fba-dirty
Checking cache...
- keptndev/lighthouse-service: Found Locally
Starting test...
Tags used in deployment:
- keptndev/lighthouse-service -> keptndev/lighthouse-service:d60d51a57e844e32ff2d9483a60864e862af0c47b049d39f62e8c72efa4d448a
Starting deploy...
- deployment.apps/lighthouse-service configured
- service/lighthouse-service configured
Waiting for deployments to stabilize...
- keptn:deployment/lighthouse-service: waiting for rollout to finish: 1 old replicas are pending termination...
- keptn:deployment/lighthouse-service is ready.
Deployments stabilized in 16.116 seconds
Press Ctrl+C to exit
[lighthouse-service] time="2022-08-09T11:28:05Z" level=info msg="Container termination triggered, starting graceful shutdown and cancelling context"
[lighthouse-service] time="2022-08-09T11:28:05Z" level=info msg="ControlPlane cancelled via context. Unregistering..."
[lighthouse-service] time="2022-08-09T11:28:05Z" level=info msg="Stopping subscription source..."
[lighthouse-service] time="2022-08-09T11:28:05Z" level=info msg="Stopping event source..."
[lighthouse-service] time="2022-08-09T11:28:05Z" level=info msg="Wait for all event handlers to finish"
[lighthouse-service] time="2022-08-09T11:28:05Z" level=info msg="All event handlers done - ready to shut down"
[lighthouse-service] time="2022-08-09T11:28:05Z" level=info msg="Cleaning up event source..."
[lighthouse-service] time="2022-08-09T11:28:05Z" level=info msg="Disconnected from NATS"
[lighthouse-service] time="2022-08-09T11:28:05Z" level=info msg="Waiting for evaluation event handlers to finish"
[lighthouse-service] time="2022-08-09T11:28:10Z" level=info msg="All evaluation handlers finished - exiting"
[lighthouse-service] We are starting with Keptn Development.

Yeah, that is how I just deployed a container and that should be working for you as well. Now it will stay until and unless we didn’t say it to clean up but the skaffold can be configured to clean up afterward.

It has worked so far; so what you would do now is you could push your change into your git repo and then make a pull request and yeah some people will review it and give you comments about it and yeah, this is how you would develop but what if you don’t want to develop a Keptn core service.

What if you want to develop an additional service? Let’s say you want to create an integration that interacts with terraform, what it interacts with Prometheus, or anything else, then this is the wrong service for you to look at!

What you would have to look at then is Keptn’s job executor service! Job executor service allows you to just create customizable tasks with Keptn as Kubernetes jobs by specifying an event that you want to listen to and when this event is received and much more.

However, this is a topic for another article. Alright, if you have any questions feel free to comment down below.

Reference: https://youtu.be/AQM-HQoftD4
Shoutout to Christian Kreuzberger for being so supportive!

--

--

Meha Bhalodiya

Software Quality Engineer at RedHat (OpenShift Container Platform) | K8s v1.31 Branch Manager & v1.28 CI Signal Lead | Ex - GSoC'22 & LFX'22