Scan floating IPs in the background, page by page, so thousands of addresses work
The "Scan Floating IP" button failed with a client timeout: the project now holds ~6.4k floating IPs and the scan listed them all in one unpaginated, timeout-less Neutron request on the HTTP request context. openstack: ListFreeFloatingIPs reads marker-based pages (fields= keeps them small) with per-page retry/backoff on transport errors, 5xx and 429, and every request now has a timeout (also ends hangs inside the orchestrator tick). orchestrator: the scan is a single-flight background job on the process context with progress (clearing/listing/enqueuing/done/error), dry_run, full discovery before anything is enqueued, then SubmitIPs in chunks of 500 in ascending IP order; a failed read leaves the queue untouched. The auto-cycle gets a "scanning" phase that polls the job, so the control loop and autoCycleMu are never held across OpenStack/DB work; it recovers after a restart and waits for (instead of adopting) a scan started by someone else. db: migration 0009 (indexes), paged ListIPsPage/ListRegistryPage, GROUP BY counters, EXISTS completion check, set-based ClearAllIPs. API: POST /admin/ips/scan -> 202 (dry_run, wait), GET /admin/ips/scan, paging and filters on /admin/ips and /admin/registry (bare arrays without limit), results_by_overall in /admin/status. dashboard: scan progress panel and dry-run button, paginated /ips and /registry with server-side filters, Overview on counters and capped lists with progress/ETA, "select all N by filter", hx-params fix for per-row buttons, real counts in confirmations. Also: docs (API, USAGE, DASHBOARD, README), plan and review under docs/changes/, bin/ rebuilt with new SHA256SUMS. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
debf2afed2
commit
aff8fe38b5
61 files changed
+5833
-536
No files matched your search
+38
-7
@@ -90,7 +90,8 @@ curl -s -X POST http://<control-api>:8080/api/v1/admin/ips \
|
||||
самому найти их в облаке:
|
||||
|
||||
```bash
|
||||
curl -s -X POST http://<control-api>:8080/api/v1/admin/ips/scan
|
||||
curl -s -X POST http://<control-api>:8080/api/v1/admin/ips/scan # 202: сканирование запущено в фоне
|
||||
curl -s http://<control-api>:8080/api/v1/admin/ips/scan # ход и результат
|
||||
```
|
||||
|
||||
Сканируются все Floating IP текущего проекта OpenStack, но в очередь
|
||||
@@ -101,8 +102,23 @@ curl -s -X POST http://<control-api>:8080/api/v1/admin/ips/scan
|
||||
встают в очередь, уже завершённые перезапускаются, активно проверяемые не
|
||||
трогаются (см. [выше](#добавление-новых-ip-в-очередь)).
|
||||
|
||||
В `admin-dashboard` то же самое — кнопка «Сканировать Floating IP» на
|
||||
странице `/ips`.
|
||||
**Сколько адресов — не важно.** Сканирование работает в фоне и читает список из OpenStack
|
||||
**страницами** (по 200 адресов, с повторами при обрывах), поэтому подходит и для проекта с
|
||||
тысячами Floating IP: на стенде с 6441 адресом чтение занимает около 1,5–2 минут. Сначала
|
||||
обнаруживаются **все** адреса, и только потом они ставятся в очередь (кусками по 500, в порядке
|
||||
возрастания IP); сразу после этого начинаются проверки. Если чтение сорвалось даже после повторов,
|
||||
в очередь не попадает ничего — очередь остаётся как была, а на панели виден `error` и причина.
|
||||
Одновременно идёт одно сканирование: повторное нажатие присоединяется к текущему.
|
||||
|
||||
В `admin-dashboard` — кнопка «Сканировать Floating IP» на странице `/ips`: она сразу отвечает, а под
|
||||
кнопкой появляется панель прогресса (читаются страницы → ставятся в очередь → готово: прочитано
|
||||
страниц, найдено, свободных, добавлено, время), по окончании таблица обновляется сама. Рядом —
|
||||
«Пробное сканирование»: оно проходит все страницы и показывает, сколько свободных адресов нашлось,
|
||||
**не меняя очередь** (удобно проверить, что облако отвечает и сколько адресов будет поставлено).
|
||||
|
||||
Параметры чтения (`control-api.yaml`): `openstack.list_page_size` (200), `openstack.request_timeout_seconds`
|
||||
(60 — таймаут одного запроса к OpenStack), `openstack.list_page_retries` (5), `orchestrator.fip_scan_timeout_seconds`
|
||||
(1800 — предел всего сканирования).
|
||||
|
||||
Если хочется, чтобы сканирование происходило само по расписанию, а не
|
||||
только по запросу — задайте `orchestrator.fip_scan_interval_seconds`
|
||||
@@ -111,6 +127,11 @@ curl -s -X POST http://<control-api>:8080/api/v1/admin/ips/scan
|
||||
[автоматический цикл](#автоматический-цикл-проверок), это периодическое
|
||||
сканирование не выполняется — цикл сам управляет очередью.
|
||||
|
||||
> **Сколько займут проверки.** Один адрес занимает около 50 секунд на валидаторе (из них 30 с — пауза
|
||||
> `fip_settle_seconds`). Поэтому очередь из 6440 адресов — примерно 18 часов на 5 валидаторах,
|
||||
> 9 часов на 10, 4,5 часа на 20. Ускорить можно числом валидаторов и (осторожно) `fip_settle_seconds`;
|
||||
> на странице «Обзор» виден прогресс «Готово D из T» и оценка оставшегося времени.
|
||||
|
||||
## Автоматический цикл проверок
|
||||
|
||||
Опциональный режим, который сам повторяет то, что оператор делает руками:
|
||||
@@ -122,7 +143,9 @@ curl -s -X POST http://<control-api>:8080/api/v1/admin/ips/scan
|
||||
в [реестре](#реестр-адресов-и-глубина-истории) при этом сохраняется.
|
||||
2. Control-api находит все свободные Floating IP и ставит их в очередь —
|
||||
то же, что «Сканировать Floating IP» (см.
|
||||
[выше](#сканирование-floating-ip-из-openstack)).
|
||||
[выше](#сканирование-floating-ip-из-openstack)). Шаги 1–2 выполняются одним
|
||||
фоновым заданием, поэтому долгое чтение тысяч адресов не блокирует работу
|
||||
оркестратора (назначение валидаторов, лизинги, heartbeat).
|
||||
3. Проверки запускаются сами — как для любого адреса в очереди.
|
||||
4. Цикл ждёт, пока **все** адреса очереди дойдут до конечного состояния
|
||||
(`done`, `failed` или `occupied`). К этому моменту результат каждого
|
||||
@@ -136,7 +159,7 @@ curl -s -X POST http://<control-api>:8080/api/v1/admin/ips/scan
|
||||
| Параметр | По умолчанию | Смысл |
|
||||
|---|---|---|
|
||||
| `interval_seconds` | `3600` (1 час) | Пауза между циклами. Не меньше `60`: слишком частые сканы нагружают API OpenStack. |
|
||||
| `max_run_seconds` | `0` (без лимита) | Сколько максимум ждать на шаге 4. По истечении цикл фиксирует `timeout` и переходит к паузе — защита от зависания (нет свободных валидаторов, недоступна площадка). Очередь при этом не трогается: следующий цикл её очистит, а до тех пор видно, что именно не дошло до конца. |
|
||||
| `max_run_seconds` | `0` (без лимита) | Сколько максимум ждать на шаге 4 (отсчёт — **от конца сканирования**). По истечении цикл фиксирует `timeout` и переходит к паузе — защита от зависания (нет свободных валидаторов, недоступна площадка). Очередь при этом не трогается: следующий цикл её очистит, а до тех пор видно, что именно не дошло до конца. **При тысячах адресов оставьте `0`** (или задайте больше расчётного времени: 6440 адресов — часы). |
|
||||
|
||||
Параметры хранятся в базе и меняются на лету, без перезапуска; в `control-api.yaml`
|
||||
ничего задавать не нужно. Новый `interval_seconds` применяется к паузе
|
||||
@@ -170,7 +193,8 @@ curl -s http://<control-api>:8080/api/v1/admin/auto-cycle
|
||||
### Фазы и результат последнего цикла
|
||||
|
||||
`phase` показывает, что происходит сейчас: `idle` (автоцикл выключен или ещё не
|
||||
стартовал), `running` (идут проверки — шаги 3–4) и `waiting` (пауза между циклами,
|
||||
стартовал), `scanning` (шаги 1–2: очистка очереди и чтение/постановка Floating IP),
|
||||
`running` (идут проверки — шаги 3–4) и `waiting` (пауза между циклами,
|
||||
шаг 5; время следующего запуска — `next_run_at`). Результат последнего цикла
|
||||
(`last_outcome`):
|
||||
|
||||
@@ -185,7 +209,8 @@ curl -s http://<control-api>:8080/api/v1/admin/auto-cycle
|
||||
### Что важно знать
|
||||
|
||||
- **Выключение не прерывает проверки**, которые уже идут: они закончатся и попадут
|
||||
в реестр, остановится только повторение.
|
||||
в реестр, остановится только повторение. Если выключить цикл во время фазы `scanning`,
|
||||
сканирование отменяется (уже поставленные в очередь куски остаются).
|
||||
- Автоцикл **владеет очередью**: каждый цикл начинается с её полной очистки,
|
||||
поэтому адреса, добавленные вручную, будут удалены (их история в реестре
|
||||
остаётся). Ручные «Очистить всё» и «Сканировать Floating IP» во время цикла
|
||||
@@ -195,6 +220,12 @@ curl -s http://<control-api>:8080/api/v1/admin/auto-cycle
|
||||
- События цикла (`auto_cycle_started`, `auto_cycle_completed`, `auto_cycle_timeout`,
|
||||
`auto_cycle_error`, `auto_cycle_stopped`) пишутся в журнал событий вместе с
|
||||
`queue_cleared` и `fip_scan`.
|
||||
- Если в момент старта цикла уже идёт чужое сканирование (ручное, пробное или по расписанию),
|
||||
цикл **дожидается** его окончания и запускает собственное (с очисткой очереди) — присоединяться
|
||||
к чужому нельзя: оно могло ничего не поставить в очередь.
|
||||
- Если сканирование завершилось ошибкой, очередь уже очищена (шаг 1) и остаётся пустой до следующего
|
||||
цикла (`interval_seconds`); исход цикла — `error` с причиной в `last_error`.
|
||||
- Цикл на тысячах адресов длится часы; пауза `interval_seconds` отсчитывается после его завершения.
|
||||
- В реальном OpenStack отвязка Floating IP после очистки очереди может
|
||||
отразиться с задержкой; если скан сразу после неё не увидел свободных адресов,
|
||||
цикл завершится с `no_free_ips` и повторится через `interval_seconds`.
|
||||
|
||||
Reference in new issue
Block a user