I used NATS Streaming before for my microservices based on Docker and Kubernetes and node.js but because NATS Streaming is currently being deprecated I want to migrate to NATS and NATS JetStream.
This is the deployment yaml config file that I used for NATS Streaming server in my k8s folder which is using by skaffold to apply and it works fine:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nats-depl
spec:
replicas: 1
selector:
matchLabels:
app: nats
template:
metadata:
labels:
app: nats
spec:
containers:
- name: nats
image: nats-streaming:0.23.2
args:
[
'-p',
'4222',
'-m',
'8222',
'-hbi',
'5s',
'-hbt',
'5s',
'-hbf',
'2',
'-SD',
'-cid',
'adrian',
]
---
apiVersion: v1
kind: Service
metadata:
name: nats-srv
spec:
selector:
app: nats
ports:
- name: client
protocol: TCP
port: 4222
targetPort: 4222
- name: monitoring
protocol: TCP
port: 8222
targetPort: 8222
The cluster named adrian
and I could connect to NATS Streaming server as a client like this in my node.js application:
import nats from 'node-nats-streaming';
const stan = nats.connect( 'adrian', 'abc', {
url: "http://localhost:4222"
} );
Now I want to migrate to NATS and NATS JetStream. So, I changed my Kubernetes deployment config to this:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nats-depl
spec:
replicas: 1
selector:
matchLabels:
app: nats
template:
metadata:
labels:
app: nats
spec:
containers:
- name: nats
image: nats
args:
[
'-p',
'4222',
'-m',
'8222',
'-D',
'-js',
'--cluster_name',
'adrian',
]
---
apiVersion: v1
kind: Service
metadata:
name: nats-srv
spec:
selector:
app: nats
ports:
- name: client
protocol: TCP
port: 4222
targetPort: 4222
- name: monitoring
protocol: TCP
port: 8222
targetPort: 8222
And when I try new NATS client's connect method to connect to NATS server like below:
import { connect } from 'nats';
const natsPublisher = async () => {
try {
const nc = await connect( { servers: "http://localhost:4222" } );
console.log(`connected to ${nc.getServer()}`);
} catch ( error ) {
console.log( '--- NATS ERROR: ', error )
}
}
natsPublisher();
I get this error in terminal:
--- NATS ERROR: NatsError: CONNECTION_REFUSED
at Function.errorForCode (E:\Projects\express-projects\adrian-microservices\nats-test\node_modules\nats\nats-base-client\error.ts:119:12)
at NodeTransport.<anonymous> (E:\Projects\express-projects\adrian-microservices\nats-test\node_modules\nats\src\node_transport.ts:92:21)
at Generator.throw (<anonymous>)
at rejected (E:\Projects\express-projects\adrian-microservices\nats-test\node_modules\nats\lib\src\node_transport.js:6:65)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
code: 'CONNECTION_REFUSED',
chainedError: Error: connect ECONNREFUSED 127.0.0.1:4222
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1161:16) {
errno: -4078,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 4222
}
}
So how could I solve the issue and connect to NATS without any problem?
After some trials and errors and some research, I realized that it is actually better to use Helm (Kubernetes package manager) to have a complete and correct manifest for things like NATS or Kafka or ElasticSearch, etc... So, after installing Helm Kubernetes package manager you can install NATS in your Kubernetes cluster by running a command as simple as "helm install my-nats nats/nats
" and then you have NATS up and running there in your Kubernetes.
But in this case with the manifest I came up with for NATS unlike before that it was common to connect to NATS server from node.js client using localhost
and external access was possible, you can connect to NATS server from node.js client by using service name like this, that is perhaps even more appropriate:
import { connect } from 'nats';
const natsPublisher = async () => {
try {
const nc = await connect( { servers: "http://nats-srv:4222" } );
console.log( `connected to ${ nc.getServer() }` );
} catch ( error ) {
console.log( 'NATS ERROR: ', error )
}
}
And this is my terminal logs after connecting to NATS:
[taxonomy] Listening on port 3000!
[taxonomy] connected to nats-srv:4222
Hopefully, that'll be helpful for others.