Настройка NATS сервера

Обновлено и опубликовано Опубликовано:

В двух словах, NATS позволяет обмениваться данными, сегментированными в виде сообщений. Что-то подобное делает KafkaRabbitMQRedis и многое другое. В данной инструкции будет рассмотрен процесс установки NATS сервера на Linux, а также его запуск в режиме кластера.

Установка и запуск

Рассмотрим отдельно процессы установки и запуска сервера nats.

Установка

NATS может быть развернут несколькими способами:

  • Как процесс, работающий в docker.
  • Как приложение Kubernetes.
  • С помощью пакетного менеджера (далеко не для всех систем).
  • Распаковка бинарника.

Последний вариант является универсальным и самым простым. Рассмотрим его.

Нам понадобятся следующие пакеты:

  1. wget — для загрузки архива.
  2. tar — для распаковки архива.

В зависимости от системы, команды для установки будут отличаться.

а) Для Deb (Ubuntu / Debian / Astra Linux):

apt update

apt install tar wget

б) Для RPM (Rocky Linux / РЕД ОС):

yum install tar wget

Переходим на страницу с релизами проекта в GitHub. Копируем ссылку на архив с последней версией (или конкретную, если требуется) nats server:

Используя ссылку, загружаем архив на сервер:

wget https://github.com/nats-io/nats-server/releases/download/v2.9.15/nats-server-v2.9.15-linux-amd64.tar.gz

Распакуем:

tar -zxf nats-server-*.tar.gz

Копируем бинарный файл в каталог /usr/bin:

cp nats-server-*-linux-amd64/nats-server /usr/bin/

Проверяем, что nats-server может быть запущен:

nats-server -v

Мы должны получить что-то на подобие:

nats-server: v2.9.15

Исходники можно удалить:

rm -rf nats-server-*-linux-amd64 nats-server-*.tar.gz

Запуск

Для разового запуска достаточно ввести команду:

nats-server

Мы должны увидеть что-то на подобие:

[153420] 2023/04/04 16:20:40.059157 [INF] Starting nats-server
[153420] 2023/04/04 16:20:40.059246 [INF]   Version:  2.9.15
[153420] 2023/04/04 16:20:40.059254 [INF]   Git:      [b91fa85]
[153420] 2023/04/04 16:20:40.059264 [INF]   Name:     NDAXZI62G33F3IR6UGBMFCL4XMPPI6VDRCYDU4NP5OFSKYIH4TDQ63WQ
[153420] 2023/04/04 16:20:40.059268 [INF]   ID:       NDAXZI62G33F3IR6UGBMFCL4XMPPI6VDRCYDU4NP5OFSKYIH4TDQ63WQ
[153420] 2023/04/04 16:20:40.060083 [INF] Listening for client connections on 0.0.0.0:4222
[153420] 2023/04/04 16:20:40.060292 [INF] Server is ready

Прерываем работу сервиса клавишами Ctrl + C. Теперь выполним запуск nats в качестве сервиса.

Создадим конфигурационный файл для сервера nats:

mkdir /etc/nats

vi /etc/nats/nats-server.conf

cluster {
  name: "test-nats"
}

store_dir: "/var/lib/nats"
listen: "0.0.0.0:4222"
log_file: /var/log/nats/nats.log

* где:

  • cluster name — имя сервера кластера NATS.
  • store_dir — путь к файлу хранилища данных.
  • listen — адрес и порт, на котором будет слушать сервер.
  • log_file — путь к файлу журнала.

Создадим служебную учетную запись nats:

useradd -r -c 'NATS service' nats

Создадим каталоги:

mkdir /var/log/nats /var/lib/nats

И назначим в качестве их владельца созданную учетную запись:

chown nats:nats /var/log/nats /var/lib/nats

Создадим systemd юнит-файл:

vi /etc/systemd/system/nats-server.service

[Unit]
Description=NATS messaging server
After=syslog.target network.target

[Service]
Type=simple
ExecStart=/usr/bin/nats-server -c /etc/nats/nats-server.conf
User=nats
Group=nats
LimitNOFILE=65536
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure

