
Привет! Меня зовут Дмитрий, я старший системный инженер в Selectel, работаю с серверами и клиентским оборудованием.
Ранее я написал статью о том, как появилась идея создать бота на базе API Telegram, который анализирует показатель S.M.A.R.T дисков. Теперь более детально расскажу о его разработке и о том, как было развернуто приложение.
Перед тем как мы погрузимся в детали, добавлю, что у меня нет опыта коммерческой разработки и администрирования инфраструктуры. В сети довольно много информации о том, как это делать в теории, но мало практических материалов для выхода на уровень продакшена.
Как системный инженер я изучаю новые вещи «методом тыка». Поэтому все представленные сборки приложения и способы его развертывания основаны на личном опыте и умении искать информацию в сети, а также применении «метода тыка» для получения конечного результата.
Воспользуйтесь навигацией, чтобы выбрать интересующий вас блок:
→ Инфраструктура
→ Разработка
→ Заключение
Инфраструктура
Важный аспект при планировании инфраструктуры приложения — ее готовность к будущему масштабированию. Начнем с визуализации и описания схемы взаимодействия компонентов.

Основные компоненты модели взаимодействия:
- Сервер: виртуальная машина с двумя vCPU, 4 ГБ ОЗУ и 10 ГБ SSD. Операционная система — Ubuntu 22.04.
- Внутрикорпоративные сервисы Selectel: сервисы с содержанием актуальных данных S.M.A.R.T и пользователей, которые могут с ними взаимодействовать.
- Telegram: интеграция с Telegram API для уведомлений и связи с пользователями.
- Сеть: задает связи между компонентами.
- Инженер: имеет доступ в ОС через SSH-ключ и на веб-панель Portainer.
Сервер
Сервер — ключевая часть инфраструктуры, я развернул его в облаке Selectel. В качестве ОС выбрал Ubuntu 22.04.

