My CIVO Hackathon Experience about how I deploy my app to the civo Kubernetes cluster
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.
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.
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;
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.go
file as below;
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.