Files
NODEDC_MISSION_CORE/deploy/telemetry-plane/README.md
T

102 lines
4.3 KiB
Markdown

# NDC Mission Core local telemetry plane
Portable local-only telemetry infrastructure for compute contours.
One Docker Compose project, `ndc-mission-core-telemetry`, owns three long-running
containers and one bounded bootstrap job:
- `ndc-mission-core-mqtt-broker` — Eclipse Mosquitto `2.1.2-alpine`;
- `ndc-mission-core-telemetry-timescaledb` — TimescaleDB HA OSS
`pg16.14-ts2.28.2-all-oss`;
- `ndc-mission-core-telemetry-bootstrap` — one-shot database role/bootstrap job;
- `ndc-mission-core-telemetry-normalizer` — Mission Core telemetry normalizer.
The Telegraf configuration templates cover Windows and Linux, but the agent runs as a
host service rather than inside this Compose project. This preserves access to native
Windows performance counters, Docker Desktop and NVIDIA telemetry.
The normalizer exposes a read-only normalized telemetry adapter on
`127.0.0.1:18030`. Mission Core reads this adapter; the browser never receives MQTT or
Timescale credentials, and Timescale is not published on a host port.
The normalizer uses a separate `missioncore_normalizer` database role with only
`SELECT`, `INSERT`, `UPDATE`, and bounded retention `DELETE` on the telemetry
hypertable. Raw telemetry older than 30 days is removed at most once per day by the
normalizer. This stays compatible with the Apache-licensed Timescale image without
depending on the Timescale License retention scheduler.
The stack is one deployment contour, not one multi-process container. Keeping broker,
normalizer and database in separate containers preserves independent health checks,
least-privilege boundaries and rollback while Compose provides one operator lifecycle:
```bash
docker compose ps
docker compose up -d
docker compose down
```
All NODE.DC-owned Docker objects use the lowercase `ndc-` namespace. Docker names are
case-sensitive identifiers, so the product prefix is normalized to lowercase while the
product name remains NODE.DC in operator-facing copy.
This directory does not contain credentials. Copy `.env.example` to `.env`, generate
unique passwords and build the ACL/password files before starting the stack.
```bash
uv run python prepare.py --initialize --mqtt-bind-address <MISSION_CORE_HOST_LAN_IP>
docker compose up -d --build
```
Expected Docker object names:
```text
project: ndc-mission-core-telemetry
network: ndc-mission-core-telemetry
containers:
ndc-mission-core-mqtt-broker
ndc-mission-core-telemetry-normalizer
ndc-mission-core-telemetry-timescaledb
volumes:
ndc-mission-core-mqtt-data
ndc-mission-core-telemetry-timescale-data
```
`prepare.py` passes passwords to `mosquitto_passwd` through stdin. Secrets are not placed
in process arguments or committed files. `--initialize` generates `.env` with mode
`0600` and refuses to replace existing credentials. The generated `.env` and `runtime/`
directory are ignored by Git.
The product architecture and topic contract are defined in
`docs/adr/0031-local-compute-contour-telemetry-plane.md`.
## Security boundary
The current MQTT listener is authenticated and contour-scoped, but intentionally
uses plaintext MQTT inside one owner-controlled laboratory LAN. Do not expose port
1883 through a router, cellular WAN, public Wi-Fi, or an Internet-facing host. A
remote or shared-network deployment requires a reviewed TLS listener, a private CA
distributed to every agent, and credential rotation. Wi-Fi link encryption is not a
replacement for MQTT TLS.
Each agent credential is bound to one exact
`contours/<contour-id>/agents/<agent-id>/+` prefix. Adding another contour requires
issuing another password entry and explicit ACL row; the wildcard contour writer is
not permitted.
## Worker agent
Worker 006 uses the official Windows Telegraf distribution as the host service
`NDC Mission Core Telemetry Agent`. Install or update it with:
```powershell
.\telegraf\Install-NdcMissionCoreTelegraf.ps1
.\telegraf\Update-NdcMissionCoreTelegraf.ps1
```
The update path validates the candidate configuration, backs up the active
configuration and rolls back if the service does not return to `Running`. MQTT
credentials are scoped to the service environment and must not be passed on a command
line or stored in the repository.
The stack and agent are intentionally not started by repository tests. Provisioning a
machine is a separate, explicit operation.