Files
IoT/legacy/doc/architecture/overview.md
T

237 lines
9.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
> ⛔⛔⛔ ЛЕГАСИ (2026-08-16) — СТАРЫЙ IoT (k8s-деплой). НЕ ПРИНИМАТЬ ВО ВНИМАНИЕ. Актуальное: HISTORY/2026-08-16-session-log.md
# IoT Managed Service — Архитектура
## Общая схема
```
IoT Device (MQTT CONNECT)
│ username="{ns}_{deviceId}", password=hex
EMQX 5.5.1 (sless/emqx)
│ POST /internal/mqtt/auth → iot-operator:9090
│ POST /internal/mqtt/acl → iot-operator:9090
│ MQTT PUBLISH → topic: "{ns}/telemetry/{deviceId}"
iot-mqtt-bridge (cmd/mqtt-bridge)
│ подписка на "+/telemetry/+"
│ → Kafka topic "iot.telemetry"
Kafka
iot-kafka-consumer (cmd/kafka-consumer)
│ consumer group "iot-pg-consumer"
│ → per-tenant Postgres DB
IoT Postgres (iot-postgres.sless.svc)
│ DB: tenant_{namespace}
│ Table: iot_telemetry
REST API (iot-operator:9090)
│ GET /v1/namespaces/{ns}/iot/telemetry
Пользователь (Terraform / UI Console)
```
## Компоненты
| Компонент | Бинарник | Порт | Назначение |
|-----------|----------|------|------------|
| iot-operator | cmd/iot-operator | :9090 (API), :8081 (health) | Controller-manager + REST API |
| mqtt-bridge | cmd/mqtt-bridge | — | MQTT→Kafka bridge |
| kafka-consumer | cmd/kafka-consumer | — | Kafka→Postgres pipeline |
## CRD
- **IoTDevice** (`iot.kube5s.ru/v1alpha1`)
- Создание: пользователь через API / Terraform
- Controller генерирует MQTT credentials → k8s Secret
- Secret удаляется каскадно через OwnerReference
## Хранение
- **IoT Postgres** — отдельный от sless PG
- Management DB: `iot_platform` (таблица `tenant_credentials`)
- Per-tenant DB: `tenant_{namespace}` (таблица `iot_telemetry`)
## Аутентификация
- REST API (/v1/): Bearer JWT (middleware.Auth)
- MQTT Auth (/internal/): вызывается EMQX, без JWT
- Admin (/iot-admin/stats): ADMIN_STATS_TOKEN
## Docker образ
- `naeel/iot-operator` (Docker Hub)
- Все 3 бинарника в одном образе
- `command: ["/iot-operator"]` или `["/mqtt-bridge"]` или `["/kafka-consumer"]`
---
## Актуальная архитектура (2026-04-12)
> Kafka заменён на shared-SQS. Postgres заменён на managed. Новый кластер iot-naeel.
### Текущая схема
```
IoT Device (MQTT CONNECT)
│ username="{ns}_{deviceId}", password=hex
EMQX 5.5.1 (sless/emqx)
│ POST /internal/mqtt/auth → iot-operator:9090
│ POST /internal/mqtt/acl → iot-operator:9090
│ MQTT PUBLISH → topic: "{ns}/telemetry/{deviceId}"
iot-mqtt-bridge (cmd/mqtt-bridge)
│ подписка на "+/telemetry/+"
│ → AWS SDK SQS SendMessage → shared-SQS (https://qu.kube5s.ru)
│ очередь: "iot-telemetry" (tenant: iot-service, id: t-96afe7e9f781f6ca)
shared-SQS (namespace shared-sqs)
│ AWS SQS-совместимый, multi-tenant
iot-sqs-consumer (cmd/sqs-consumer)
│ ReceiveMessage (WaitTimeSeconds=20, long polling)
│ DeleteMessage после успешной записи (at-least-once)
│ → per-tenant Postgres DB
Managed PostgreSQL 17 (namespace dc5db45d-f8b4-4fd0-ad33-ec4dd017f2d5)
│ Host: postgresqlk8s-master.dc5db45d-....svc.cluster.local
│ User: super, DB: sqsdb
│ Per-tenant DB: tenant_{namespace}, Table: iot_telemetry
REST API (iot-operator:9090)
│ GET /v1/namespaces/{ns}/iot/telemetry
Пользователь (Terraform / UI Console)
│ wss://iot.kube5s.ru/mqtt (WebSocket через Ingress)
│ https://iot.kube5s.ru/console (UI)
```
### Компоненты (актуальные)
| Компонент | Бинарник | Порт | Назначение |
|-----------|----------|------|------------|
| iot-operator | cmd/iot-operator | :9090 (API), :8080 (metrics), :8081 (health) | Controller-manager + REST API |
| mqtt-bridge | cmd/mqtt-bridge | — | MQTT → shared-SQS bridge |
| sqs-consumer | cmd/sqs-consumer | — | shared-SQS → Postgres pipeline |
### Инфраструктура
| Сервис | Тип | Namespace | Описание |
|--------|-----|-----------|----------|
| EMQX 5.5.1 | В кластере | sless | MQTT-брокер, HTTP auth/acl → iot-operator |
| shared-SQS | В кластере | shared-sqs | AWS SQS-совместимая очередь, endpoint https://qu.kube5s.ru |
| PostgreSQL 17 | Managed (оператор) | dc5db45d-... | per-tenant DB, тот же инстанс что и SQS billing |
| cert-manager | В кластере | cert-manager | TLS сертификаты для iot.kube5s.ru |
| nginx-ingress | В кластере | ingress | WSS/HTTPS проксирование |
### Секреты в namespace sless
| Secret | Ключи | Источник |
|--------|-------|----------|
| iot-sqs-credentials | SQS_ENDPOINT, SQS_ACCESS_KEY, SQS_SECRET_KEY | shared-SQS tenant iot-service |
| iot-postgres-secret | POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB, IOT_PG_DSN | Managed PG |
| iot-bridge-credentials | MQTT_USERNAME, MQTT_PASSWORD | Для mqtt-bridge → EMQX |
### Docker образ (актуальный)
- `naeel/iot-operator:v0.2.0` (Docker Hub)
- Все 3 бинарника в одном образе
- `command: ["/iot-operator"]` или `["/mqtt-bridge"]` или `["/sqs-consumer"]`
- Базовый: `gcr.io/distroless/static:nonroot`
### Кластер
- Имя: `iot-naeel`
- API: `https://185.247.187.149:6443`
- Ingress IP: `185.247.187.151`
- DNS: `iot.kube5s.ru → 185.247.187.147`
---
## Актуальная архитектура (2026-04-12)
> Kafka заменён на shared-SQS. Postgres заменён на managed. Новый кластер iot-naeel.
### Текущая схема
```
IoT Device (MQTT CONNECT)
│ username="{ns}_{deviceId}", password=hex
EMQX 5.5.1 (sless/emqx)
│ POST /internal/mqtt/auth → iot-operator:9090
│ POST /internal/mqtt/acl → iot-operator:9090
│ MQTT PUBLISH → topic: "{ns}/telemetry/{deviceId}"
iot-mqtt-bridge (cmd/mqtt-bridge)
│ подписка на "+/telemetry/+"
│ → AWS SDK SQS SendMessage → shared-SQS (https://qu.kube5s.ru)
│ очередь: "iot-telemetry" (tenant: iot-service, id: t-96afe7e9f781f6ca)
shared-SQS (namespace shared-sqs)
│ AWS SQS-совместимый, multi-tenant
iot-sqs-consumer (cmd/sqs-consumer)
│ ReceiveMessage (WaitTimeSeconds=20, long polling)
│ DeleteMessage после успешной записи (at-least-once)
│ → per-tenant Postgres DB
Managed PostgreSQL 17 (namespace dc5db45d-f8b4-4fd0-ad33-ec4dd017f2d5)
│ Host: postgresqlk8s-master.dc5db45d-....svc.cluster.local
│ User: super, DB: sqsdb
│ Per-tenant DB: tenant_{namespace}, Table: iot_telemetry
REST API (iot-operator:9090)
│ GET /v1/namespaces/{ns}/iot/telemetry
Пользователь (Terraform / UI Console)
│ wss://iot.kube5s.ru/mqtt (WebSocket через Ingress)
│ https://iot.kube5s.ru/console (UI)
```
### Компоненты (актуальные)
| Компонент | Бинарник | Порт | Назначение |
|-----------|----------|------|------------|
| iot-operator | cmd/iot-operator | :9090 (API), :8080 (metrics), :8081 (health) | Controller-manager + REST API |
| mqtt-bridge | cmd/mqtt-bridge | — | MQTT → shared-SQS bridge |
| sqs-consumer | cmd/sqs-consumer | — | shared-SQS → Postgres pipeline |
### Инфраструктура
| Сервис | Тип | Namespace | Описание |
|--------|-----|-----------|----------|
| EMQX 5.5.1 | В кластере | sless | MQTT-брокер, HTTP auth/acl → iot-operator |
| shared-SQS | В кластере | shared-sqs | AWS SQS-совместимая очередь, endpoint https://qu.kube5s.ru |
| PostgreSQL 17 | Managed (оператор) | dc5db45d-... | per-tenant DB, тот же инстанс что и SQS billing |
| cert-manager | В кластере | cert-manager | TLS сертификаты для iot.kube5s.ru |
| nginx-ingress | В кластере | ingress | WSS/HTTPS проксирование |
### Секреты в namespace sless
| Secret | Ключи | Источник |
|--------|-------|----------|
| iot-sqs-credentials | SQS_ENDPOINT, SQS_ACCESS_KEY, SQS_SECRET_KEY | shared-SQS tenant iot-service |
| iot-postgres-secret | POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB, IOT_PG_DSN | Managed PG |
| iot-bridge-credentials | MQTT_USERNAME, MQTT_PASSWORD | Для mqtt-bridge → EMQX |
### Docker образ (актуальный)
- `naeel/iot-operator:v0.2.0` (Docker Hub)
- Все 3 бинарника в одном образе
- `command: ["/iot-operator"]` или `["/mqtt-bridge"]` или `["/sqs-consumer"]`
- Базовый: `gcr.io/distroless/static:nonroot`
### Кластер
- Имя: `iot-naeel`
- API: `https://185.247.187.149:6443`
- Ingress IP: `185.247.187.151`
- DNS: `iot.kube5s.ru → 185.247.187.147`