[Install]
WantedBy=multi-user.target

Для разрешения автозапуска и старта сервиса вводим:

systemctl enable nats-server --now

Статус смотрим командой:

systemctl status nats-server

Подключение к серверу

Если мы хотим подключаться к нашему серверу по сети с другого узла, необходимо убедиться, что брандмауэр разрешает подключение по настроенному порту (в нашем примере, 4222). Для разных утилит управления фаерволом это делается по-разному.

а) В iptables (как правило, для систем deb):

iptables -I INPUT 1 -p tcp --dport 4222 -j ACCEPT

apt install iptables-persistent

netfilter-persistent save

* последние 2 команды для сохранения правил. Подробнее про настройку iptables и сохранение правил читайте в инструкции Настройка netfilter с помощью iptables.

б) В firewalld (как правило, для систем rpm):

firewall-cmd --permanent --add-port=4222/tcp

firewall-cmd --reload

* подробнее в инструкции Настройка firewalld в CentOS.

Тестирование работы сервера можно выполнить из командной строки. Для этого нужно установить клиента nats. В репозиториях системы его нет, но готовый пакет (deb или rpm) можно скачать с GitHub — переходим на соответствующую страницу, копируем ссылку на установщик, загружаем его в систему и выполняем установку.

а) Например, для Ubuntu / Debian / Astra Linux:

wget https://github.com/nats-io/natscli/releases/download/v0.0.35/nats-0.0.35-amd64.deb

dpkg -i nats-0.0.35-amd64.deb

б) Или для Rocky Linux / РЕД ОС:

wget https://github.com/nats-io/natscli/releases/download/v0.0.35/nats-0.0.35-amd64.rpm

yum localinstall ./nats-0.0.35-amd64.rpm

После мы можем выполнить команду для тестирования.

Вводим:

nats pub -s <адрес сервера> <тема> <сообщение>

Например:

nats pub -s 127.0.0.1 "test-subject" "Test message"

* в данном примере мы опубликуем сообщение Test message в теме test-subject на локальном сервере (127.0.0.1).

Система может вернуть ошибку:

bash: nats: command not found

Это происходит из-за того, что исполняемый файл помещается в каталог /usr/local/bin, а системная переменная PATH не включает данный путь. Как вариант, мы можем либо прописать полный путь к утилите:

/usr/local/bin/nats

Либо отредактировать конфигурационный файл шела, добавив путь к переменной PATH, например, для bash:

vi ~/.bash_profile

Добавим строку:

PATH=$PATH:/usr/local/bin

Применяем:

source ~/.bash_profile

Для подписки на тему, можно в другой сессии ssh или с другого компьютера ввести команду:

nats sub -s <адрес сервера> <тема>

При повторной отправки сообщения мы должны увидеть его текст из консоли, где выполнена подписка (nats sub).

Включение JetStream

JetStream в NATS предоставляет механизмы для хранения, репликации, управления и быстрого доступа к сообщениям, обеспечивая высокую производительность и надежность системы обмена сообщениями. Он предназначен для использования в приложениях, где требуется долговременное хранение сообщений, отслеживание их состояния и быстрый доступ к ним.

Для включения JetStream достаточно в конфигурационном файле добавить одну строчку:

vi /etc/nats/nats-server.conf

...
jetstream: true

И перезапустим сервис:

systemctl restart nats-server

В логе мы должны увидеть что-то на подобие:

tail /var/log/nats/nats.log

 ---------------- JETSTREAM ----------------
   Max Memory:      3.61 GB
   Max Storage:     15.69 GB
   Store Directory: "/var/lib/nats/jetstream"
 -------------------------------------------
 Listening for client connections on 0.0.0.0:4222
 Server is ready

Добавление системной учетной записи

При выполнении некоторых команд nats мы можем получить ответ:

nats: error: server request failed, ensure the account used has system privileges and appropriate permissions

По умолчанию, мы работаем с nats от анонимной учетной записи с ограниченными правами, которых недостаточно для выполнения некоторых команд или получении определенных сведений.

