diagrams and binaries
This commit is contained in:
1 parent
7e44db87b2
commit
f81285b151
7 files changed
+293
-15
No files matched your search
@@ -0,0 +1,207 @@
|
||||
# Диаграммы потоков данных
|
||||
|
||||
Три диаграммы, поясняющие устройство системы на уровне потоков данных —
|
||||
дополнение к [API.md](API.md) (протокол) и [USAGE.md](USAGE.md) (работа
|
||||
оператора). Диаграммы — в формате Mermaid, рендерятся нативно на
|
||||
GitHub/GitLab и в большинстве современных Markdown-просмотрщиков.
|
||||
|
||||
## Как читать диаграммы
|
||||
|
||||
Единое условное обозначение стрелок для всех диаграмм:
|
||||
|
||||
| Обозначение | Значение |
|
||||
|---|---|
|
||||
| `-->` тонкая сплошная | Управляющий вызов / API-запрос |
|
||||
| `-.->` пунктирная | Ответ, уведомление, асинхронный результат |
|
||||
| `==>` жирная сплошная | Реальный сетевой трафик проверки (data-plane) — именно то, что валидируется, а не служебный вызов |
|
||||
|
||||
## Содержание
|
||||
|
||||
- [1. Control plane сервиса](#1-control-plane-сервиса)
|
||||
- [2. Поток данных: от валидатора к целевому серверу (egress-проверка)](#2-поток-данных-от-валидатора-к-целевому-серверу-egress-проверка)
|
||||
- [3. Поток данных телеметрии](#3-поток-данных-телеметрии)
|
||||
|
||||
---
|
||||
|
||||
## 1. Control plane сервиса
|
||||
|
||||
Кто кем управляет и через какой канал: конфигурация оператора, HTTP API
|
||||
control-api, фоновый оркестратор, база данных, вызовы к OpenStack и опрос
|
||||
со стороны validator-agent/prober.
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph OP["Оператор"]
|
||||
CFG["control-api.yaml<br/>(validators, sites, targets,<br/>ip_addresses, check_types)"]
|
||||
ENV["control-api.env<br/>(OS_AUTH_URL, OS_TOKEN, ...)"]
|
||||
ADMIN["curl /api/v1/admin/*"]
|
||||
end
|
||||
|
||||
subgraph CAPI["control-api (управляющая машина, 1 экземпляр)"]
|
||||
HTTP["HTTP API<br/>/api/v1/agents/*<br/>/api/v1/probers/*<br/>/api/v1/admin/*<br/>/healthz · /whatsmyip"]
|
||||
ORCH["Оркестратор: Tick раз в<br/>poll_interval_seconds<br/>claim → associate FIP →<br/>ожидание self-check →<br/>checking → aggregate → release<br/>+ lease sweep + heartbeat sweep"]
|
||||
DB[("SQLite<br/>validators / ip_queue<br/>checks / events")]
|
||||
OSCLIENT["OpenStack-клиент<br/>(mode: mock | real)"]
|
||||
end
|
||||
|
||||
OS["OpenStack Neutron<br/>Floating IP API"]
|
||||
|
||||
VA["validator-agent ×N<br/>(на каждой ВМ-валидаторе)"]
|
||||
PR["prober ×3<br/>(на каждой внешней площадке)"]
|
||||
|
||||
CFG -->|"читается при старте<br/>(инициализация validators, ip_queue)"| CAPI
|
||||
ENV -->|"переменные окружения процесса"| OSCLIENT
|
||||
ADMIN --> HTTP
|
||||
HTTP --> ORCH
|
||||
ORCH <--> DB
|
||||
ORCH --> OSCLIENT
|
||||
OSCLIENT -->|"associate / disassociate<br/>floating ip"| OS
|
||||
|
||||
VA <-->|"register, heartbeat,<br/>GET assignment,<br/>POST self-check/events/<br/>results/complete"| HTTP
|
||||
PR <-->|"register,<br/>GET assignments,<br/>POST results"| HTTP
|
||||
```
|
||||
|
||||
**Пояснение.** `control-api` — единственный компонент с состоянием и
|
||||
единственная точка принятия решений (какой IP кому назначить, когда
|
||||
считать проверку завершённой). Конфигурация читается один раз при
|
||||
старте процесса (горячей перезагрузки нет — изменения требуют
|
||||
`systemctl restart control-api`, см. [SETUP.md](SETUP.md)). Оркестратор
|
||||
работает по таймеру независимо от HTTP-запросов — назначение IP
|
||||
валидаторам и агрегация результатов не привязаны к конкретному входящему
|
||||
запросу, а выполняются фоновым циклом `Tick`. `validator-agent` и
|
||||
`prober` — активная сторона: они сами инициируют все HTTP-запросы к
|
||||
control-api (pull-модель), сам control-api к ним не обращается.
|
||||
|
||||
---
|
||||
|
||||
## 2. Поток данных: от валидатора к целевому серверу (egress-проверка)
|
||||
|
||||
Как валидатор проверяет, что через назначенный ему публичный адрес
|
||||
реально работает исходящий доступ в интернет.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph VM["ВМ-валидатор (сервисный проект OpenStack)"]
|
||||
AGENT["validator-agent"]
|
||||
end
|
||||
|
||||
CAPI["control-api"]
|
||||
FIP(["Floating IP<br/>203.0.113.10<br/>(адрес под проверкой,<br/>привязан оркестратором заранее)"])
|
||||
|
||||
subgraph TARGETS["Целевые серверы (targets из конфига)"]
|
||||
T1["hub.docker.com"]
|
||||
T2["github.com"]
|
||||
T3["packages.ubuntu.com"]
|
||||
end
|
||||
|
||||
AGENT -->|"1 GET /api/v1/whatsmyip<br/>(self-check)"| CAPI
|
||||
CAPI -.->|"2 наблюдаемый исходящий IP"| AGENT
|
||||
AGENT ==>|"3 весь исходящий трафик ВМ<br/>идёт через FIP (SNAT облака)"| FIP
|
||||
FIP ==>|"4 HTTPS GET"| T1
|
||||
FIP ==>|"4 HTTPS GET"| T2
|
||||
FIP ==>|"4 ICMP echo"| T3
|
||||
```
|
||||
|
||||
**Пояснение.** Шаги 1–2 — самопроверка (self-check): агент обращается к
|
||||
`control-api` и сравнивает адрес, с которого пришёл его собственный
|
||||
запрос, с адресом, который ему назначен. Поскольку весь исходящий трафик
|
||||
ВМ реально идёт через привязанный Floating IP (шаг 3, SNAT на стороне
|
||||
облака), совпадение подтверждает, что назначение применилось корректно —
|
||||
только после этого агент переходит к шагу 4 и выполняет проверки из
|
||||
`check_config` (HTTPS/ICMP/опционально SSH) против целей из конфига.
|
||||
Каждый результат отправляется обратно в control-api сразу после
|
||||
выполнения (см. диаграмму телеметрии ниже) — сам этот data-plane трафик
|
||||
(шаги 3–4) в control-api не проходит и им не наблюдается напрямую,
|
||||
control-api видит только заявленный агентом результат.
|
||||
|
||||
### Дополнительно: обратное направление (пробер к валидатору)
|
||||
|
||||
Тот же Floating IP одновременно проверяется и «снаружи» — с трёх внешних
|
||||
площадок, независимо от исходящих проверок агента:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph SITES["3 внешние площадки"]
|
||||
P1["prober site-1"]
|
||||
P2["prober site-2"]
|
||||
P3["prober site-3"]
|
||||
end
|
||||
|
||||
FIP(["тот же Floating IP<br/>203.0.113.10"])
|
||||
VM["ВМ-валидатор<br/>(слушает 22/80/443/8080)"]
|
||||
|
||||
P1 ==>|"TCP connect + ICMP echo"| FIP
|
||||
P2 ==>|"TCP connect + ICMP echo"| FIP
|
||||
P3 ==>|"TCP connect + ICMP echo"| FIP
|
||||
FIP -.-> VM
|
||||
```
|
||||
|
||||
Именно сочетание двух направлений (egress от валидатора и inbound от трёх
|
||||
площадок) и даёт полную картину: адрес может нормально работать «наружу»,
|
||||
но быть заблокирован для конкретных внешних сетей — это увидит только
|
||||
inbound-проверка, и наоборот.
|
||||
|
||||
---
|
||||
|
||||
## 3. Поток данных телеметрии
|
||||
|
||||
Как результаты проверок и события аудита от validator-agent и трёх
|
||||
проберов попадают в базу данных control-api, агрегируются в итоговый
|
||||
результат и становятся видны оператору.
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph SOURCES["Источники телеметрии"]
|
||||
VA["validator-agent<br/>(egress-проверки + self-check)"]
|
||||
P1["prober site-1"]
|
||||
P2["prober site-2"]
|
||||
P3["prober site-3"]
|
||||
end
|
||||
|
||||
subgraph API["HTTP API control-api"]
|
||||
EP1["POST /agents/{id}/events"]
|
||||
EP2["POST /agents/{id}/self-check"]
|
||||
EP3["POST /agents/{id}/results"]
|
||||
EP4["POST /probers/{site_id}/results"]
|
||||
end
|
||||
|
||||
subgraph DB["SQLite (control-api)"]
|
||||
EVENTS[("events<br/>журнал аудита")]
|
||||
CHECKS[("checks<br/>результаты проверок,<br/>source=egress|inbound-site-N")]
|
||||
IPQ[("ip_queue<br/>state, *_complete,<br/>overall_result")]
|
||||
end
|
||||
|
||||
AGG["Агрегация (оркестратор):<br/>по достижении всех *_complete<br/>или по таймауту checking_window_seconds"]
|
||||
|
||||
ADMIN["Оператор:<br/>GET /api/v1/admin/status<br/>GET /api/v1/admin/ips<br/>GET /api/v1/admin/ips/{ip}"]
|
||||
|
||||
VA -->|"config_received,<br/>self_check_result, ..."| EP1 --> EVENTS
|
||||
VA -->|"success, detected_egress_ip"| EP2 --> EVENTS
|
||||
EP2 -.->|"успех → egress_complete"| IPQ
|
||||
VA -->|"check_type, target,<br/>success, latency_ms"| EP3 --> CHECKS
|
||||
P1 & P2 & P3 -->|"check_type, success,<br/>latency_ms, complete"| EP4 --> CHECKS
|
||||
EP4 -.->|"complete=true → siteN_complete"| IPQ
|
||||
|
||||
CHECKS --> AGG
|
||||
IPQ --> AGG
|
||||
AGG -->|"overall_result:<br/>pass / partial / fail"| IPQ
|
||||
|
||||
EVENTS --> ADMIN
|
||||
CHECKS --> ADMIN
|
||||
IPQ --> ADMIN
|
||||
```
|
||||
|
||||
**Пояснение.** Телеметрия стекается в БД из четырёх независимых потоков
|
||||
(один от агента-валидатора, три — по одному с каждой площадки),
|
||||
записываясь в две таблицы: `events` — сырой журнал аудита (что и когда
|
||||
произошло), `checks` — результат каждой отдельной проверки с указанием
|
||||
источника (`source`: `egress` для валидатора, `inbound-site-1/2/3` для
|
||||
площадок). Отдельно, по мере поступления данных, выставляются флаги
|
||||
завершения (`egress_complete`, `site1/2/3_complete`) в `ip_queue`. Как
|
||||
только все четыре флага выставлены — либо истекло время ожидания
|
||||
(`checking_window_seconds`) — фоновая агрегация суммирует все строки
|
||||
`checks` по текущей попытке и записывает итог (`pass`/`partial`/`fail`)
|
||||
обратно в `ip_queue`. Оператор в любой момент читает уже накопленные
|
||||
данные через административные `GET`-методы, не дожидаясь завершения
|
||||
проверки — подробнее о значениях полей см.
|
||||
[USAGE.md](USAGE.md#значения-полей-ip).
|
||||
+78
-12
@@ -1,16 +1,21 @@
|
||||
# Подготовка стенда и первичная инициализация
|
||||
|
||||
Документ описывает, как собрать компоненты, подготовить конфигурацию и
|
||||
запустить стенд с нуля — от чистой машины до работающего control-api,
|
||||
валидаторов и проберов. Если нужно просто быстро посмотреть систему в
|
||||
работе без реального OpenStack — сразу переходите к разделу
|
||||
Документ описывает, как подготовить конфигурацию и запустить стенд с нуля
|
||||
— от чистой машины до работающего control-api, валидаторов и проберов.
|
||||
Бинарники брать не обязательно из исходников: в репозитории уже лежат
|
||||
готовые сборки для Linux x86_64 (`bin/`) — это самый быстрый путь к
|
||||
развёртыванию, см. [«Получение бинарников»](#получение-бинарников). Если
|
||||
нужно просто быстро посмотреть систему в работе без реального OpenStack —
|
||||
сразу переходите к разделу
|
||||
[«Быстрая проверка без OpenStack»](#быстрая-проверка-без-openstack-offline-режим).
|
||||
|
||||
## Содержание
|
||||
|
||||
- [Компоненты и роли машин](#компоненты-и-роли-машин)
|
||||
- [Требования](#требования)
|
||||
- [Сборка бинарников](#сборка-бинарников)
|
||||
- [Получение бинарников](#получение-бинарников)
|
||||
- [Вариант A: готовые бинарники из репозитория (рекомендуется)](#вариант-a-готовые-бинарники-из-репозитория-рекомендуется)
|
||||
- [Вариант B: сборка из исходников](#вариант-b-сборка-из-исходников)
|
||||
- [Быстрая проверка без OpenStack (offline-режим)](#быстрая-проверка-без-openstack-offline-режим)
|
||||
- [Подготовка конфигурации для реального стенда](#подготовка-конфигурации-для-реального-стенда)
|
||||
- [Развёртывание control-api](#развёртывание-control-api)
|
||||
@@ -33,9 +38,12 @@ control-api (см. [API.md](API.md)).
|
||||
|
||||
## Требования
|
||||
|
||||
- **Go 1.22+** для сборки (проверено на Go 1.26). Собранные бинарники —
|
||||
статические, дополнительных зависимостей на целевых машинах не требуют
|
||||
(используется чистый Go-драйвер SQLite, без cgo).
|
||||
- Целевые серверы (control-api, валидаторы, площадки) — **Linux
|
||||
x86_64 (amd64)**. Для этой платформы в репозитории уже лежат готовые
|
||||
бинарники (см. ниже) — устанавливать Go на целевые машины не требуется.
|
||||
- **Go 1.22+** нужен только если вы пересобираете бинарники из
|
||||
исходников (проверено на Go 1.26) — например, для другой платформы
|
||||
(arm64, другая ОС) или после изменения кода.
|
||||
- Для `control-api` в боевом режиме (`openstack.mode: real`) — учётная
|
||||
запись OpenStack с правами на чтение/изменение floating IP (Neutron)
|
||||
в сервисном проекте, и заранее выделенные (allocated) floating IP —
|
||||
@@ -46,15 +54,65 @@ control-api (см. [API.md](API.md)).
|
||||
- `curl`, `sqlite3` (опционально, для ручной инспекции БД) на машине с
|
||||
control-api пригодятся для диагностики.
|
||||
|
||||
## Сборка бинарников
|
||||
## Получение бинарников
|
||||
|
||||
### Вариант A: готовые бинарники из репозитория (рекомендуется)
|
||||
|
||||
В директории `bin/` репозитория уже лежат три готовых бинарника —
|
||||
собирать их на целевых серверах не нужно, разворачивание сразу
|
||||
начинается с копирования и запуска (раздел
|
||||
[«Развёртывание control-api»](#развёртывание-control-api) и далее).
|
||||
|
||||
```
|
||||
bin/
|
||||
├── control-api # ~11 МБ
|
||||
├── validator-agent # ~7 МБ
|
||||
├── prober # ~7 МБ
|
||||
└── SHA256SUMS
|
||||
```
|
||||
|
||||
Характеристики сборки:
|
||||
- Платформа: `GOOS=linux GOARCH=amd64`.
|
||||
- `CGO_ENABLED=0` — статическая линковка, без cgo (используется чистый
|
||||
Go-драйвер SQLite `modernc.org/sqlite`). Дополнительные `.so`-библиотеки
|
||||
и конкретная версия glibc на целевом сервере **не требуются**.
|
||||
- Собрано флагами `-trimpath -ldflags="-s -w"` (без путей сборки и
|
||||
отладочной информации — компактнее и без утечки информации о машине
|
||||
сборки).
|
||||
|
||||
Убедиться в отсутствии динамических зависимостей и целостности файлов
|
||||
после переноса на целевой сервер:
|
||||
|
||||
```bash
|
||||
ldd bin/control-api # => "not a dynamic executable"
|
||||
file bin/control-api # => ELF 64-bit LSB executable, x86-64, statically linked
|
||||
|
||||
# После scp/rsync на целевой сервер — проверить, что файлы не повреждены:
|
||||
sha256sum -c bin/SHA256SUMS
|
||||
```
|
||||
|
||||
Перенос на целевые серверы, например:
|
||||
|
||||
```bash
|
||||
scp bin/control-api control-api-host:/tmp/
|
||||
scp bin/validator-agent validator-host-01:/tmp/
|
||||
scp bin/prober probe-site-1:/tmp/
|
||||
```
|
||||
|
||||
> Если целевая платформа отличается от linux/amd64 (например, ВМ на
|
||||
> arm64) — готовые бинарники не подойдут, используйте
|
||||
> [вариант B](#вариант-b-сборка-из-исходников).
|
||||
|
||||
### Вариант B: сборка из исходников
|
||||
|
||||
Из корня репозитория:
|
||||
|
||||
```bash
|
||||
export PATH=$PATH:/usr/local/go/bin # если go не в PATH
|
||||
go build -o bin/control-api ./cmd/control-api
|
||||
go build -o bin/validator-agent ./cmd/validator-agent
|
||||
go build -o bin/prober ./cmd/prober
|
||||
export CGO_ENABLED=0 GOOS=linux GOARCH=amd64 # поменяйте GOARCH для другой платформы
|
||||
go build -trimpath -ldflags="-s -w" -o bin/control-api ./cmd/control-api
|
||||
go build -trimpath -ldflags="-s -w" -o bin/validator-agent ./cmd/validator-agent
|
||||
go build -trimpath -ldflags="-s -w" -o bin/prober ./cmd/prober
|
||||
```
|
||||
|
||||
Каждый бинарник самодостаточен — скопируйте нужный файл на
|
||||
@@ -67,6 +125,14 @@ go build -o bin/prober ./cmd/prober
|
||||
go build ./... && go test ./...
|
||||
```
|
||||
|
||||
Пересобирайте из исходников и обновляйте `bin/` с зафиксированными
|
||||
`SHA256SUMS`, если меняли код — готовые бинарники в репозитории **не
|
||||
обновляются автоматически**:
|
||||
|
||||
```bash
|
||||
sha256sum bin/control-api bin/validator-agent bin/prober | sed 's#bin/##' > bin/SHA256SUMS
|
||||
```
|
||||
|
||||
## Быстрая проверка без OpenStack (offline-режим)
|
||||
|
||||
Прежде чем разворачивать реальный стенд, рекомендуется убедиться, что всё
|
||||
|
||||
Reference in new issue
Block a user