Files
cloud-ip-validator/docs/DIAGRAMS.md
T
2026-08-21 08:11:58 +03:00

11 KiB
Raw Blame History

Диаграммы потоков данных

Три диаграммы, поясняющие устройство системы на уровне потоков данных — дополнение к API.md (протокол) и USAGE.md (работа оператора). Диаграммы — в формате Mermaid, рендерятся нативно на GitHub/GitLab и в большинстве современных Markdown-просмотрщиков.

Как читать диаграммы

Единое условное обозначение стрелок для всех диаграмм:

Обозначение Значение
--> тонкая сплошная Управляющий вызов / API-запрос
-.-> пунктирная Ответ, уведомление, асинхронный результат
==> жирная сплошная Реальный сетевой трафик проверки (data-plane) — именно то, что валидируется, а не служебный вызов

Содержание


1. Control plane сервиса

Кто кем управляет и через какой канал: конфигурация оператора, HTTP API control-api, фоновый оркестратор, база данных, вызовы к OpenStack и опрос со стороны validator-agent/prober.

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). Оркестратор работает по таймеру независимо от HTTP-запросов — назначение IP валидаторам и агрегация результатов не привязаны к конкретному входящему запросу, а выполняются фоновым циклом Tick. validator-agent и prober — активная сторона: они сами инициируют все HTTP-запросы к control-api (pull-модель), сам control-api к ним не обращается.


2. Поток данных: от валидатора к целевому серверу (egress-проверка)

Как валидатор проверяет, что через назначенный ему публичный адрес реально работает исходящий доступ в интернет.

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 одновременно проверяется и «снаружи» — с трёх внешних площадок, независимо от исходящих проверок агента:

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, агрегируются в итоговый результат и становятся видны оператору.

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.