Implementing Message Queues with NATS on Kubernetes
What is NATs and how to use it on Kubernetes cluster environment?
NATS(https://nats.io/) is a connective technology built for the ever increasingly hyper-connected world. It is a single technology that enables applications to securely communicate across any combination of cloud vendors, on-premise, edge, web and mobile, and devices. NATS consists of a family of open source products that are tightly integrated but can be deployed easily and independently.
NATS was created by Derek Collison, in response to the market need for a simple, secure, and connective technology. NATS is currently deployed in some of the largest cloud platforms, including: VMware, CloudFoundry, Baidu, Siemens, and GE. NATS is 100% free to use under the Apache-2.0 Open Source License.
This article is about installing and operating NATS on Kubernetes. The easiest installation method, by all means, is to use Helm.
First, the PC used for installation should be connected to the Kubernetes cluster. You can achieve this by either copying the Kubernetes context to the `~/.kube/config` file or by using the `EXPORT KUBECONFIG` command as needed.
At first, Add NATS to your helm chart:
% helm repo add nats https://nats-io.github.io/k8s/helm/charts/
"nats" has been added to your repositories
Update the helm repository:
% helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "nats" chart repository
...Successfully got an update from the "openfaas" chart repository
Update Complete. ⎈Happy Helming!⎈
Check if NATS has been added to the repository:
% helm repo list
NAME URL
nats https://nats-io.github.io/k8s/helm/charts/
By using the default installation options, a single NATS server will be deployed as a StatefulSet with one Replica Deployment. Install the chart with the default options, using the name “my-nats” in this example:
% helm install my-nats nats/nats
NAME: my-nats
LAST DEPLOYED: Sun Sep 3 03:16:07 2023
NAMESPACE: default
STATUS: deployed
REVISION: 1
Check the StatefulSet, Deployment, and Pods:
% kubectl get statefulset
NAME READY AGE
my-nats 1/1 22h
% kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
my-nats-box 1/1 1 1 22h
% kubectl get pods | grep nats
my-nats-0 2/2 Running 0 22h
my-nats-box-547fd47df-76fm9 1/1 Running 0 22h
To understand NATS server communication, check the Services. It uses the ClusterIP method:
% kubectl get service | grep nats
my-nats ClusterIP 10.128.78.134 <none> 4222/TCP 22h
my-nats-headless ClusterIP None <none> 4222/TCP,8222/TCP 22h
Now, let’s run the my-nats deployment for NATS server operation. Run both subscription and publishing in separate terminals.
<Publisher>
% kubectl exec -it deployment/my-nats-box -- nats pub my-subject "Hello?"
16:27:23 Published 6 bytes to "my-subject"
<Subscriber>
% kubectl exec -it deployment/my-nats-box -- nats sub my-subject
16:26:55 Subscribing on my-subject
[#1] Received on "my-subject"
Hello?
Subscriber messages will reach all subscribers, even if there are multiple.
Now, let’s set up a Wild Card subject. This allows communication to all subscribers with matching subjects.
When a Subscriber’s subscribed subject is “greet.*,” it will receive messages with “greet.joe” and “greet.smith” subjects.
Next, let’s test Request-Reply messaging. Request-Reply is a unique messaging type in NATS where you send a request and receive a response. It can be represented as follows:
First, create a Reply client listener that subscribes to the “help.please” subject and automatically joins the “NATS-RPLY-22” group:
% kubectl exec -it deployment/my-nats-box -- nats reply help.please 'OK, I CAN HELP!'
16:36:36 Listening on "help.please" in group "NATS-RPLY-22"
Now, create a Request client. Sending a request with the same subject results in a response from the Reply client, including the response message and round-trip time (RTT):
% kubectl exec -it deployment/my-nats-box -- nats request help.please 'I need help!'
16:37:46 Sending request on "help.please"
16:37:46 Received with rtt 980.984µs
OK, I CAN HELP!
Next, let’s test Queueing messaging, which is a form of messaging where only one subscriber receives the message.
According to the NATS official website, when using a globally deployed NATS cluster, it is possible to configure message routing to go to nearby subscribers using the “get-affinity” method. Additionally, if there are no listeners available, it is also possible to configure it to use clusters in different regions.
In this example, three subscribers are created, each with its own response containing A, B, or C for differentiation:
nats reply foo "service instance A Reply# {{Count}}"
nats reply foo "service instance B Reply# {{Count}}"
nats reply foo "service instance C Reply# {{Count}}"
All three subscribers join the “NATS-RPLY-22” group.
Now, send a Request:
% kubectl exec -it deployment/my-nats-box -- nats request foo "Simple request"
The response will be from one of the three subscribers.
You can continue to send requests, and they will be distributed randomly among subscribers, incrementing the Count variable:
% kubectl exec -it deployment/my-nats-box -- nats request foo "Another request"
16:52:44 Sending request on "foo"
16:52:44 Received with rtt 989.014µs
service instance A Reply# 4
That’s it! You’ve learned how to use NATS messaging service in a Kubernetes cluster environment.