Для решения проблемы в конфигурационном файле необходимо прописать системную учетную запись, после чего указать клиенту, что мы будем работать под ней.

Так устроена система NATS, что мы не сможем работать с функциями JetStream от системной учетной записи, поэтому для полноценной работы нам нужно будет переключаться между контекстами. Об этом будет ниже.

Открываем файл:

vi /etc/nats/nats-server.conf

Добавим:

...
accounts: {
  $SYS: {
    users: [
      { user: sys-user, password: sys-pass }
    ]
  }
}
...

* мы добавили системную учетную запись с логином sys-user и паролем sys-pass.

Перезапустим сервис:

systemctl restart nats-server

Теперь можно создать контекст, который будет работать с nats-server от созданной системной записи:

nats context save sys --user sys-user --password sys-pass

Также создадим контекст, который будет работать от анонимной учетной записи:

nats context save default

default — просто название контекста и оно может быть любым.

После чего выбираем данный контекст:

nats context select sys

Теперь можно подавать клиенту nats любые системные команды, например:

nats server info

После можно переключиться на контекст с анонимной учетной записью:

nats context select default

Настройка кластера

Серверы NATS могут работать в режиме кластера, реплицируя сообщения. Для начала, нам нужно установить его на все ноды кластера. Предположим, что у нас есть 3 сервера со следующими адресами:

  1. 192.168.0.10
  2. 192.168.0.20
  3. 192.168.0.30

Создадим из них кластер NATS.

На всех серверах открываем наш конфигурационный файл:

vi /etc/nats/nats-server.conf

У нас уже была директива cluster — дополним ее, а также добавим опцию server_name:

cluster {
  name: "test-nats"

  listen: 0.0.0.0:6222

  authorization {
      user: nats-user
      pass: nats-password
      timeout: 2
  }

  routes: [
    nats-route://nats-user:nats-password@192.168.0.20:6222
    nats-route://nats-user:nats-password@192.168.0.30:6222
  ]
}

server_name: nats1
...

* где:

  • listen — адрес и порт, на котором будут прослушиваться запросы к кластеру.
  • authorization — директива отвечает за настройку авторизации кластера. В нашем примере мы укажем, что необходимо вводить логин nats-user и пароль nats-password. При желании, на каждом сервере могут быть свои данные.
  • routes — перечисляем список серверов для подключения. В нем нужно указать соседние серверы, к которым необходимо подключиться. Обратите внимание, что строка также содержит логин и пароль для аутентификации.
  • server_name — имя сервера. Данная опция обязательно для кластеров NATS с включенной функцией JetStream.

Будьте аккуратны при использовании спецсимволов в пароле nats. Они могу привести к ошибке парсинга конфигурационного файла.

На серверах 2 и 3 выполним такую же правку, только в routes должны быть значения, указывающие на соседние серверы, а также задан свой server_name.

На сервере 2:

  ...
  routes: [
    nats-route://nats-user:nats-password@192.168.0.10:6222
    nats-route://nats-user:nats-password@192.168.0.30:6222
  ]
}

server_name: nats2
...

И на сервере 3:

  ...
  routes: [
    nats-route://nats-user:nats-password@192.168.0.10:6222
    nats-route://nats-user:nats-password@192.168.0.20:6222
  ]
}

server_name: nats3
...

Открываем на брандмауэрах порт, который используется для нужд кластера (в нашем примере, 6222). Для разных утилит управления фаерволом это делается по-разному.

а) В iptables (как правило, для систем deb):

iptables -I INPUT 1 -p tcp --dport 6222 -j ACCEPT

apt install iptables-persistent

netfilter-persistent save

б) В firewalld (как правило, для систем rpm):

firewall-cmd --permanent --add-port=6222/tcp

firewall-cmd --reload

Перезапускаем сервисы на всех серверах:

systemctl restart nats-server

Смотрим в лог:

tail /var/log/nats/nats.log

Мы должны увидеть что-то на подобие:

 Cluster name is test-nats
 Listening for route connections on 0.0.0.0:6222
 192.168.0.20:6222 - rid:4 - Route connection created

