Get Started With NATS on Kubernetes

Ismail Demirbilek
3 min readNov 4, 2021

--

I’ve been looking into NATS Streaming to leverage it in our microservices. I will be documenting what I encounter as a starter. Main goal of this article is taking notes for myself.

Prerequisites:

  • Local Kubernetes cluster (minikube on macOs is used)
  • Helm installed

At the time of writing, there are no one official way of using NATS on K8s as far as I followed. Though, nats-controller is deprecated with following words:

The recommended way of running NATS on Kubernetes is by using the Helm charts.

Then there is also NACK, NATS Controllers for Kubernetes. I anticipated that using NACK with Helm charts is the optimal way. So let’s get started.

I followed the steps on NACK’s readme. But somehow NACK couldn’t access the NATS server.

After some frustrating hours, I finally got the solution from Helm charts repo.

So final steps are:

// Install Custom Resource Definitions (CRD)
$ kubectl apply -f https://raw.githubusercontent.com/nats-io/nack/v0.6.0/deploy/crds.yml
// Add Helm repo
$ helm repo add nats https://nats-io.github.io/k8s/helm/charts/
$ helm repo update
// Deploy NATS
$ helm install nats nats/nats --set=nats.jetstream.enabled=true
// Deploy NACK (this step is different from NACK's readme!)
$ helm install nack-jsc nats/nack --set jetstream.nats.url=nats://nats:4222

NACK is responsible for adding stream / consumer from CRDs into NATS server.

Let’s follow steps from readme again to add a stream and few consumers.

// Add a stream
$ kubectl apply -f https://raw.githubusercontent.com/nats-io/nack/main/deploy/examples/stream.yml
// Add a push based consumer
$ kubectl apply -f https://raw.githubusercontent.com/nats-io/nack/main/deploy/examples/consumer_push.yml
// Add a pull based consumer
kubectl apply -f https://raw.githubusercontent.com/nats-io/nack/main/deploy/examples/consumer_pull.yml

First command adds a stream named mystream. Later commands add consumers named my-push-consumer and my-pull-consumer.

Deploying NATS with Helm also installs nats-box a container including tools to interact with NATS server.

To execute a shell inside nats-box run following:

$ kubectl exec -n default -it deployment/nats-box -- /bin/sh -l

Our pull consumer listens for orders.received subject. Publish some messages:

// publish messages
nats-box:$ nats pub orders.received "order 1"
nats-box:$ nats pub orders.received "order 2"

Let’s read messages with pull consumer.

// pull first message
nats-box:$ nats consumer next mystream my-pull-consumer
subj: orders.received / tries: 1 / cons seq: 1/ str seq: 1 / pending: 1
order 1Acknowledged message// pull next message
nats-box:$ nats consumer next mystream my-pull-consumer
subj: orders.received / tries: 1 / cons seq: 2 / str seq: 2 / pending: 0
order 2Acknowledged message

Subscribing to messages continuously is possible with push consumer.

nats-box:$ nats sub my-push-consumer.orders
Subscribing on my-push-consumer.orders
[#1] Received JetStream message: consumer: mystream > my-push-consumer / subject: orders.received / delivered: 1 / consumer seq: 1 / stream seq: 2 / ack: false
order 1
[#2] Received JetStream message: consumer: mystream > my-push-consumer / subject: orders.received / delivered: 1 / consumer seq: 2 / stream seq: 2 / ack: false
order 2

That’s it. We deployed NATS, nats-box and NACK with ease of Helm. Using NACK allows us to manage streams and consumers with Kubernetes Custom Resource Definitions.

--

--