> root@server:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 10G 0 disk
├─sda1 8:1 0 10G 0 part /
└─sda14 8:14 0 8M 0 part
sr0 11:0 1 492K 0 rom
Сетевые интерфейсы
IP-адрес сервера — 172.168.1.1.
> ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether fa:16:3e:a9:a5:8a brd ff:ff:ff:ff:ff:ff
altname enp0s3
altname ens3
inet 172.168.1.1/24 brd 172.168.1.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::f816:3eff:fea9:a58a/64 scope link
valid_lft forever preferred_lft forever
Настройка SSH-доступа
В данном примере SSH-ключ копируется на сервер для безопасного доступа. Также изменяется конфигурация SSH для отключения входа по паролю.
ssh-copy-id</i> <i>root@172.168.1.1
> sed -i 's/#PermitRootLogin.*/PermitRootLogin yes/g' /etc/ssh/sshd_config
> sed -i 's/PasswordAuthentication.*/PasswordAuthentication no/g' /etc/ssh/sshd_config
> systemctl restart sshd
Все шаги по развертыванию приложения будем выполнять с использованием Ansible.
Установим Ansible на локальную операционную систему
> apt-add-repository ppa:ansible/ansible
> apt update
> apt install ansible -y
> ansible --version
ansible [core 2.15.2]
config file = /etc/ansible/ansible.cfg
configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3/dist-packages/ansible
ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/bin/ansible
python version = 3.10.12 (main, Jun 11 2023, 05:26:28) [GCC 11.4.0] (/usr/bin/python3)
jinja version = 3.0.3
libyaml = True
В файле определяем удаленный хост srv-smart. ansible/hosts
[servers]
srv-smart ansible_host=172.168.1.1
[all:vars]
ansible_python_interpreter=/usr/bin/python3
Проверяем доступность удаленного хоста.
> ansible srv-smart -m ping
srv-smart | SUCCESS => {
"changed": false,
"ping": "pong"
}
На схеме взаимодействия указаны:
Порт 22
— для удаленного доступа к серверу по SSH,eth0
— интерфейс, на который подан VLAN для связи с внешней и внутренней сетями сервисов Selectel.
Для развертывания приложения использую Docker, в котором работают три контейнера:
portainer
— для запуска Portainer, который позволяет управлять контейнерами в Docker,mongodb
— для развертывания MongoDB,service
— для запуска сервисов приложения на Node.js.
Сначала клонируем репозиторий на локальную ОС.
> git clone git@bitbucket.org:khamchenko/smart-slc.git
> curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
> echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
> apt update
> apt-cache policy docker-ce
> apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin
Проверяем статус.
> systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2023-06-06 15:55:44 UTC; 30s ago
TriggeredBy: ● docker.socket
Docs: https://docs.docker.com
Main PID: 3371 (dockerd)
Tasks: 9
Memory: 27.1M
CPU: 706ms
CGroup: /system.slice/docker.service
└─3371 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
> docker -v
Docker version 24.0.5, build ced0996
Редактируем переменные окружения в файле smart-slc/docker.infra/.env
.
MONGO_USER=<mongo-user>
MONGO_PASS_PROD=<mongo-pass-prod>
MONGO_PASS_DEV=<mongo-pass-dev>
MONGO_DB=<mongo-db>
MONGO_INITDB_ROOT_USERNAME=<mongo-root>
MONGO_INITDB_ROOT_PASSWORD=<mongo-root-pass>
MONGO_INITDB_DATABASE=<mongo-init-db>
TG_TOKEN=<tg-token-jwt>
JWT_SECRET=<jwt-secret>
TELEGRAM_TOKEN_DEV=<tg-token-dev>
TELEGRAM_TOKEN_PROD=<tg-token-prod>
Для сборки приложения используется webpack. Для этого выделили отдельный контейнер nodejs-build
, который содержит окружение node.js.
> cd ./smart-slc/docker.infra/nodejs-build
> docker compose up -d
> bash build-prod.sh
Запускаем Ansible-плейбук для развертывания инфраструктуры на удаленном хосте srv-smart
.
> ansible-playbook docker.infra/ansible/srv-smart/main/pb_main.yml
После развертывания на удаленном хосте проверяем статус контейнеров.
> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
adb13e7089d8 mongo:latest "docker-entrypoint.s…" 33 seconds ago Up 32 seconds 0.0.0.0:35689->27017/tcp, :::35689->27017/tcp mongodb
b6c3e9e2fdfe nodejs-nodejs "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 0.0.0.0:5001-5002->5001-5002/tcp, :::5001-5002->5001-5002/tcp services
694bb2e80cb5 portainer/portainer-ce:latest "/portainer" 18 minutes ago Up 18 minutes 8000/tcp, 9000/tcp, 0.0.0.0:9443->9443/tcp, :::9443->9443/tcp portainer
Контейнер Portainer
Portainer.io предоставляет средство управления Docker-контейнерами. Рассмотрим его структуру и взаимодействие с другими контейнерами.
Подсеть (172.18.0.0/16)
с названиемnetwork-smart
создана для связи между контейнерамиmongodb
иservices
, обеспечивая их взаимодействие.Подсеть (172.17.0.0/16) bridge
.Порт 9443
предоставляет внешний доступ к веб-интерфейсу Portainer.
Конфигурационный файл docker-compose.yml
.
version: "3.8"
services:
portainer:
image: portainer/portainer-ce:latest
container_name: portainer
hostname: portainer
restart: always
ports:
- 9443:9443
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- {{ path_infra }}/smart-slc/portainer/data:/data
Переходим в браузерной строке на https://172.168.1.1:9443 и задаем username
и password
.

Проверим список запущенных контейнеров.

Проверим подключение к базе данных извне с помощью MongoDB Compass.


Файл конфигурации контейнера docker-compose.yml
.
version: "3.8"
services:
portainer:
image: portainer/portainer-ce:latest
container_name: portainer
hostname: portainer
restart: always
ports:
- 9443:9443
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- {{ path_infra }}/smart-slc/portainer/data:/data
Контейнер MongoDB
Представляет собой NoSQL базу данных MongoDB. В этом контейнере созданы коллекции users (пользователи) и devices (устройства). Более подробно со схемами коллекций можно ознакомиться здесь. Давайте рассмотрим структуру контейнера и проверим работу.
На схеме указаны:
Порт 35689
— используется для подключения к базе данных,- связь с контейнером
services
осуществляется через сетьnetwork-smart
.
docker-compose.yml
.
version: "3.8"
services:
mongodb:
image: mongo:latest
container_name: mongodb
hostname: mongodb
restart: always
env_file: [.env]
ports:
- 35689:27017
volumes:
- {{ path_infra }}/smart-slc/mongodb/data:/data/db/
- {{ path_infra }}/smart-slc/mongodb/init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js
networks:
- network-smart
logging:
options:
max-size: "200k"
max-file: "3"
networks:
network-smart:
external: true
Проверяем версию установленной Mongodb
.
> docker exec -it mongodb /bin/bash
> mongosh
Current Mongosh Log ID: 64d7802347ddb6a2ae56c7b0
Connecting to: mongodb://127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+1.10.1
Using MongoDB: 6.0.8
Using Mongosh: 1.10.1
Проверим подключение к базе данных извне с помощью MongoDB Compass.