Для проверки можно на одном сервере запустить подписку из командной строки, также как мы это делали после запуска службы:

nats sub -s 127.0.0.1 "test-subject"

А на другом сервере отправить сообщение:

nats pub -s 127.0.0.1 "test-subject" "Test message"

В итоге, сообщение должно быть получено на первом сервере.

Также мы можем получить сведения о серверах в кластере командой:

nats server ls

Отправка файлов

При включеном JetStream мы можем отправлять в хранилище NATS файлы. Рассмотрим простой пример, как это сделать.

Для начала, создадим бакет:

nats object add test-bucket

Список бакетов можно посмотреть командой:

nats object ls

* если у нас настроен кластер, то наш бакет должен появиться и на других нодах.

Загрузить файл можно командой:

nats object put <имя бакета> <путь до файла>

Например:

nats object put test-bucket ./nats-0.0.35-amd64.rpm

* в своем примере я загрузил в созданное хранилище test-bucket ранее скачанный файл nats-0.0.35-amd64.rpm.

Увидеть содержимое бакета можно командой:

nats object ls test-bucket

Подробнее про работу с объектами можно почитать на официальном сайте.

Встроенный мониторинг

На мониторинге остановимся немного подробнее.

Включение

NATS содержит свой набор метрик, которые возвращают состояние сервиса. Для включения данной возможности открываем конфигурационный файл:

vi /etc/nats/nats-server.conf

Добавляем:

...
monitor_port: 8222

Перезапустим сервис:

systemctl restart nats-server

Теперь можно получать информацию в формате JSON с помощью http-запросов. Например, общие метрики:

curl http://127.0.0.1:8222/varz

Или метрика "жив — не жив":

curl http://127.0.0.1:8222/healthz

Весь набор запросов представлен в документации на официальном сайте.

Prometheus

Также разработчик предоставляет экспортера, который может отдавать показатели сервиса на сервер Prometheus. Рассмотрим процесс по шагам.

Установка, настройка и запуск экспортера

У нас уже должен быть развернут сервер Prometheus — если нет, читайте инструкцию Установка Prometheus + Alertmanager + node_exporter на Linux.

Теперь установим prometheus-nats-exporter на сервер NATS. 

На официальной страничке Github ознакомимся с релизами экспортера. Копируем ссылку на бинарник (для linux amd64, архив tar.gz).

Перейдем в более подходящий для загрузки исходников каталог:

cd /usr/local/src

Скачаем их:

wget https://github.com/nats-io/prometheus-nats-exporter/releases/download/v0.10.1/prometheus-nats-exporter-v0.10.1-linux-amd64.tar.gz

Распакуем:

tar -zxf prometheus-nats-exporter-v*-linux-amd64.tar.gz

Копируем бинарник в bin-каталог системы:

cp prometheus-nats-exporter-v*-linux-amd64/prometheus-nats-exporter /usr/local/bin/

Проверим, что мы можем запустить экспортер:

prometheus-nats-exporter -version

Мы должны увидеть версию установленного пакета, например:

prometheus-nats-exporter version 0.10.1

Исходники можно удалить:

rm -rf prometheus-nats-exporter*

Теперь настроим запуск экспортера в качестве юнита systemd. Так как экспортер подразумевает возможность сбора различных групп метрик, рассмотрим более сложный вариант настройки сервиса.

Создадим пользователя, от которого будет запускаться и работать юнит:

useradd -r -c 'NATS Prometheus Exporter' nats-exporter

Создадим файл:

vi /etc/systemd/system/nats-exporter@.service

[Unit]
Description=NATS Exporter Service
After=network.target

[Service]
User=nats-exporter
Group=nats-exporter
Type=simple
EnvironmentFile=-/etc/prometheus-nats-exporter/%i.env
ExecStart=/usr/local/bin/prometheus-nats-exporter -%i $POINTSTRING -p $PORT "http://nats1:8222"
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure

[Install]
WantedBy=multi-user.target

