Deploying a Golang Application to Vultr Kubernetes Engine

Introduction

Efficient management and orchestration of containerized applications is important when working with Kubernetes clusters. Golang is a programming language for building scalable and high-performance applications. Its simplicity, efficiency, and strong concurrency support make it ideal for developing microservices and containerized applications. By harnessing the power of Kubernetes clusters, Golang applications run optimally efficiently, with scalability and resilience in a production environment.

This article explains how to deploy a Golang containerized application on a Vultr Kubernetes Engine (VKE) engine. To efficiently manage the application, you will containerize and push the image using the Vultr Container Registry.

Prerequisites

Before you begin:

  • Deploy a Vultr Kubernetes Engine (VKE) cluster with at least three nodes.
  • Deploy a Vultr OneClick Docker instance to use as the management system.
  • Access the server using SSH as a non-root user with sudo privileges.
  • Install and Configure Kubectl to access the cluster.
  • Create a Vultr Container Registry to store Docker images.

Create a Golang Application

  1. Install the latest Golang packageCONSOLECopy$ sudo apt install golang
  2. Create a new directory to store your application files.CONSOLECopy$ mkdir app
  3. Switch to the new directory.CONSOLECopy$ cd app
  4. Create a Golang main application file using a text editor such as Nano.CONSOLECopy$ nano main.go
  5. Add the following contents to the file.GOCopypackage main import ( “fmt” “net/http” ) func homePage(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, “This is my Go App!”) } func setupRoutes() { http.HandleFunc(“/”, homePage) } func main() { fmt.Println(“Go Web App Started on Port 8000”) setupRoutes() http.ListenAndServe(“:8000”, nil) } Save and close the file.The above application code performs the following functions:
    • import: Imports the fmt package for formatting and printing, and the net/http package to handle HTTP requests and responses.
    • func homePage: Defines a new HTTP handler. It takes two parameters: w, which is an http.ResponseWriter used to write the response, and r, which is an http.Request that contains information about the incoming request. In this case, it writes the string This is my Go App! to the response writer.
    • func setupRoutes: Sets up the application’s routes. In the application, it associates the root ("/") path with the homePage handler function.
    • fmt.Println("Go Web App Started on Port 8000"): Prints a message to the console indicating that the Go web application has started.
    • setupRoutes(): Calls the setupRoutes function to configure the application’s routes.
    • http.ListenAndServe(":8000", nil): Starts the HTTP server that actively listens for connections on the defined port 8000. The second parameter, nil, specifies that the default server is used. This function blocks interferences and allows the HTTP server to continue running until an error occurs or the program is manually terminated.
  6. Run the Golang application as a background task.CONSOLECopy$ go run main.go & Output:Go Web App Started on Port 8000
  7. Using the Curl utility, test access to your server port 8000 to verify that the application runs correctly.CONSOLECopy$ curl 127.0.0.1:8000 Output:This is my Go App!
  8. View the Golang application Job ID.CONSOLECopy$ jobs
  9. Kill the application Job ID to stop the background process. For example, Job ID 1CONSOLECopy$ kill %1

Build the Golang Application Image

  1. Create a Dockerfile within the application directory.CONSOLECopy$ nano Dockerfile
  2. Add the following configurations to the file.DOCKERFILECopy# Latest golang image on apline linux FROM golang:1.12.0-alpine3.9 # Work directory RUN mkdir /app ADD . /app WORKDIR /app # Installing dependencies RUN go build -o main . # Starting our application CMD [“/app/main”] The above Docker file configuration includes the following key components:
    • FROM golang:1.12.0-alpine3.9: Specifies the application image to use the official Golang image version 1.12.0 based on Alpine Linux version 3.9 to keep the overall image size small.
    • RUN mkdir /app: Creates a new directory named /app in the Docker image to use as the working directory for subsequent commands.
    • ADD . /app: Copies the contents of the local application directory to the image /app directory.
    • WORKDIR /app: Sets the working directory to /app.
    • RUN go build -o main .: Runs the go build command to compile the Go application. The -o main flag specifies that the compiled binary should be named main. The . at the end of the command instructs the compiler to run the source code from the current directory.
    • CMD ["/app/main"]: Sets the command that executes when a container based on this image runs. /app/main specifies the path to the executable binary within the /app directory.
  3. Build the Docker image.CONSOLECopy$ docker build -t go-app .
  4. When successful, view the created image and its size.CONSOLECopy$ docker images Output:REPOSITORY TAG IMAGE ID CREATED SIZE go-app latest 149ea0f60676 About a minute ago 355MB golang 1.12.0-alpine3.9 2205a315f9c7 4 years ago 347MB
  5. Start a new container to test the image locally using Docker.CONSOLECopy$ docker run -dit -p 8000:8000 go-app:latest
  6. View the list of running Docker containers to verify that the new container is running correctly on port 8080.CONSOLECopy$ docker ps Output:CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 59b3a6a67bf5 go-app:latest "/app/main" 22 seconds ago Up 21 seconds 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp beautiful_panini

Push Docker Image to Vultr Container Registry

To use your Golang container image in a Vultr Kubernetes Engine (VKE) cluster, push it to your Vultr Container Registry as described in the steps below.

  1. Log in to the Vultr Container Registry using your repository username and password.CONSOLECopy$ docker login https://sjc.vultrcr.com/golangregistry -u vcr-user -p vcr-password Replace golangregistryvcr-user and vcr-password with your actual values displayed in the registry overview section.
  2. Tag the Docker Image with your Vultr Container Registry repository path.CONSOLECopy$ docker tag go-app:latest sjc.vultrcr.com/golangregistry/go-app:latest
  3. View the list of Docker Images available on your server.CONSOLECopy$ docker images Output:REPOSITORY TAG IMAGE ID CREATED SIZE go-app latest 149ea0f60676 7 minutes ago 355MB sjc.vultrcr.com/golangregistry/go-app latest 149ea0f60676 7 minutes ago 355MBIn the above output, two container images are listed. This means you can push the tagged sjc.vultrcr.com/golangregistry/go-app image to your Vultr Container Registry.
  4. Push your go-app Docker image to the Vultr Container Registry.CONSOLECopy$ docker push sjc.vultrcr.com/golangregistry/go-app:latest

