118 lines
7.5 KiB
Markdown
118 lines
7.5 KiB
Markdown
# IoT Demo — Nubes Cloud
|
||
|
||
Демо-стенд «Умный дом»: 6 сервисов Nubes Cloud, развёртывание через Terraform.
|
||
|
||
## Пайплайн данных
|
||
|
||
Эмуляция IoT-датчиков «Умного дома»: температура, влажность, энергопотребление.
|
||
|
||
```
|
||
┌──────────┐ AMQP ┌──────────┐ AMQP ┌──────────┐
|
||
│ Producer │ ──────────→ │ RabbitMQ │ ──────────→ │ Consumer │
|
||
│ Node.js │ iot-events │ (очередь)│ iot-events │ Node.js │
|
||
└──────────┘ └──────────┘ └────┬─────┘
|
||
│
|
||
┌────────────────────────┼────────────────────────┐
|
||
│ запись │ запись │
|
||
▼ ▼ ▼
|
||
┌──────────┐ ┌──────────┐ ┌──────────┐
|
||
│ Redis │ │ MongoDB │ │ Redis │
|
||
│ latest │ │ архив │ │ counters │
|
||
│ recent │ │ (7 дн.) │ │ │
|
||
└────┬─────┘ └──────────┘ └────┬─────┘
|
||
│ │
|
||
│ ┌────────────────────────────────────┘
|
||
│ │ чтение
|
||
▼ ▼
|
||
┌──────────────┐
|
||
│ Dashboard │
|
||
│ Node.js + │
|
||
│ Chart.js │
|
||
└──────────────┘
|
||
```
|
||
|
||
| # | Сервис | Тип Nubes | Что делает |
|
||
|---|---|---|---|
|
||
| 1 | **Producer** | Node.js (22) | Генерирует случайные события от 8 датчиков (3 типа: температура °C, влажность %, энергопотребление kW). Раз в 3 секунды отправляет JSON-событие в очередь RabbitMQ `iot-events`. |
|
||
| 2 | **RabbitMQ** | RabbitMQ | Очередь сообщений AMQP. Держит события, пока Consumer не заберёт. `durable: true` — сообщения переживают рестарт брокера. |
|
||
| 3 | **Consumer** | Node.js (22) | Читает очередь RabbitMQ. Каждое событие пишет параллельно в Redis (оперативный кэш: последние значения + счётчики + лента) и MongoDB (постоянный архив с TTL 7 дней). |
|
||
| 4 | **Redis** | Redis | Кэш для Dashboard: `iot:latest` (hash — актуальные значения датчиков), `iot:counters` (hash — счётчики по типам), `iot:recent` (zset — лента 1000 событий). |
|
||
| 5 | **MongoDB** | MongoDB | Архив всех событий в коллекции `iot_events`. TTL-индекс на 7 дней — автоочистка. |
|
||
| 6 | **Dashboard** | Node.js (22) | Веб-интерфейс. Читает только Redis, отдаёт JSON-API и HTML с графиками Chart.js (bar chart значений, doughnut счётчиков, таблица событий). Автообновление каждые 3 сек. |
|
||
|
||
Все соединения между сервисами — внутренние, через K8s Service (`.svc.cluster.local`). Наружу торчат только HTTP-эндпоинты Node.js-приложений.
|
||
|
||
## Быстрый старт
|
||
|
||
### 1. Скопировать и заполнить `terraform.tfvars`
|
||
|
||
```bash
|
||
cp terraform.tfvars.example terraform.tfvars
|
||
```
|
||
|
||
```hcl
|
||
api_token = "xxx" # API-токен из ЛК Nubes
|
||
realm = "k8s-4-sandbox-nubes-ru" # Ваш K8s-кластер
|
||
api_endpoint = "https://lk-api-gateway-test.ngcloud.ru/api/v1/svc"
|
||
```
|
||
|
||
### 2. Заменить обязательные параметры в `locals.tf`
|
||
|
||
| Параметр | Что писать |
|
||
|---|---|
|
||
| `prod_git_path` | URL вашего форка producer в Gitea |
|
||
| `cons_git_path` | URL вашего форка consumer в Gitea |
|
||
| `dash_git_path` | URL вашего форка dashboard в Gitea |
|
||
| `prod_domain` | **Уникальный** поддомен для producer |
|
||
| `cons_domain` | **Уникальный** поддомен для consumer |
|
||
| `dash_domain` | **Уникальный** поддомен для dashboard |
|
||
| `prod_resource_name` | Имя инстанса producer в кабинете Nubes |
|
||
| `cons_resource_name` | Имя инстанса consumer |
|
||
| `dash_resource_name` | Имя инстанса dashboard |
|
||
|
||
> ⚠️ Домены (поддомены `.nodejsk8s.dev.nubes.ru`) должны быть **уникальны** в рамках кластера. Занятый домен — ошибка при деплое.
|
||
|
||
### 3. Деплой
|
||
|
||
```bash
|
||
terraform init
|
||
terraform apply
|
||
```
|
||
|
||
### 4. Проверка
|
||
|
||
```bash
|
||
curl https://<prod_domain>.nodejsk8s.dev.nubes.ru # → {"events_sent": N, "errors": 0}
|
||
curl https://<cons_domain>.nodejsk8s.dev.nubes.ru # → {"consumed": N, "errors": 0}
|
||
# Dashboard: открыть https://<dash_domain>.nodejsk8s.dev.nubes.ru в браузере
|
||
```
|
||
|
||
## Репозитории приложений
|
||
|
||
Код каждого приложения — отдельный репо. Склонируйте/форкните к себе в Gitea.
|
||
|
||
| Приложение | Репо | Стек |
|
||
|---|---|---|
|
||
| Producer | [`Nail/tf-iot-producer`](https://gitea.services.ngcloud.ru/Nail/tf-iot-producer) | Node.js + amqplib |
|
||
| Consumer | [`Nail/tf-iot-consumer`](https://gitea.services.ngcloud.ru/Nail/tf-iot-consumer) | Node.js + amqplib + redis + mongodb |
|
||
| Dashboard | [`Nail/tf-iot-dashboard`](https://gitea.services.ngcloud.ru/Nail/tf-iot-dashboard) | Node.js + express + redis + Chart.js |
|
||
|
||
## Файлы
|
||
|
||
| Файл | Назначение |
|
||
|---|---|
|
||
| `main.tf` | Провайдер, переменные |
|
||
| `locals.tf` | **Все настройки** — менять здесь |
|
||
| `infra.tf` | RabbitMQ + Redis + MongoDB |
|
||
| `producer.tf` | Node.js producer |
|
||
| `consumer.tf` | Node.js consumer |
|
||
| `dashboard.tf` | Node.js dashboard |
|
||
| `terraform.tfvars.example` | Шаблон секретов |
|
||
|
||
## Примечания
|
||
|
||
- **MongoDB без пароля** — для демо. В проде настроить аутентификацию.
|
||
- **`adopt_existing_on_create = true`** — повторный `apply` подхватывает существующие инстансы.
|
||
- **`suspend_on_destroy = true`** — `destroy` не удаляет, а засыпает (suspend).
|
||
- Все внутренние соединения — K8s Service (`.svc.cluster.local`).
|