Контейнер Services
Представляет собой среду node.js с пакетом pm2. Внутри контейнера запущены следующие компоненты приложения:
workers-smart
— обработчики для синхронизации MongoDB с БД Selectel и синхронизации пользователей во внутренних сервисах,srv-smart
— обработчик для анализа информации S.M.A.R.T.,tg-smart
— обработчик событий Telegram.
docker-compose.yml
.
version: "3.8"
services:
mongodb:
image: mongo:latest
container_name: mongodb
hostname: mongodb
restart: always
env_file: [.env]
ports:
- 35689:27017
volumes:
- {{ path_infra }}/smart-slc/mongodb/data:/data/db/
- {{ path_infra }}/smart-slc/mongodb/init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js
networks:
- network-smart
logging:
options:
max-size: "200k"
max-file: "3"
networks:
network-smart:
external: true
Файл Dockerfile
с инструкциями для создания образа контейнера.
FROM node:18.14.0
RUN npm install pm2 -g
Файл init-node.sh
для запуска сервисов.
#!/bin/bash
docker exec -it services /bin/bash -c "cd /srv/tg-smart && npm install"
docker exec -it services /bin/bash -c "cd /srv/srv-smart && npm install"
docker exec -it services /bin/bash -c "cd /srv/workers-smart && npm install"
docker exec -it services /bin/bash -c "pm2 start"
docker exec -it services /bin/bash -c "pm2 save"
Файл upd-build.sh
для перезапуска сервисов после повторной сборки.
docker exec -it services /bin/bash -c "cd /srv/tg-smart && npm install && pm2 restart srv-smart"
docker exec -it services /bin/bash -c "cd /srv/srv-smart && npm install && pm2 restart smart-slc"
docker exec -it services /bin/bash -c "cd /srv/workers-smart && npm install && pm2 restart workers-smart"
Файл конфигурации pm2 ecosystem.config.js
.
module.exports = {
apps : [{
name: "tg-smart",
script: "/srv/tg-smart/api.prod.js"
},{
name: "srv-smart",
script: "/srv/srv-smart/api.prod.js"
},{
name: "workers-smart",
script: "/srv/workers-smart/api.prod.js"
}]
}
Проверяем работу сервисов.
docker exec -it services bash
> root@services:/# pm2 status

> root@services:/# pm2 monit

