
NATS is an open-source, lightweight, high-performance messaging system for building distributed and scalable applications. It supports publish-subscribe, queuing, and request-reply patterns commonly used in cloud-native and microservice architectures. In the publish-subscribe pattern, a publisher sends a message on a subject and every active subscriber listening on that subject receives it. In the queuing pattern, subscribers register as part of a queue group, and only one randomly selected member of the group consumes each message.
This guide explains how to deploy a NATS cluster on a Vultr Kubernetes Engine (VKE) cluster using Helm. It covers installing the NATS chart, building Go producer and consumer applications into container images, storing those images in a Vultr Container Registry, deploying both applications to the cluster, and scaling the consumer to demonstrate how queue-based messaging distributes load.
Before you begin, you need to:
The NATS project publishes an official Helm chart that deploys the server together with a nats-box utility pod for administrative commands. Installing the chart creates the messaging backbone that both application deployments connect to.
Add the NATS Helm repository.
Update the repository cache.
Install NATS into your cluster.
View the NATS pods.
Wait until the pods report a Running status.
The consumer subscribes to a subject as part of a queue group. Running more than one replica of this application later demonstrates how NATS distributes messages across a group instead of delivering every message to every subscriber.
Switch to your home directory.
Create the project directory.
Create the consumer application directory inside it.
Switch to the consumer directory.
Initialize a new Go module.
Create the application source file.
Add the following code.
Save and close the file.
The application performs the following actions in order:
A two-stage Dockerfile compiles the Go binary in a build image and copies it into a minimal distroless runtime image, which keeps the published image small and free of a shell and package manager.
Create the Dockerfile.
Add the following configuration.
Save and close the file.
golang:1.18-buster to compile the consumer binary.gcr.io/distroless/base-debian10 and copies in the binary produced by the first stage.Resolve the Go modules and create the go.sum file.
Verify the directory contents.
The output lists the source file, the Dockerfile, and both module files.
Log in to your Vultr Container Registry. Replace example with your registry name.
Enter your registry username and password when prompted.
Build the consumer image. Replace example with your registry name.
Push the image to the registry. Replace example with your registry name.
The output confirms each layer is pushed and reports the image digest.
The Deployment passes the NATS server address, subject, and queue group to the container as environment variables, which the application reads at startup. The server address uses the nats Service that the Helm chart created.
Create the deployment manifest.
Add the following configuration. Replace sjc.vultrcr.com/example with your registry URL.
Save and close the file.
NATS_SERVER: Points at the nats Service created by the Helm chart on the default client port.NATS_QUEUE_GROUP: Places every replica of this Deployment in the same queue group so that NATS delivers each message to only one of them.Apply the manifest.
Verify that the consumer pod is running.
Verify that the pod reports a Running status.
The producer publishes a numbered message to the same subject every three seconds, which provides a steady stream to observe when testing how the consumers share the load.
Switch to the project directory.
Create the producer application directory.
Switch to the directory.
Initialize a new Go module.
Create the application source file.
Add the following code.
Save and close the file.
The application performs the following actions in order:
SIGTERM signal.The producer uses the same two-stage build as the consumer, differing only in the source file it compiles and the resulting binary name.
Create the Dockerfile.
Add the following configuration.
Save and close the file.
golang:1.18-buster to compile the producer binary.gcr.io/distroless/base-debian10 and copies in the binary produced by the first stage.Resolve the Go modules and create the go.sum file.
Build the producer image. Replace example with your registry name.
Push the image to the registry. Replace example with your registry name.
The producer Deployment reads the same NATS server address and subject as the consumer, but takes no queue group because it publishes rather than subscribes.
Create the deployment manifest.
Add the following configuration. Replace sjc.vultrcr.com/example with your registry URL.
Save and close the file.
Apply the manifest.
Verify that the deployments are available.
The output lists the NATS utility pod alongside both application deployments.
Verify that the producer pod is running.
Verify that the pod reports a Running status.
Following both application logs confirms that messages published by the producer reach the consumer through NATS. Scaling the consumer afterward shows the queue group distributing those messages instead of duplicating them.
Follow the producer logs.
The output displays a new published message every three seconds.
Press Ctrl + C to stop following the log.
Follow the consumer logs.
The output displays the matching received messages.
Press Ctrl + C to stop following the log.
Scale the consumer to two replicas.
Verify that both consumer pods are running.
Follow the logs of the first consumer replica.
The output displays only a subset of the message sequence.
Press Ctrl + C to stop following the log.
Follow the logs of the second consumer replica.
The output displays the remaining messages in the sequence.
Each message reaches exactly one replica rather than both, because both pods belong to the same queue group. Distributing messages this way lets you scale message processing horizontally by adding replicas.
You have deployed NATS on a Vultr Kubernetes Engine cluster, published messages from a Go producer application, and consumed them with a scalable consumer application that shares work through a queue group. Extend the deployment by adding more subjects, enabling JetStream for persistent streams, or scaling the consumer further to match your processing needs. For more information, visit the official NATS documentation and the Vultr Kubernetes Engine documentation.
0 Comments
Be the first to comment and share your perspective with the community.