* обратите внимание, что в качестве источника мы указали http://nats1:8222, а не http://localhost:8222. Это сделано для того, чтобы на сервере Prometheus мы потом смогли отделить какие метрики с каких именно серверов пришли, в противном случае все данные будут отмечаться как с сервера http://localhost:8222, что усложнит анализ. Само собой, имя nats1 должно разрешаться в адрес нашего сервера. Этого эффекта можно добиться с помощью локальной DNS или файла hosts. На каждом сервере это будет свое соответственное имя.

Создадим каталог, в котором будем хранить файлы environment:

mkdir /etc/prometheus-nats-exporter

И создадим для примера 3 файла.

Первый:

vi /etc/prometheus-nats-exporter/varz.env

PORT="9155"

Второй:

vi /etc/prometheus-nats-exporter/leafz.env

PORT="9156"

Третий:

vi /etc/prometheus-nats-exporter/jsz.env

POINTSTRING="streams"
PORT="9157"

И так, что мы сделали. Как говорилось выше, встроенный мониторинг позволяет получить несколько групп метрик, например, leafz, jsz, varz и другие. Мы предусмотрели возможность запуска сервиса для нужной группы. Но необходимо позаботиться, чтобы для нее был создан свой environment-файл, в котором мы указываем порт, на котором будет работать экспортер. Обратите внимание, что некоторые группы требуют своего аргумента, поэтому мы также обозначили его переменной POINTSTRING.

В нашем случае мы создали возможность публиковать метрики для varz, leafz и jsz на портах (соответственно) 9155, 9156 и 9157.

Теперь разрешим и запустим сервисы:

systemctl enable nats-exporter@varz --now

systemctl enable nats-exporter@leafz --now

systemctl enable nats-exporter@jsz --now

Статус сервисов можно проверить командой:

systemctl status nats-exporter@*

Также сервер должен начать слушать на портах 9155, 9156 и 9157:

ss -tunlp | grep 915[5,6,7]

Посмотреть список метрик можно командами:

curl http://127.0.0.1:9155/metrics

curl http://127.0.0.1:9156/metrics

curl http://127.0.0.1:9157/metrics

Получение метрик сервером

Если сервер Prometheus находится на другом сервере и будет забирать метрики по сети, необходимо убедиться, что брандмауэр разрешит подключение. Для этого откроем порты, на которых настроили экспортер. В нашем примере, это 9155, 9156 и 9157. 

Для разных утилит управления фаерволом это делается по-разному.

а) В iptables (как правило, для систем deb):

iptables -I INPUT 1 -p tcp --dport 9155 -j ACCEPT

iptables -I INPUT 1 -p tcp --dport 9156 -j ACCEPT

iptables -I INPUT 1 -p tcp --dport 9157 -j ACCEPT

netfilter-persistent save

б) В firewalld (как правило, для систем rpm):

firewall-cmd --permanent --add-port={9155,9156,9157}/tcp

firewall-cmd --reload

Брандмауэр настроен. Можно переходить к настройке самого сервера.

Открываем на сервере конфигурационный файл prometheus:

vi /etc/prometheus/prometheus.yml

Добавим:

  - job_name: NATS Server
    scrape_interval: 5s
    static_configs:
      - targets:
          - 192.168.0.10:9155
          - 192.168.0.10:9156
          - 192.168.0.10:9157

* предполагается, что мы добавили к мониторингу один сервер с адресом 192.168.0.10.

Перезапустим сервис prometheus:

systemctl restart prometheus

Можно проверить таргеты в Prometheus.

Grafana

Визуализировать данные метрик можно с помощью графаны. Для этого можно использовать готовые дашборды, например:

  • NATS Server Dashboard — общий мониторинг. Используем группу varz.
  • NATS JetStream — мониторинг для JetStream. Используем группу jsz.

На страницах мы можем скопировать коды для импорта дашбордов, после чего загрузить их, выбрав в качестве источников данных базу Prometheus.

Подробнее о работе с графаной читайте в инструкциях Установка и настройка сервера Grafana на Linux и Создание графиков в Grafana на основе данных из Prometheus.

# DevOps # Linux # Базы данных # Серверы
Дмитрий Моск — частный мастер
Была ли полезна вам эта инструкция?

Да            Нет