Схема связей:
Порты 5001-5003
используются для внутреннего взаимодействия.- Связь
tg-smart
иsrv-smart
осуществляется через socket.io для доставки сообщений. - Связь
mongodb-smart
иsrv-smart
. - Cвязь
mongodb-smart
иtg-smart
. - Cвязь
mongodb-smart
иworkers-smart
— для синхронизации пользователей и пороговых значений S.M.A.R.T. - Cвязь
worker-smart
ивнутрикорпоративных сервисов Selectel
. - Связь
tg-smart
иTelegram
.
Внутрикорпоративные сервисы Selectel
Доступ к сервисам Selectel строго ограничен правами группы доступа. Для управления логикой взаимодействия с сервисами создал контейнеры mongodb
и services
. Сервис workers-smart
выполняет эту логику взаимодействия, а база данных MongoDB
хранит пороговые значения S.M.A.R.T и информацию о пользователях.
Telegram
Для взаимодействия с Telegram API использую npm-пакет node-telegram-bot-api. В составе сборки сервиса tg-smart
он обрабатывает логику подключения к Telegram.
Сеть
Как я описал выше, отдельные компоненты инфраструктуры имеют связи. Они обусловлены организацией сети на уровне Docker и самой ОС. Доступ извне ограничен правилами iptables и ufw.
Текущий вывод iptables после запуска контейнеров Docker.
>iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy DROP)
target prot opt source destination
DOCKER-USER all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-1 all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain DOCKER (2 references)
target prot opt source destination
ACCEPT tcp -- anywhere 172.17.0.2 tcp dpt:9443
ACCEPT tcp -- anywhere 172.18.0.2 tcp dpt:5002
ACCEPT tcp -- anywhere 172.18.0.2 tcp dpt:5001
ACCEPT tcp -- anywhere 172.18.0.3 tcp dpt:27017
Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target prot opt source destination
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
RETURN all -- anywhere anywhere
Chain DOCKER-ISOLATION-STAGE-2 (2 references)
target prot opt source destination
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
RETURN all -- anywhere anywhere
Chain DOCKER-USER (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere
Проверим сетевые интерфейсы.
>ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether fa:16:3e:a9:a5:8a brd ff:ff:ff:ff:ff:ff
altname enp0s3
altname ens3
inet 172.168.1.1/24 brd 172.168.1.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::f816:3eff:fea9:a58a/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:06:d0:81:b1 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:6ff:fed0:81b1/64 scope link
valid_lft forever preferred_lft forever
4: br-6bf419f6296f: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:e0:a6:17:ae brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.18.255.255 scope global br-6bf419f6296f
valid_lft forever preferred_lft forever
inet6 fe80::42:e0ff:fea6:17ae/64 scope link
valid_lft forever preferred_lft forever
5: br-7a47cf77f7b2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:b8:d1:fc:36 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.1/16 brd 172.19.255.255 scope global br-7a47cf77f7b2
valid_lft forever preferred_lft forever
inet6 fe80::42:b8ff:fed1:fc36/64 scope link
valid_lft forever preferred_lft forever
25: veth011a094@if24: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-6bf419f6296f state UP group default
link/ether ba:5e:30:fe:7e:b9 brd ff:ff:ff:ff:ff:ff link-netnsid 2
inet6 fe80::b85e:30ff:fefe:7eb9/64 scope link
valid_lft forever preferred_lft forever
27: veth664666f@if26: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-7a47cf77f7b2 state UP group default
link/ether 92:81:05:84:5b:8e brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::9081:5ff:fe84:5b8e/64 scope link
valid_lft forever preferred_lft forever
29: veth373aaf8@if28: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-6bf419f6296f state UP group default
link/ether ea:71:35:2a:9f:fb brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet6 fe80::e871:35ff:fe2a:9ffb/64 scope link
valid_lft forever preferred_lft forever
В файл добавим правила. ufw/after.rules
*filter
:DOCKER-USER - [0:0]
:ufw-user-input - [0:0]
-A DOCKER-USER -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A DOCKER-USER -m conntrack --ctstate INVALID -j DROP
-A DOCKER-USER -i eth0 -j ufw-user-input
-A DOCKER-USER -i eth0 -j DROP
COMMIT
Далее выполняем команды для перезапуска службы ufw
, открытия портов 22
и 9443
и включения ufw
.
> systemctl restart ufw
> ufw allow 22
> ufw allow 9443
> ufw enable
Результат сканирования портов.
> nmap -p- 172.168.1.1
Nmap scan report for 172.168.1.1 Host is up (0.030s latency). Not shown: 65533 filtered tcp ports (no-response) PORT STATE SERVICE 22/tcp open ssh 9443/tcp open tungsten-https
Инженер
Роль инженера в данной схеме описывает его взаимодействие с компонентами инфраструктуры:
- доступ в ОС через SSH-ключ;
- доступ к веб-интерфейсу Portainer.

Разработка
Предлагаю пройтись по основным моментам разработки.
Что использовал?
koa.js, axios, lodash, moment, mongoose, nodemon, uuid, babel, webpack, jwt, socket.io, node-telegram-bot-api

Ниже вы можете кратко ознакомиться с некоторыми деталями.
webpack
Сборщик модулей, который используется для упаковки и оптимизации кода приложения. Подробнее с конфигурацией можно ознакомиться в репозитории.
mongoose
Библиотека для работы с MongoDB. Используется для определения объектов со строго типизированной схемой, соответствующей документам MongoDB.
Подробнее со схемами коллекции устройств и пользователей можно ознакомиться в репозитории. Для подключения к MongoDB используется метод mongoConnection.
koa.js
Фреймворк для Node.js, используемый как middleware. Обеспечивает гибкость разработки и масштабируемость, минимизируя объем ресурсов для запуска.
socket.io
Библиотека на основе протокола WebSocket. Используется для обмена сообщениями между сервисами tg-smart
и srv-smart
.
Структура
.
├── .env // константы окружения
├── .babelrc // конфигурационный файл babel
├── api
│ ├── api.prod.js // build
│ ├── app.js // основной файл приложения на koa.js.
│ ├── server.js // точка входа в приложение
│ ├── collection // доступ к коллекциям mongodb
│ ├── config // формирование констант из окружения и конфигурационных файлов
│ ├── connectors // подключения к базам данных и другим сервисам
│ ├── constants // константы окружения
│ ├── handlers // обработчики ошибок и другие обработчики
│ ├── helpers // вспомогательные функции и классы
│ ├── services // вспомогательные методы для работы с данными
│ ├── socket // логика подключения socket.io
│ └── utils // утилиты для работы с окружением
├── config // содержит конфигурационные объект
├── package.json // зависимости
├── schemes // содержит схемы для работы с данными MongoDB
└── webpack // содержит конфигурационный файл webpack для сборки модулей
Сборка workers-smart
Я уже писал, что опущу подробности о сервисе workers-smart, так как его главная функция заключается в синхронизации с сервисами Selectel. Конкретно он занимается обновлением текущих пороговых значений атрибутов S.M.A.R.T в базе данных MongoDB. Детали его реализации находятся внутри нашего закрытого окружения и остаются в рамках строгой политики конфиденциальности и безопасности данных.
Сборка tg-smart
Подробнее ознакомиться с данной сборкой можно в репозитории. Этот сервис выделен в отдельный модуль, что обеспечивает удобство масштабирования приложения в будущем. Главные задачи tg-smart — это управление пользовательским интерфейсом, трансляция сообщений от других сервисов и проверка подлинности пользователей.
Благодаря использованию транспорта socket.io впоследствии появится возможность декомпозировать приложение на функциональные части и распределять нагрузку между различными сервисами.
tg-smart
через socket.io. Также в коде файла осуществляется подписка на события состояния соединения с другими сервисами через socket.io. Подключение к Telegram API реализуется через библиотеку node-telegram-bot-api.
При подключении сервиса srv-smart
сначала проверяется валидность токена с помощью метода jwt.verify. После успешной проверки сервис присоединяется к комнате “service”
в socket.io и ожидает сообщения для передачи в Telegram от других сервисов.
В этой части кода реализована подписка на событие “message”
от Telegram. Когда сообщение поступает, происходит проверка наличия пользователя в базе данных. Если пользователь уже существует, отправляется сообщение сервису srv-smart
через socket.io. В случае отсутствия пользователя он создается в базе данных, и ему отправляется приветственное сообщение, аналогичное тому, что генерируется при отправке события “/start”
. Обработка события “/start”
также предусматривает свой обработчик, который будет использоваться для отрисовки будущего меню.
Сборка srv-smart
Подробнее ознакомиться с этим сервисом можно в репозитории. Данный компонент инфраструктуры занимается обработкой входящих сообщений и предоставляет информацию о состоянии атрибутов S.M.A.R.T.
“message”
от сервиса tg-smart
. Когда происходит получение сообщения, важно учесть, что информация о состоянии атрибутов S.M.A.R.T может быть представлена несколькими сообщениями.
Для обработки этой ситуации используется механизм таймаута. Как только приходит сообщение, запускается таймаут длительностью одну секунду, в течение которого от пользователя ожидается следующее сообщение. При этом сообщение сохраняется в базе данных вместе с идентификатором таймера. Если в течение этой секунды не поступает новое сообщение, таймаут обнуляется, а все данные, связанные с ним, также удаляются из базы данных. Когда собирается достаточное количество информации, производится анализ сообщений на наличие данных о состоянии атрибутов S.M.A.R.T с помощью метода checkSmart.
Наконец, метод checkSmart выполняет анализ показателей S.M.A.R.T и определяет общий статус диска. После формирования ответа происходит вызов метода sendMessage для отправки сообщения в сервис tg-smart
, которое затем передается в чат Telegram.
Заключение
Вот так устроен и работает созданный бот для проверки дисков. Могу предположить, что появится вопрос про пороговые значения — отвечу сразу.
Я понимаю, что вопрос пороговых значений атрибутов S.M.A.R.T вызывает интерес. Но Selectel придерживается строгой политики конфиденциальности и безопасности данных. В связи с этим мы не можем раскрыть подробные пороговые значения по каждой модели накопителя. Вы можете настроить свои системы мониторинга, исходя из базовых параметров, которые я указал в прошлой статье.
Описанный бот — небольшая функциональность, которая облегчает жизнь инженерам дата-центров. Возможности мониторинга состояния инфраструктуры для клиентов мы реализуем на другом уровне. Сейчас мы рассматриваем возможность добавления новых функциональностей и улучшений в ближайшем будущем, в том числе за счет внедрения модуля IPMI. Это даст пользователям еще больше инструментов для мониторинга и управления своими ресурсами.
Другие полезные материалы
Автор: Дмитрий