DEV Community

Dsysd Dev
Dsysd Dev

Posted on • Updated on

Deploying a Go Application with NATS Messaging on Kubernetes

We will go through the step-by-step process, from writing the deployment YAML files to building the Docker image and finally deploying the application on Kubernetes.
Prerequisites

Before we begin, make sure you have the following prerequisites in

Docker installed on your machine.
Minikube and kubectl installed for setting up a local Kubernetes cluster.

Step 1

Writing the Deployment YAML Files

To start, we need to define the deployment YAML files for our Go application and NATS messaging system. Let’s create the following YAML files:

  1. app-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-go-img-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app-go
  template:
    metadata:
      labels:
        app: app-go
    spec:
      containers:
        - name: app-go-container
          image: app-go
          imagePullPolicy: Never
          ports:
            - containerPort: 8080
Enter fullscreen mode Exit fullscreen mode
  1. nats-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nats
spec:
  replicas: 1
  strategy: {}
  selector:
    matchLabels:
      app: nats
  template:
    metadata:
      labels:
        app: nats
    spec:
      containers:
        - name: nats
          image: nats:2.7.0-alpine
          ports:
            - containerPort: 4222
              targetPort: 4222
Enter fullscreen mode Exit fullscreen mode
  1. nats-service.yaml:
apiVersion: v1
kind: Service
metadata:
  name: nats-service
spec:
  selector:
    app: nats
  ports:
    - name: client
      port: 4222
      targetPort: 4222
      protocol: TCP
Enter fullscreen mode Exit fullscreen mode

Step 2

Writing the Go Application Code

Next, we need to write the code for our Go application. Create a file named main.go and add the following code:

package main

import (
 "fmt"
 "log"
 "os"
 "time"

 "github.com/nats-io/nats.go"
)

func main() {

 url := os.Getenv("NATS_URL")
 if url == "" {
  url = nats.DefaultURL

  // url = "nats://nats-service.default.svc.cluster.local:4222"
  // works fine in case of interpod communication

  // another way is to use the service-url directly
  url = "nats-service:4222"
 }

 nc, err := nats.Connect(url)
 if err != nil {
  log.Fatalln(err)
 }

 defer nc.Drain()

 nc.Publish("greet.joe", []byte("hello"))

 sub, _ := nc.SubscribeSync("greet.*")

 msg, _ := sub.NextMsg(10 * time.Millisecond)
 fmt.Println("subscribed after a publish...")
 fmt.Printf("msg is nil? %v\n", msg == nil)

 nc.Publish("greet.joe", []byte("hello"))
 nc.Publish("greet.pam", []byte("hello"))

 msg, _ = sub.NextMsg(10 * time.Millisecond)
 fmt.Printf("msg data: %q on subject %q\n", string(msg.Data), msg.Subject)

 msg, _ = sub.NextMsg(10 * time.Millisecond)
 fmt.Printf("msg data: %q on subject %q\n", string(msg.Data), msg.Subject)

 nc.Publish("greet.bob", []byte("hello"))

 msg, _ = sub.NextMsg(10 * time.Millisecond)
 fmt.Printf("msg data: %q on subject %q\n", string(msg.Data), msg.Subject)


}
Enter fullscreen mode Exit fullscreen mode

This code connects to the NATS messaging system, publishes and subscribes to messages, and demonstrates basic functionality.
Step 3

Building the Docker Image

Now, let’s build the Docker image for our Go application. We will use a multi-stage Dockerfile to ensure a lightweight and optimized image. Create a file named Dockerfile and add the following code:

### Stage 1: Build the Go binary
FROM golang:1.17 AS builder

### Set the working directory inside the container
WORKDIR /app

### Copy the Go modules files and download dependencies

COPY go.mod go.sum ./
RUN go mod download


### Copy the application source code to the container
COPY . .

### Build the Go application

RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .

# Stage 2: Create the final image
FROM alpine:latest

# Set the working directory inside the container
WORKDIR /app

# Copy the Go binary from the builder stage
COPY --from=builder /app/main .

# Expose the port that the application listens on
EXPOSE 8080

# Define the command to run the application when the container starts
CMD ["./main"]
Enter fullscreen mode Exit fullscreen mode

To build the image on a Mac, execute the following command:

docker buildx build --platform linux/amd64 -t app-go-container .
Enter fullscreen mode Exit fullscreen mode

After doing everything, your folder structure should look like this

Step 4

Deploying the Application on Kubernetes

With our Docker image ready, let’s deploy the application on Kubernetes using Minikube.

Ensure Minikube is running by executing the following command:

minikube start
Enter fullscreen mode Exit fullscreen mode

Next, load the Docker image into Minikube’s image repository:

minikube image load app-go-container
Enter fullscreen mode Exit fullscreen mode

Finally, apply the deployment and service YAML files to create the necessary resources on Kubernetes:

kubectl apply -f app-deployment.yaml
kubectl apply -f nats-deployment.yaml
kubectl apply -f nats-service.yaml
Enter fullscreen mode Exit fullscreen mode

Conclusion

In this article, we have walked through the process of deploying a Go application with NATS messaging on Kubernetes.

We covered writing the deployment YAML files, writing the Go application code, building the Docker image, and deploying the application on Kubernetes using Minikube.

By following these steps, you can easily deploy your Go application with NATS messaging on a Kubernetes cluster, leveraging the power of containerization and orchestration.

Feel free to customize the configurations and expand upon the concepts covered here to suit your specific needs.

Happy coding and deploying!

Newsletter

If you like my content, then consider subscribing to my free newsletter, to get exclusive, educational, technical, interesting and career related content directly delivered to your inbox

https://dsysd.beehiiv.com/subscribe

Important Links

Thanks for reading the post, be sure to follow the links below for even more awesome content in the future.

Twitter: https://twitter.com/dsysd_dev
Youtube: https://www.youtube.com/@dsysd-dev
Github: https://github.com/dsysd-dev
Medium: https://medium.com/@dsysd-dev
Email: dsysd.mail@gmail.com
Linkedin: https://www.linkedin.com/in/dsysd-dev/
Newsletter: https://dsysd.beehiiv.com/subscribe
Gumroad: https://dsysd.gumroad.com/

Top comments (0)