My CIVO Hackathon Experience about how I deploy my app to the civo Kubernetes cluster

Afzal Ansari
6 min readDec 10, 2021

--

Hello everyone! I’m Afzal, an Open Source Enthusiasts by passion — OS contributor at Meshery. I am going to share my experiences of the CIVO-Hackathon with you all. Before I start writing my experiences in my words, I would like to tell about my journey towards DevOps.
When I first heard the word Kubernetes, I was overwhelming to find related guides and tutorial to enrich my knowledge here and there to get into it. I stepped into open source projects under CNCF, where I didn’t even know what the ecosystem around the project is. I was much curious then. Next, I delved into it seriously for two weeks and understood the concept of Kubernetes beyond Docker in practice from katakoda labs, Tech with Nana YT and later on CIVO academy and other tutorials.

Project Architecture for our demonstration

About the project

In this post, I will describe how to develop a REST API in Go (Golang). More specifically, I will show how to build a REST API into Go Web framework, deploy it in a docker container, and finally publish it on CIVO cluster for production.

I will discuss the sequence of a simple use case implemented with gin gonic framework. Here, I have to build an HTTP GET/POST request API to allow the user to get the list of the article’s details which includes its id, article Name, etc.

So, I’m going to implement RESTful API services by using “Gin Gonic Framework”. There are also other HTTP web frameworks that offer HTTP request handler functionality like GO kit, GorillaMux, GoBuffalo etc. Gin is one of the incredible frameworks of Go, which is lightweight and massively fast. The interesting feature of Gin is that it provides custom version of HttpRouter which makes the API routes extremely fast, than that of other Go frameworks.

The web frameworks mentioned above are open source projects that allow us to build, configure and deploy API services(microservices) (In our case, GO Gin Gonic).

With this framework, we can quickly build, configure and deploy resources within a few commands. We can create and store our API’s and configuration in a centralized repository as many as possible.

In this article, we’re going to build a microservice named as artcleInfo API service built with Golang using our own framework.

The code for this article can be found here: https://github.com/afzal442/civo-hack/artcleInfoAPI

Getting Started

To get started, I would assume you have GOlang already installed and configured locally and the corresponding Go package. For more details, please follow the official docs. Once we set up the requirements, we will proceed with the next steps to play around GO gin pkg.

So, let’s install plugins and libraries step by step;

The below commands will clone basic templates for you to work with the API after you clone the repo. Plz, ignore the docker file and other manifest files for now.

After that install the dependencies as follows; this allows you to update the pkg installed.

go mod download

go mod tidy

Your template will look as below.

web-api directory contents

Let’s dive into main.go file and create another file inside our `handlers` dir and `routes` dir.

Copy the contents into that folder and edit around the main.go containing our routes initialization function call, routes.go containing routes path along with HTTP requests, handlers.go containing our REST API implementation and except other `.yaml` files as below;

This contains our routes initialization function call and runs the server.
This router is responsible for routing paths according to various HTTP requests.

The below are the endpoints we will use to create, update, read and delete the articleInfo data.

GET articles-api → Retrieves all the articles infoGET articles-api/{id} → Retrieve the single article's infoPOST articles-api → Add new articles infoPUT articles-api/{id} → Update the articles infoDELETE articles-api/{id} → Delete the single article's info

Let’s look at the handlers.gofile as below;

This handler is responsible for taking various HTTP requests and processing them accordingly

Let’s first run the output locally;

go run main.go

While developing locally or for dev environment

CGO_ENABLED=0 go build -o bin/server

For building to deploy to production

export GIN_MODE=release && CGO_ENABLED=0 go build -o bin/server

Now, let’s move forward and see the output if it works as expected

$ curl http://localhost:8080/articles-api

[{“id”:”1",”title”:”Let’s GO”,”author”:”John Doe”,”price”:56.99,”review”:”Very Good”,”rating”:4},{“id”:”2",”title”:”the three mistakes of my life”,”author”:”Chetan”,”price”:17.99,”review”:”Good”,”rating”:3.5},{“id”:”3",”title”:”3idiots”,”author”:”Bhagat”,”price”:39.99,”review”:”Excellent”,”rating”:5}]

$ curl http://localhost:8080/articles-api/1{“id”: “2”,“title”: “the three mistakes of my life”,“author”: “Chetan”,“price”: 17.99,“review”: “Good”,“rating”: 3.5}

The above API points firstly, list the article stored and secondly, query the list of articles to get the details based on its ID.

Dockerize the backend service into a container

Build the image of an application

$ docker build -t afzal442/articleinfoapi:v1 .

The above command will build an image of the above API service into a docker container and ship/push them to the docker hub repository. We can run the same command multiple times if any changes are required.

Run the image into a container

$ docker run -p 5000:8080 afzal442/articleinfoapi:v1

The above command will run the application locally in port 5000.

Configuring Kubernetes Cluster

To configure, I suggest first going through official docs and blogs from CIVO on how to set up our K8s cluster on top of Civo Kubernetes cluster using various tools.

For my app to be deployed, I create 3 nodes to the running Civo Kubernetes cluster. I delve into how to manage deployment, service and ingress manifest files further. For more details about that, again I would say you can go through that.

$ kubectl describe deployment/web4api-deploymentName: web4api-deployment
Namespace: default
CreationTimestamp: Fri, 10 Dec 2021 04:56:11 +0530
Labels: app=web4api
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=web4api
Replicas: 2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=web4api
Containers:
web4api:
Image: afzal442/web4api:v1
Port: 5000/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
— — — — — — — —
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: web4api-deployment-779d6b6768 (2/2 replicas created)
Events:
Type Reason Age From Message
— — — — — — — — — — — — -
Normal ScalingReplicaSet 6m34s deployment-controller Scaled up replica set web4api-deployment-779d6b6768 to 2

Here you can see that we created the Deployment, it created a ReplicaSet (web4api-deployment) and scaled it up to 2 replicas directly. If you want to update the Deployment, Kubernetes will be spun up, will create a new ReplicaSet and scale it up/down.

Our application is set to run on a subdomain called `webapi`. If you point your browser at http://webapi.{your-cluster-id}.k8s.civo.com/articles, you will find the API running up successfully.

Let’s look at our API running on our CIVO Kubernetes cluster.

$ curl http://webapi.your-cluster-id.k8s.civo.com/articles/1{“id”: “1”,“title”: “Let’s GO”,“author”: “John Doe”,“price”: 56.99,“review”: “Very Good”,“rating”: 4}

To my surprise, when I first tried to deploy my app, I learnt a lot about why deployment is needed when we have a docker container running already, what’s the reason behind the use of service and ingress files. What the purpose of k3s cluster behind k8s cluster is and so forth.

The experience with the CIVO platform is amazing when you first deploy your app and control or ssh into that. Even you can make use of the marketplace features and their own CLI tool to configure clusters, nodes, etc.

What’s next!

I am looking forward to adding more API endpoints to make use of HTTP requests persistently and integrating with MySQL DB service.

--

--