Jump to contentJump to page navigation: previous page [access key p]/next page [access key n]
documentation.suse.com / SUSE Edge Documentation / Third-Party Integration / NATS

22 NATS

NATS 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-premises, edge, Web and mobile devices. NATS consists of a family of open-source products that are tightly integrated but can be deployed easily and independently. NATS is being used globally by thousands of companies, spanning use cases including microservices, edge computing, mobile and IoT, and can be used to augment or replace traditional messaging.

22.1 Architecture

NATS is an infrastructure that allows data exchange between applications in the form of messages.

22.1.1 NATS client applications

NATS client libraries can be used to allow the applications to publish, subscribe, request and reply between different instances. These applications are generally referred to as client applications.

22.1.2 NATS service infrastructure

The NATS services are provided by one or more NATS server processes that are configured to interconnect with each other and provide a NATS service infrastructure. The NATS service infrastructure can scale from a single NATS server process running on an end device to a public global super-cluster of many clusters spanning all major cloud providers and all regions of the world.

22.1.3 Simple messaging design

NATS makes it easy for applications to communicate by sending and receiving messages. These messages are addressed and identified by subject strings and do not depend on network location. Data is encoded and framed as a message and sent by a publisher. The message is received, decoded and processed by one or more subscribers.

22.1.4 NATS JetStream

NATS has a built-in distributed persistence system called JetStream. JetStream was created to solve the problems identified with streaming in technology today — complexity, fragility and a lack of scalability. JetStream also solves the problem with the coupling of the publisher and the subscriber (the subscribers need to be up and running to receive the message when it is published). More information about NATS JetStream can be found here.

22.2 Installation

22.2.1 Installing NATS on top of K3s

NATS is built for multiple architectures so it can easily be installed on K3s. (Chapter 13, K3s)

Let us create a values file to overwrite the default values of NATS.

cat > values.yaml <<EOF
cluster:
  # Enable the HA setup of the NATS
  enabled: true
  replicas: 3

nats:
  jetstream:
    # Enable JetStream
    enabled: true

    memStorage:
      enabled: true
      size: 2Gi

    fileStorage:
      enabled: true
      size: 1Gi
      storageDirectory: /data/
EOF

Now let us install NATS via Helm:

helm repo add nats https://nats-io.github.io/k8s/helm/charts/
helm install nats nats/nats --namespace nats --values values.yaml \
 --create-namespace

With the values.yaml file above, the following components will be in the nats namespace:

  1. HA version of NATS Statefulset containing three containers: NATS server + Config reloader and Metrics sidecars.

  2. NATS box container, which comes with a set of NATS utilities that can be used to verify the setup.

  3. JetStream also leverages its Key-Value back-end that comes with PVCs bounded to the pods.

22.2.1.1 Testing the setup

kubectl exec -n nats -it deployment/nats-box -- /bin/sh -l
  1. Create a subscription for the test subject:

    nats sub test &
  2. Send a message to the test subject:

    nats pub test hi

22.2.1.2 Cleaning up

helm -n nats uninstall nats
rm values.yaml

22.2.2 NATS as a back-end for K3s

One component K3s leverages is KINE, which is a shim enabling the replacement of etcd with alternate storage back-ends originally targeting relational databases. As JetStream provides a Key Value API, this makes it possible to have NATS as a back-end for the K3s cluster.

There is an already merged PR which makes the built-in NATS in K3s straightforward, but the change is still not included in the K3s releases.

For this reason, the K3s binary should be built manually.

In this tutorial, SLE Micro on OSX on Apple Silicon (UTM) VM is used.

Note
Note

Run the commands below on the OSX PC.

22.2.2.1 Building K3s

git clone --depth 1 https://github.com/k3s-io/k3s.git && cd k3s

The following command adds nats in the build tags to enable the NATS built-in feature in K3s:

sed -i '' 's/TAGS="ctrd/TAGS="nats ctrd/g' scripts/build
make local

Replace <node-ip> with the actual IP of the node where the K3s will be started:

export NODE_IP=<node-ip>
sudo scp dist/artifacts/k3s-arm64 ${NODE_IP}:/usr/local/bin/k3s
Note
Note

Locally building K3s requires the buildx Docker CLI plugin. It can be manually installed if $ make local fails.

22.2.2.2 Installing NATS CLI

TMPDIR=$(mktemp -d)
nats_version="nats-0.0.35-linux-arm64"
curl -o "${TMPDIR}/nats.zip" -sfL https://github.com/nats-io/natscli/releases/download/v0.0.35/${nats_version}.zip
unzip "${TMPDIR}/nats.zip" -d "${TMPDIR}"

sudo scp ${TMPDIR}/${nats_version}/nats ${NODE_IP}:/usr/local/bin/nats
rm -rf ${TMPDIR}

22.2.2.3 Running NATS as K3s back-end

Let us ssh on the node and run the K3s with the --datastore-endpoint flag pointing to nats.

Note
Note

The command below starts K3s as a foreground process, so the logs can be easily followed to see if there are any issues. To not block the current terminal, a & flag could be added before the command to start it as a background process.

k3s server  --datastore-endpoint=nats://
Note
Note

For making the K3s server with the NATS back-end permanent on your slemicro VM, the script below can be run, which creates a systemd service with the needed configurations.

export INSTALL_K3S_SKIP_START=false
export INSTALL_K3S_SKIP_DOWNLOAD=true

curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server \
 --datastore-endpoint=nats://"  sh -

22.2.2.4 Troubleshooting

The following commands can be run on the node to verify that everything with the stream works properly:

nats str report -a
nats str view -a