This content originally appeared on Twilio Blog and was authored by Gareth Paul Jones
In this tutorial we’ll walk through scaling your Go application with Kubernetes. We will do this by building an application in Go. We will then get it up and running locally on your development machine, containerize it with Docker, deploy it to a Kubernetes cluster with Minikube, and create a load balancer that will serve as its public facing entry point.
Docker is a containerization tool used to provide applications with a filesystem holding everything they need to run. This ensures that apps will have a consistent run-time environment and behave the same way regardless of where they are deployed. Kubernetes is a cloud platform for automating the deployment, scaling, and management of containerized applications.
Prerequisites
Before you can complete the tutorial, you’ll need a few things.
- Go 1.19
- Kubernetes 1.25
- Minikube 1.26
- You preferred editor or IDE
- Some prior experience with containers and with developing applications in Go would also be ideal
Build a Sample Web Application
First up, you will build a sample application written in Go. Once you containerize this app with Docker, it will serve requests to your server’s IP address port 3000
.
Create a new directory to contain the project files by running the following command in your development workspace:
mkdir my-go-app
cd- my-go-app
We’ll then go ahead and create a service with Gin to respond to HTTP requests.
package main
import (
"fmt"
"time"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.New()
r.SetTrustedProxies([]string{"192.168.1.*"})
// Example pingog request.
r.GET("/", func(c *gin.Context) {
c.String(200, "pong "+fmt.Sprint(time.Now().Unix()))
})
// Example when panic happen.
r.GET("/panic", func(c *gin.Context) {
panic("An unexpected error happen!")
})
// Listen and Server in 0.0.0.0:8080
r.Run(":3000")
}
Next, run the application using the following command. This will compile the code in your main.go
file and run it locally on your development machine.
go run main.go
In the next step we are going to add some logging to our application to make debugging easier.
Add Logging to our Go Application
We’ll use Gin Zap as middleware to our application to handle logging of HTTP requests in our application.
package main
import (
"fmt"
"time"
ginzap "github.com/gin-contrib/zap"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
func main() {
r := gin.New()
logger, _ := zap.NewProduction()
// Add a ginzap middleware, which:
// - Logs all requests, like a combined access and error log.
// - Logs to stdout.
// - RFC3339 with UTC time format.
r.Use(ginzap.Ginzap(logger, time.RFC3339, true))
// Logs all panic to error log
// - stack means whether output the stack info.
r.Use(ginzap.RecoveryWithZap(logger, true))
// Example ping request.
r.GET("/", func(c *gin.Context) {
c.String(200, "pong "+fmt.Sprint(time.Now().Unix()))
})
// Example when panic happen.
r.GET("/panic", func(c *gin.Context) {
panic("An unexpected error happen!")
})
// Listen and Server in 0.0.0.0:8080
r.Run(":3000")
}
In the next step, we will dockerize the application.
Dockerize Your Go Application
Create a new file in the top-level project directory named Dockerfile
# syntax=docker/dockerfile:1
FROM golang:1.19-alpine
WORKDIR /app
COPY go.mod ./
COPY go.sum ./
RUN go mod download
COPY *.go ./
RUN go build -o /main
EXPOSE 8080
CMD [ "/main" ]
Build the docker image
docker build -t <your_user_name>/my-go-app
Next use the following command to create and start the container.
docker run -it -p 3000:3000 <your_user_name>/my-go-app
When you deploy your containerized application to your Kubernetes cluster, you’ll need to pull the image from a centralized location. So you need to first push your newly created image to your Docker Hub image repo. However, before you can do that, you first have to log in to Docker Hub.
Run the following command to do this:
docker login
After logging in push your new image up to Docker Hub using the docker push command
docker push <your_user_name>/my-go-app
Now that we have pushed the image to a central location we are ready to deploy it to your Kubernetes cluster.
Start your local kubernetes cluster
We’ll use minikube which implements a local Kubernetes cluster on macOS, Linux, and Windows. Run the following command on your command line to begin:
minikube start
If you're interested, you can view a Kubernetes dashboard via the minikube dashboard
command.
Create a Deployment
One kind of Kubernetes object, known as a deployment, is a set of identical, indistinguishable pods, where a pod is a grouping of one or more containers which are able to communicate over the same shared network and interact with the same shared storage.
A deployment runs more than one replica of the parent application at a time and automatically replaces any instances that fail ensuring that your application is always available to serve user requests.
In this step, you’ll create a Kubernetes object description file known as a manifest for the deployment. The manifest will contain all the configuration details needed to deploy your Go app to your cluster.
Begin by creating a deployment file in the root of your directory named deployment.yaml
.
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-go-app
spec:
replicas: 5
selector:
matchLabels:
name: my-go-app
template:
metadata:
labels:
name: my-go-app
spec:
containers:
- name: application
image: gjonestwilio/my-go-app:latest
imagePullPolicy: IfNotPresent
envFrom:
- secretRef:
name: test-secret
ports:
- containerPort: 3000
Next apply your new deployment using this command:
kubectl apply -f deployment.yml
In the next step you’ll create another kind of Kubernetes object, a service, which will manage how you access the pods that exist in your deployment. This service will create a load balancer which will then expose a single IP address. Requests to this IP address will be distributed to the replicas in your deployment. This service will also handle port forwarding rules so that you can access your application over HTTP.
Create a Service
Now that you have a successful Kubernetes deployment, you’re ready to expose your application to the outside world. In order to do this you’ll need to define another kind of kubernetes object: a service. This service will expose the same port on all of your cluster’s nodes. Your nodes will then forward any incoming traffic on that port to the pods running your application.
Create a new file called service.yml
---
apiVersion: v1
kind: Service
metadata:
name: my-go-app-service
spec:
type: LoadBalancer
ports:
- name: http
port: 3001
targetPort: 3000
selector:
name: my-go-app
After adding these lines, save and close the file. Following that, apply this service to your Kubernetes cluster by, once again, using the kubectl
apply command:
kubectl apply -f service.yml
This command will apply the new Kubernetes service as well as create a load balancer. This load balancer will serve as the public-facing entry point to your application running within the cluster.
As we are using a custom Kubernetes Cluster with minikube, there is no load balancer integrated (unlike with AWS or Google Cloud) so we need to tunnel requests. You can do this with minikube tunnel
command
To view the application, you will need the new load balancer’s IP address. Find it by running the command:
kubectl get services
The load balancer will take in the request on the port 80 and forward it to one of the pods running within your cluster.
Conclusion
Congratulations! With that you’ve created a Kubernetes service coupled with a load balancer, giving you a single, stable entry point to your application.
Gareth Paul Jones is a Group Product Manager for our Developer Experience (DX) Team. He's invested in helping solve large scale software problems. When he is not staring at screens, he enjoys family time with his wife and daughter. He can be reached at gjones [at] twilio.com.
This content originally appeared on Twilio Blog and was authored by Gareth Paul Jones
Gareth Paul Jones | Sciencx (2022-10-17T18:09:16+00:00) Scaling your Go Application with Kubernetes. Retrieved from https://www.scien.cx/2022/10/17/scaling-your-go-application-with-kubernetes/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.