Home > other >  Kubernetes Deployment config for connecting to NATS event bus
Kubernetes Deployment config for connecting to NATS event bus

Time:12-03

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?

Any help would be appreciated.

CodePudding user response:

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.

  • Related