Deploy the Golang Application to your VKE Cluster

  1. Create a new deployment resource file deployment.yaml.CONSOLECopy$ nano deployment.yaml
  2. Add the following configurations to the file.YAMLCopykind: Deployment apiVersion: apps/v1 metadata: name: go-app spec: replicas: 2 selector: matchLabels: app: go-app template: metadata: labels: app: go-app spec: containers: – name: go-app image: sjc.vultrcr.com/golangregistry/go-app:latest ports: – containerPort: 8000 Save and close the file.Below is what the above Deployment resource directives represent:
    • name: go-app: Sets the name of the deployment to go-app.
    • spec: Describes the desired state of the deployment.
    • replicas: 2: Sets the number of replica Pods to 2.
    • selector: Defines how the deployment identifies the Pods to manage. In the configuration, it uses labels to match Pods with the label app: go-app.
    • template: Describes the Pod template used to create new Pods managed by the Deployment.
    • spec: Specifies the specification of the Pods created from this template.
    • containers: Describes the containers within the Pod.
    • name: go-app: Sets the name of the container to go-app.
    • image: sjc.vultrcr.com/golangregistry/go-app:latest: Specifies the image to use with the go-app container, sjc.vultrcr.com/golangregistry/go-app uses the latest image that uses the latest tag.
    • ports: Specifies the ports exposed by the container.
  3. Apply the deployment to your cluster.CONSOLECopy$ kubectl apply -f deployment.yaml
  4. View the deployment status and verify that it’s available.CONSOLECopy$ kubectl get deployment Output:NAME READY UP-TO-DATE AVAILABLE AGE go-app 2/2 2 2 40s
  5. Verify the pods created by your deployment.CONSOLECopy$ kubectl get pods Output:NAME READY STATUS RESTARTS AGE go-app-67b879b97-6zkxd 1/1 Running 0 37s go-app-67b879b97-vbq2r 1/1 Running 0 37s

As displayed in the above output, the Pods follow the go-app naming scheme specified in the Deployment configuration, for example, the first Pod name is go-app-67b879b97-6zkxd.

  1. View the running Pod logs to verify the container output.CONSOLECopy$ kubectl logs go-app-67b879b97-6zkxd Output:Go Web App Started on Port 8000

Expose the Golang Application for External Access

After deploying your Golang application to the VKE cluster, use an Ingress Controller or create a Service resource configuration to expose your application for external access. In this case, VKE uses a linked Vultr Load Balancer resource and associates it with your cluster Service resource. This allows external users to access your application using the Load Balancer public IP Address.

  1. Create a new Service resource file service.yaml.CONSOLECopy$ nano service.yaml
  2. Add the following configurations to the file.YAMLCopyapiVersion: v1 kind: Service metadata: name: load-balancer labels: app: go-app spec: type: LoadBalancer ports: – port: 80 targetPort: 8000 protocol: TCP nodePort: 32000 selector: app: go-app Save and close the file.Below is what the above configuration values represent:
    • name: load-balancer: Sets the service name to load-balancer.
    • type: LoadBalancer: Specifies that the service is a Load Balancer resource. This results in the creation of a Vultr Load Balancer that forwards traffic to the target cluster resources.
    • port: 80: Specifies the external access port used by the service to handle connections. Incoming traffic requests on this cluster port are forwarded to the Service.
    • targetPort: 8000: The running Pods port to forward incoming traffic.
    • protocol: TCP: Specifies the protocol used for the Service, in this case, TCP.
    • nodePort: 32000: Specifies the node port for the Service. NodePort is a way to expose the Service on each node’s IP at the specified port.
    • selector: Defines how the Service discovers the Pods to target and forward traffic. In this case, it targets Pods with the label app: go-app.
  3. Apply the configuration to your cluster.CONSOLECopy$ kubectl apply -f service.yaml
  4. Wait for at least 3 minutes and view the cluster service resources to verify the new Load Balancer external IP address.CONSOLECopy$ kubectl get svc Your output should look like the one below:NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE go-app LoadBalancer 10.108.248.240 192.168.0.11 80:32000/TCP 3m38s kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6m20s
  5. Using a web browser such as Chrome, visit your Load Balancer IP to access your Golang application. Replace the example IP 192.168.0.11 with your actual Load Balancer external IP address.http://192.168.0.11Golang Dashboard

Conclusion

You have explored the end-to-end process of deploying a Golang application to a Vultr Kubernetes Engine cluster. Each step is important for a successful deployment allowing you to build containerized production applications you can push to the Vultr Container Registry for deployment in your cluster.

Introduction Efficient management and orchestration of containerized applications is important when working with Kubernetes clusters. Golang is a programming language for building scalable and high-performance applications. Its simplicity, efficiency, and strong concurrency support make it ideal for developing microservices and containerized applications. By harnessing the power of Kubernetes clusters, Golang…

Introduction Efficient management and orchestration of containerized applications is important when working with Kubernetes clusters. Golang is a programming language for building scalable and high-performance applications. Its simplicity, efficiency, and strong concurrency support make it ideal for developing microservices and containerized applications. By harnessing the power of Kubernetes clusters, Golang…

Leave a Reply

Your email address will not be published. Required fields are marked *