From 4cba163ace3c73f459f7b50a9951aa30b789bb7f Mon Sep 17 00:00:00 2001 From: Naeel Date: Sun, 12 Apr 2026 16:32:14 +0300 Subject: [PATCH] =?UTF-8?q?doc:=20=D0=B0=D0=BA=D1=82=D1=83=D0=B0=D0=BB?= =?UTF-8?q?=D1=8C=D0=BD=D0=B0=D1=8F=20=D0=B0=D1=80=D1=85=D0=B8=D1=82=D0=B5?= =?UTF-8?q?=D0=BA=D1=82=D1=83=D1=80=D0=B0,=20thinking=20log,=20=D0=BF?= =?UTF-8?q?=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=D0=B0=20=D0=A4=D0=A1=20=D0=B8=20?= =?UTF-8?q?=D0=B4=D0=BE=D0=BA=D1=83=D0=BC=D0=B5=D0=BD=D1=82=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/copilot-instructions.md | 11 +++++ doc/architecture/overview.md | 84 +++++++++++++++++++++++++++++++++ doc/thinking/2026-04-12.md | 47 ++++++++++++++++++ 3 files changed, 142 insertions(+) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index ef68ac9..59c5272 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -40,6 +40,17 @@ --- +## ⚠️ ФАЙЛОВАЯ СИСТЕМА — ОБЩАЯ + +**`~/remote_dev/` на локальной машине = `~/terra/` на ВМ. Это одна и та же файловая система (монтирование).** + +- Редактирование файлов через VS Code автоматически видно на ВМ. **НЕ копировать файлы через scp.** +- Пример: `/home/naeel/remote_dev/IoT/` === `/home/naeel/terra/IoT/` на ВМ. +- Файлы редактировать ТОЛЬКО через SSH на ВМ. НЕ использовать VS Code инструменты (replace_string_in_file, create_file и т.д.). +- Команды (git, go, docker, kubectl) — тоже ТОЛЬКО через SSH на ВМ. + +--- + ## ⚠️ ВЫПОЛНЕНИЕ КОМАНД — ТОЛЬКО НА УДАЛЁННОЙ МАШИНЕ - Все команды (git, go, docker, kubectl, make и т.д.) выполнять **ТОЛЬКО на удалённой машине** через SSH. diff --git a/doc/architecture/overview.md b/doc/architecture/overview.md index c9124cd..7454e7c 100644 --- a/doc/architecture/overview.md +++ b/doc/architecture/overview.md @@ -148,3 +148,87 @@ REST API (iot-operator:9090) - 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` diff --git a/doc/thinking/2026-04-12.md b/doc/thinking/2026-04-12.md index 630d1a8..6e17073 100644 --- a/doc/thinking/2026-04-12.md +++ b/doc/thinking/2026-04-12.md @@ -122,3 +122,50 @@ - `iot-sqs-consumer` — подключён к PG и SQS, polling loop активен TLS сертификат для `iot.kube5s.ru` выпускается cert-manager. + +--- + +## Сессия 2 — Агент: GitHub Copilot (Claude Opus 4.6) + +### Контекст +Продолжение деплоя после замены Kafka→SQS. Новый кластер iot-naeel, namespace sless пустой. + +### Что обнаружил +1. kubeconfig токен истёк (JWT TTL=24ч) — пользователь обновил вручную +2. Kafka отсутствует в кластере — уже нет, удалять нечего +3. Namespace sless создан в предыдущей сессии, но пуст (только Secret iot-sqs-credentials) +4. IoT Postgres: пользователь указал использовать managed PG из SQS-service (не self-hosted) + - Креды в /home/naeel/terra/SQS-service/secrets/iot_pg.md + - Host: postgresqlk8s-master.dc5db45d-f8b4-4fd0-ad33-ec4dd017f2d5.svc.cluster.local + - PG17, managed через оператор +5. EMQX: deployment-файла не было в IoT-репе, адаптировал из sless + - Ключевое: auth URL `sless-operator` → `iot-operator` +6. iot-operator deployment: не было, создал с нуля (RBAC, ServiceAccount, ClusterRole) + +### Что сделал +1. Обновил image во всех deployments: pearlharbor → Docker Hub naeel/iot-operator:v0.2.0 +2. Убрал imagePullSecrets (Docker Hub публичный) +3. Собрал Docker образ на ВМ, запушил в Docker Hub (v0.2.0 + latest) +4. Обновил iot-postgres.yaml: убрал self-hosted Deployment/Service, оставил только Secret с managed PG DSN +5. Создал emqx.yaml (EMQX 5.5.1 + ConfigMap + Service, auth→iot-operator) +6. Создал emqx-ws-ingress.yaml (ws Ingress + TLS cert-manager) +7. Создал iot-operator.yaml (ServiceAccount + ClusterRole + ClusterRoleBinding + Deployment + Service) +8. Установил CRD iotdevices.iot.kube5s.ru +9. Создал секреты: iot-postgres-secret, iot-bridge-credentials +10. Задеплоил всё: EMQX → operator → mqtt-bridge → sqs-consumer +11. Все 4 пода Running 1/1, логи чистые + +### Ошибки по ходу +- Пытался редактировать файлы локально через VS Code tools вместо SSH на ВМ — нарушение правил +- Пытался копировать файлы через scp — не нужно, ~/remote_dev/ = ~/terra/ (одна ФС) +- Правило записано в copilot-instructions.md и в memory + +### Результат +Полный IoT стек развёрнут в кластере iot-naeel: +- EMQX (MQTT :1883, WS :8083) → iot-operator (auth/acl, API :9090) +- mqtt-bridge (MQTT→SQS) → sqs-consumer (SQS→Postgres) +- Managed PG17, shared-SQS, cert-manager TLS +- Ingress: wss://iot.kube5s.ru/mqtt, https://iot.kube5s.ru/console + +### Следующий шаг +E2E тест: создать устройство → MQTT publish → проверить SQS → Postgres → API.