Files
cloud-ip-validator/docs/USAGE.md
T

269 lines
18 KiB
Markdown
Raw Normal View History

2026-08-21 07:34:45 +03:00
# Работа со стендом
Этот документ — для оператора, который уже развернул стенд (см.
[SETUP.md](SETUP.md)) и теперь использует его в повседневной работе:
добавляет адреса на проверку, следит за очередью, разбирается в
результатах и реагирует на проблемы. Прямые вызовы API описаны в
[API.md](API.md) — здесь мы используем их только как инструмент, не
углубляясь в протокол.
## Содержание
- [Как устроена работа с системой](#как-устроена-работа-с-системой)
- [Добавление новых IP в очередь](#добавление-новых-ip-в-очередь)
- [Наблюдение за очередью](#наблюдение-за-очередью)
- [Значения полей IP](#значения-полей-ip)
- [Как читать итоговый результат (pass/partial/fail)](#как-читать-итоговый-результат-passpartialfail)
- [Просмотр деталей и истории по конкретному адресу](#просмотр-деталей-и-истории-по-конкретному-адресу)
- [Управление валидаторами](#управление-валидаторами)
- [Управление площадками (проберами)](#управление-площадками-проберами)
- [Повторная проверка адреса](#повторная-проверка-адреса)
- [Частые проблемы и что с ними делать](#частые-проблемы-и-что-с-ними-делать)
## Как устроена работа с системой
Оператор не взаимодействует с валидаторами и проберами напрямую — вся
работа идёт через `control-api`. Цикл жизни одного IP-адреса:
1. Адрес встаёт в очередь (`queued`).
2. Control-api сам находит свободный валидатор, привязывает адрес к нему
как Floating IP.
3. Валидатор проверяет, что действительно вышел в интернет именно через
этот адрес (self-check), затем прогоняет исходящие проверки (HTTPS,
ICMP, опционально SSH до заданных внешних целей).
4. Одновременно три внешние площадки проверяют, что этот адрес доступен
*снаружи* (входящие TCP-подключения на 22/80/443/8080 и ICMP) — это
ловит блокировки/чёрные списки на конкретных внешних сетях.
5. Как только все источники (валидатор + 3 площадки) отчитались — или
истекло время ожидания — control-api подводит итог и освобождает
адрес (отвязывает Floating IP).
Всё это происходит автоматически, без участия оператора. Задача оператора
— положить адреса в очередь и снять с них результат.
## Добавление новых IP в очередь
**В текущей версии добавление адресов происходит только через конфиг
control-api**, отдельного API-метода "добавить IP в очередь" нет.
1. Добавьте новые адреса в список `ip_addresses` в
`/etc/cloud-ip-validator/control-api.yaml` (в конец списка, либо в
нужном порядке — очередь обрабатывается строго в порядке следования
списка, `sequence`).
2. Перезапустите control-api:
```bash
systemctl restart control-api
```
Это безопасно для уже идущей работы: при старте control-api добавляет в
очередь только **новые** адреса (те, которых там ещё нет) — уже
обработанные ранее адреса не сбрасываются и повторно не проверяются.
Адреса, которые были удалены из `ip_addresses`, но уже есть в базе,
**не удаляются** из очереди/истории автоматически — если конкретный адрес
больше не нужно проверять и его нет в очереди/в процессе, можно просто
оставить как есть (историю он не портит).
> Совет: держите `control-api.yaml` под версионным контролем (git) —
> список адресов на проверку тогда одновременно служит и журналом того,
> что вообще когда-либо ставилось в очередь.
## Наблюдение за очередью
Общая сводка:
```bash
curl -s http://<control-api>:8080/api/v1/admin/status | python3 -m json.tool
```
```json
{
"total_ips": 25,
"ips_by_state": {"queued": 10, "awaiting_self_check": 1, "checking": 3, "done": 10, "failed": 1},
"total_validators": 4
}
```
`ips_by_state` — сколько адресов в каждом состоянии прямо сейчас. Если
хотите наблюдать за прогрессом в реальном времени:
```bash
watch -n 2 'curl -s http://<control-api>:8080/api/v1/admin/status | python3 -m json.tool'
```
Полный список всех адресов со всеми полями:
```bash
curl -s http://<control-api>:8080/api/v1/admin/ips | python3 -m json.tool
```
Только финальные результаты (уже готовые адреса), с помощью `jq`:
```bash
curl -s http://<control-api>:8080/api/v1/admin/ips \
| jq '[.[] | select(.State=="done" or .State=="failed") | {IPAddress, State, OverallResult}]'
```
## Значения полей IP
| Поле | Значение |
|---|---|
| `IPAddress` | Проверяемый адрес |
| `Sequence` | Позиция в очереди (порядок из конфига) |
| `State` | Текущий этап: `queued`, `assigning_fip`, `awaiting_self_check`, `checking`, `aggregating`, `done`, `failed` |
| `OwnerValidatorID` | Какой валидатор сейчас (или последним) занимался этим адресом |
| `FIPID` | Идентификатор Floating IP в OpenStack, к которому привязан адрес (пусто, если ещё/уже не привязан) |
| `AttemptNumber` | Номер попытки — растёт при каждом requeue (сбой привязки, сбой self-check, реклейм по таймауту) |
| `RetryCount` | Сколько раз адрес уже переставлялся в очередь заново |
| `EgressComplete` | Валидатор закончил исходящие проверки |
| `Site1Complete` / `Site2Complete` / `Site3Complete` | Соответствующая площадка закончила входящие проверки |
| `OverallResult` | Итог: `pass`, `partial`, `fail`, либо пусто, пока проверка не завершена |
| `AssignedAt` / `AggregatedAt` / `FIPReleasedAt` | Метки времени соответствующих этапов |
## Как читать итоговый результат (pass/partial/fail)
- **`pass`** — прошли все проверки (все исходящие + все три площадки по
всем портам и ICMP). Адрес можно считать пригодным к повторной выдаче.
- **`partial`** — часть проверок прошла, часть — нет (например, площадка
site-2 не смогла достучаться по 8080/tcp, но остальное в порядке).
Означает частичную деградацию — например, адрес заблокирован в
отдельном сегменте сети/у отдельного провайдера. Требует решения
оператора: годится ли адрес для данного случая использования.
- **`fail`** — либо ни одна проверка не прошла, либо адрес вообще не
дошёл до стадии проверок (например, self-check не подтвердился —
трафик валидатора не пошёл через назначенный FIP — и попытки
исчерпались). Смотрите `events` по этому адресу (см. ниже), чтобы
понять, на каком шаге и почему.
Отсутствие ответа от источника (площадка не прислала результат до
истечения `checking_window_seconds`) засчитывается как провал — это
управляется настройкой `aggregation.missing_counts_as_fail` в конфиге
control-api (по умолчанию включено).
## Просмотр деталей и истории по конкретному адресу
```bash
curl -s http://<control-api>:8080/api/v1/admin/ips/203.0.113.10 | python3 -m json.tool
```
Ответ содержит три части:
- `ip` — те же поля, что и в списке `admin/ips`, но для одного адреса;
- `checks` — все отдельные проверки текущей попытки: кто проверял
(`Source`: `egress` или `inbound-site-N`), что именно (`CheckType`,
`Target`), результат (`Success`), задержка (`LatencyMS`), и
человекочитаемая деталь (`Detail`, например текст ошибки при отказе);
- `events` — журнал аудита по этому адресу в хронологическом порядке
(регистрация, привязка FIP, self-check, агрегация и т.д.) — полезен,
чтобы восстановить точную последовательность событий при разборе
инцидента.
Пример: почему адрес получил `fail`?
```bash
curl -s http://<control-api>:8080/api/v1/admin/ips/203.0.113.10 \
| jq '.checks[] | select(.Success==false)'
```
## Управление валидаторами
Список валидаторов и их текущее состояние:
```bash
curl -s http://<control-api>:8080/api/v1/admin/validators | python3 -m json.tool
```
Состояния валидатора: `unregistered` (в конфиге есть, агент ещё не
подключался), `idle` (свободен, готов взять адрес), `assigned`/`checking`
(занят), `unreachable` (пропустил heartbeat дольше
`orchestrator.heartbeat_timeout_seconds`).
**Добавление нового валидатора:**
1. Поднимите новую ВМ в сервисном проекте облака, узнайте её Neutron
`port_id`.
2. Добавьте запись в `validators` в `control-api.yaml`
(`validator_id` + `os_port_id`) и перезапустите `control-api`.
3. Разверните и запустите `validator-agent` на новой ВМ с тем же
`validator_id` в его конфиге (см. [SETUP.md](SETUP.md#развёртывание-validator-agent-на-вм-валидаторах)).
**Вывод валидатора из эксплуатации:** остановите на нём
`validator-agent` (`systemctl stop validator-agent`). Он перестанет
получать новые задания после того, как закончит текущее (если оно было);
если он был убит посреди работы — control-api сам заберёт у него
незавершённый адрес обратно в очередь по истечении
`orchestrator.lease_ttl_seconds`. Удалять запись из `control-api.yaml`
не обязательно — просто выключенный агент не будет ничего забирать.
## Управление площадками (проберами)
Аналогично валидаторам: чтобы добавить площадку, добавьте `site_id` +
`index` (свободный от 1 до 3, или больше — но текущая схема БД
рассчитана ровно на 3 площадки, см. ниже) в `sites` конфига control-api,
разверните на площадке `prober` с тем же `site_id`.
> Важно: количество площадок в текущей версии жёстко зашито в схему БД
> (`Site1Complete`/`Site2Complete`/`Site3Complete`) — система рассчитана
> ровно на **три** внешние площадки, как и описано в исходной схеме
> процесса. Изменение их числа потребует доработки схемы данных, это не
> делается только правкой конфига.
## Повторная проверка адреса
Если адрес завершился с `failed` или `partial`, а вы хотите перепроверить
его ещё раз (например, после устранения блокировки на стороне сети):
на данный момент нет отдельного API-метода "перезапустить проверку".
Самый простой путь:
1. Убедитесь, что адрес не находится в активном состоянии (`checking`
и т.п.) — то есть уже `done`/`failed`.
2. Временно уберите и снова добавьте адрес в список `ip_addresses`
(либо просто пересоздайте запись в БД вручную, если это единичный
случай и у вас есть доступ к SQLite) и перезапустите `control-api`.
Поскольку сидирование очереди идёт по уникальности `ip_address`
(конфликт по уже существующей записи просто игнорируется), самый чистый
способ гарантированно перепроверить конкретный адрес — обратиться к
администратору БД (см. следующий раздел) либо дождаться штатной
доработки API под повторные проверки.
## Частые проблемы и что с ними делать
**Валидатор долго висит в `unreachable`.**
Проверьте сетевую связность ВМ-валидатора до `control-api` (порт из
`server.listen_addr`) и что процесс `validator-agent` вообще запущен
(`systemctl status validator-agent`, `journalctl -u validator-agent`).
**Адрес постоянно проваливает self-check.**
Смотрите `events` по адресу (`GET /api/v1/admin/ips/{ip}`) — в детали
события `self_check_result` будет указан обнаруженный исходящий адрес.
Если он не совпадает с ожидаемым — вероятно, на ВМ-валидаторе есть другой
маршрут наружу (не через назначенный Floating IP), либо привязка FIP на
стороне OpenStack не применилась. Проверьте вручную в OpenStack
(`openstack floating ip show <адрес>`), что `port_id` совпадает с портом
валидатора.
**Площадка (`site-N`) никогда не отчитывается (`SiteNComplete` всегда
`false`).**
Проверьте, что `prober` на этой площадке запущен и его `site_id` в
конфиге совпадает с `site_id` в конфиге control-api. Проверьте, что
площадка имеет сетевой доступ и до `control-api`, и до проверяемого
адреса (входящий трафик на 22/80/443/8080 + ICMP — это отдельная
связность от связи с control-api, см.
[SETUP.md](SETUP.md#сетевые-доступы)).
**Много адресов зависло в `checking` дольше ожидаемого.**
Это нормально, если ещё не истёк `orchestrator.checking_window_seconds` —
агрегация ждёт либо полного набора ответов, либо истечения окна. Если
адрес завис заметно дольше окна — проверьте, что фоновый цикл control-api
вообще работает (смотрите `journalctl -u control-api` на предмет ошибок
в `sweep checking window`).
**Нужно посмотреть на данные "из первых рук", в обход API.**
`control-api` использует SQLite, файл — по пути `database.path` из
конфига. Можно (только для чтения, на **той же машине**, где крутится
control-api) открыть его `sqlite3` в режиме WAL — это безопасно для
чтения параллельно с работающим процессом:
```bash
sqlite3 /var/lib/cloud-ip-validator/control-api.db \
"select ip_address, state, overall_result from ip_queue order by sequence"
```
Не редактируйте эту базу вручную во время работы control-api — это может
рассинхронизировать состояние с реальными привязками Floating IP в
OpenStack.