2026-08-21 07:34:45 +03:00
|
|
|
|
# Подготовка стенда и первичная инициализация
|
|
|
|
|
|
|
2026-08-21 08:11:58 +03:00
|
|
|
|
Документ описывает, как подготовить конфигурацию и запустить стенд с нуля
|
|
|
|
|
|
— от чистой машины до работающего control-api, валидаторов и проберов.
|
|
|
|
|
|
Бинарники брать не обязательно из исходников: в репозитории уже лежат
|
|
|
|
|
|
готовые сборки для Linux x86_64 (`bin/`) — это самый быстрый путь к
|
|
|
|
|
|
развёртыванию, см. [«Получение бинарников»](#получение-бинарников). Если
|
|
|
|
|
|
нужно просто быстро посмотреть систему в работе без реального OpenStack —
|
|
|
|
|
|
сразу переходите к разделу
|
2026-08-21 07:34:45 +03:00
|
|
|
|
[«Быстрая проверка без OpenStack»](#быстрая-проверка-без-openstack-offline-режим).
|
|
|
|
|
|
|
|
|
|
|
|
## Содержание
|
|
|
|
|
|
|
|
|
|
|
|
- [Компоненты и роли машин](#компоненты-и-роли-машин)
|
|
|
|
|
|
- [Требования](#требования)
|
2026-08-21 08:11:58 +03:00
|
|
|
|
- [Получение бинарников](#получение-бинарников)
|
|
|
|
|
|
- [Вариант A: готовые бинарники из репозитория (рекомендуется)](#вариант-a-готовые-бинарники-из-репозитория-рекомендуется)
|
|
|
|
|
|
- [Вариант B: сборка из исходников](#вариант-b-сборка-из-исходников)
|
2026-08-21 07:34:45 +03:00
|
|
|
|
- [Быстрая проверка без OpenStack (offline-режим)](#быстрая-проверка-без-openstack-offline-режим)
|
|
|
|
|
|
- [Подготовка конфигурации для реального стенда](#подготовка-конфигурации-для-реального-стенда)
|
|
|
|
|
|
- [Развёртывание control-api](#развёртывание-control-api)
|
|
|
|
|
|
- [Развёртывание validator-agent на ВМ-валидаторах](#развёртывание-validator-agent-на-вм-валидаторах)
|
|
|
|
|
|
- [Развёртывание prober на внешних площадках](#развёртывание-prober-на-внешних-площадках)
|
|
|
|
|
|
- [Проверка после запуска](#проверка-после-запуска)
|
|
|
|
|
|
- [Сетевые доступы](#сетевые-доступы)
|
|
|
|
|
|
|
|
|
|
|
|
## Компоненты и роли машин
|
|
|
|
|
|
|
|
|
|
|
|
| Компонент | Где запускается | Кол-во |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| `control-api` | Отдельная управляющая машина/ВМ с доступом к OpenStack API | 1 (без HA) |
|
|
|
|
|
|
| `validator-agent` | Каждая ВМ-валидатор в сервисном проекте облака | по числу валидаторов |
|
|
|
|
|
|
| `prober` | По одному на каждой из внешних тестовых площадок | 3 (по числу площадок) |
|
|
|
|
|
|
|
|
|
|
|
|
`control-api` — единственный компонент с состоянием (SQLite). Валидаторы и
|
|
|
|
|
|
проберы не хранят локального состояния и полностью управляются через опрос
|
|
|
|
|
|
control-api (см. [API.md](API.md)).
|
|
|
|
|
|
|
|
|
|
|
|
## Требования
|
|
|
|
|
|
|
2026-08-21 08:11:58 +03:00
|
|
|
|
- Целевые серверы (control-api, валидаторы, площадки) — **Linux
|
|
|
|
|
|
x86_64 (amd64)**. Для этой платформы в репозитории уже лежат готовые
|
|
|
|
|
|
бинарники (см. ниже) — устанавливать Go на целевые машины не требуется.
|
|
|
|
|
|
- **Go 1.22+** нужен только если вы пересобираете бинарники из
|
|
|
|
|
|
исходников (проверено на Go 1.26) — например, для другой платформы
|
|
|
|
|
|
(arm64, другая ОС) или после изменения кода.
|
2026-08-21 07:34:45 +03:00
|
|
|
|
- Для `control-api` в боевом режиме (`openstack.mode: real`) — учётная
|
|
|
|
|
|
запись OpenStack с правами на чтение/изменение floating IP (Neutron)
|
|
|
|
|
|
в сервисном проекте, и заранее выделенные (allocated) floating IP —
|
|
|
|
|
|
инструмент их **не создаёт**, только привязывает/отвязывает
|
|
|
|
|
|
существующие.
|
|
|
|
|
|
- Для `validator-agent` и `prober` — возможность отправлять ICMP echo
|
|
|
|
|
|
(нужен root либо capability `CAP_NET_RAW`, см. юниты systemd).
|
|
|
|
|
|
- `curl`, `sqlite3` (опционально, для ручной инспекции БД) на машине с
|
|
|
|
|
|
control-api пригодятся для диагностики.
|
|
|
|
|
|
|
2026-08-21 08:11:58 +03:00
|
|
|
|
## Получение бинарников
|
|
|
|
|
|
|
|
|
|
|
|
### Вариант 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: сборка из исходников
|
2026-08-21 07:34:45 +03:00
|
|
|
|
|
|
|
|
|
|
Из корня репозитория:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
export PATH=$PATH:/usr/local/go/bin # если go не в PATH
|
2026-08-21 08:11:58 +03:00
|
|
|
|
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
|
2026-08-21 07:34:45 +03:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Каждый бинарник самодостаточен — скопируйте нужный файл на
|
|
|
|
|
|
соответствующую машину (control-api → управляющая машина, validator-agent
|
|
|
|
|
|
→ каждый валидатор, prober → каждая площадка).
|
|
|
|
|
|
|
|
|
|
|
|
Убедиться, что всё собирается и юнит-тесты проходят:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
go build ./... && go test ./...
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-08-21 08:11:58 +03:00
|
|
|
|
Пересобирайте из исходников и обновляйте `bin/` с зафиксированными
|
|
|
|
|
|
`SHA256SUMS`, если меняли код — готовые бинарники в репозитории **не
|
|
|
|
|
|
обновляются автоматически**:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
sha256sum bin/control-api bin/validator-agent bin/prober | sed 's#bin/##' > bin/SHA256SUMS
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-08-21 07:34:45 +03:00
|
|
|
|
## Быстрая проверка без OpenStack (offline-режим)
|
|
|
|
|
|
|
|
|
|
|
|
Прежде чем разворачивать реальный стенд, рекомендуется убедиться, что всё
|
|
|
|
|
|
собирается и работает корректно на локальной машине — без облака и
|
|
|
|
|
|
внешних площадок:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
scripts/run-local-e2e.sh
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Скрипт сам поднимает control-api (в режиме `openstack.mode: mock`),
|
|
|
|
|
|
одного validator-agent и трёх проберов как локальные процессы, прогоняет
|
|
|
|
|
|
один тестовый адрес через полный цикл проверки и печатает итоговый
|
|
|
|
|
|
результат. Подробности — в [docs/LOCAL_E2E.md](LOCAL_E2E.md). Это же
|
|
|
|
|
|
хороший способ разобраться в поведении системы перед первым боевым
|
|
|
|
|
|
запуском.
|
|
|
|
|
|
|
|
|
|
|
|
## Подготовка конфигурации для реального стенда
|
|
|
|
|
|
|
|
|
|
|
|
Все три компонента конфигурируются YAML-файлами. Шаблоны лежат в
|
|
|
|
|
|
`configs/*.example.yaml` — скопируйте их и заполните под ваш стенд.
|
|
|
|
|
|
|
|
|
|
|
|
### 1. `control-api.yaml`
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cp configs/control-api.example.yaml /etc/cloud-ip-validator/control-api.yaml
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Что обязательно нужно заполнить:
|
|
|
|
|
|
|
|
|
|
|
|
- **`validators`** — список валидаторов, у каждого `validator_id`
|
|
|
|
|
|
(произвольное имя, должно совпадать с `validator_id` в конфиге
|
|
|
|
|
|
соответствующего `validator-agent`) и `os_port_id` — **ID Neutron-порта**
|
|
|
|
|
|
основного сетевого интерфейса ВМ-валидатора (узнать: `openstack port
|
|
|
|
|
|
list --server <имя-ВМ>` или в веб-консоли облака).
|
|
|
|
|
|
- **`sites`** — три внешние площадки, `site_id` + `index` (1, 2 или 3).
|
|
|
|
|
|
`site_id` должен совпадать с `site_id` в конфиге соответствующего
|
|
|
|
|
|
`prober`.
|
|
|
|
|
|
- **`ip_addresses`** — список публичных IPv4-адресов на проверку, **в
|
|
|
|
|
|
порядке обработки**. Адреса должны существовать в сервисном проекте как
|
|
|
|
|
|
уже выделенные (allocated) floating IP — инструмент их не создаёт.
|
|
|
|
|
|
- **`openstack.mode: "real"`** и `*_env` поля — имена переменных
|
|
|
|
|
|
окружения, из которых будут прочитаны реальные учётные данные (сами
|
|
|
|
|
|
значения в этот файл **не пишутся**, см. следующий пункт).
|
|
|
|
|
|
- **`targets`** и **`check_types`** — при необходимости смените набор
|
|
|
|
|
|
целей для egress-проверок (по умолчанию — hub.docker.com, github.com,
|
|
|
|
|
|
packages.ubuntu.com) или включите `ssh` (по умолчанию выключен).
|
|
|
|
|
|
|
|
|
|
|
|
### 2. Переменные окружения для OpenStack
|
|
|
|
|
|
|
|
|
|
|
|
Учётные данные передаются **только** через переменные окружения — никогда
|
|
|
|
|
|
через YAML. Создайте файл (доступный на чтение только сервисному
|
|
|
|
|
|
пользователю):
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
install -m 0600 -o cloud-ip-validator -g cloud-ip-validator /dev/null /etc/cloud-ip-validator/control-api.env
|
|
|
|
|
|
cat >> /etc/cloud-ip-validator/control-api.env <<'EOF'
|
|
|
|
|
|
OS_AUTH_URL=https://keystone.example.com:5000/v3
|
|
|
|
|
|
OS_TOKEN=<токен администратора с правами на управление floating IP>
|
|
|
|
|
|
OS_PROJECT_ID=<id сервисного проекта>
|
|
|
|
|
|
OS_REGION_NAME=<регион>
|
|
|
|
|
|
EOF
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Имена переменных должны совпадать с тем, что указано в
|
|
|
|
|
|
`control-api.yaml` в секции `openstack` (`auth_url_env`, `token_env` и
|
|
|
|
|
|
т.д.) — в шаблоне это ровно `OS_AUTH_URL`, `OS_TOKEN`, `OS_PROJECT_ID`,
|
|
|
|
|
|
`OS_PROJECT_NAME`, `OS_PROJECT_DOMAIN_NAME`, `OS_REGION_NAME`.
|
|
|
|
|
|
|
|
|
|
|
|
### 3. `validator-agent.yaml` (свой на каждом валидаторе)
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cp configs/validator-agent.example.yaml /etc/cloud-ip-validator/validator-agent.yaml
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Обязательно поменять:
|
|
|
|
|
|
- `validator_id` — должен совпадать с одним из `validators[].validator_id`
|
|
|
|
|
|
в конфиге control-api.
|
|
|
|
|
|
- `control_api_url` — адрес, по которому эта ВМ достучится до control-api.
|
|
|
|
|
|
|
|
|
|
|
|
### 4. `prober.yaml` (свой на каждой площадке)
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cp configs/prober.example.yaml /etc/cloud-ip-validator/prober.yaml
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Обязательно поменять:
|
|
|
|
|
|
- `site_id` — должен совпадать с одним из `sites[].site_id` в конфиге
|
|
|
|
|
|
control-api (для трёх площадок — три разных файла с `site-1`,
|
|
|
|
|
|
`site-2`, `site-3` или как вы их назвали).
|
|
|
|
|
|
- `control_api_url` — адрес control-api, доступный с площадки (обычно
|
|
|
|
|
|
через интернет — площадки внешние).
|
|
|
|
|
|
|
|
|
|
|
|
## Развёртывание control-api
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
useradd --system --no-create-home --shell /usr/sbin/nologin cloud-ip-validator
|
|
|
|
|
|
mkdir -p /var/lib/cloud-ip-validator /etc/cloud-ip-validator
|
|
|
|
|
|
chown cloud-ip-validator:cloud-ip-validator /var/lib/cloud-ip-validator
|
|
|
|
|
|
|
|
|
|
|
|
cp bin/control-api /usr/local/bin/control-api
|
|
|
|
|
|
cp deploy/systemd/control-api.service /etc/systemd/system/
|
|
|
|
|
|
|
|
|
|
|
|
systemctl daemon-reload
|
|
|
|
|
|
systemctl enable --now control-api
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**Первичная инициализация базы данных происходит автоматически** — при
|
|
|
|
|
|
первом старте `control-api` создаёт файл SQLite по пути `database.path`
|
|
|
|
|
|
из конфига (миграция схемы применяется один раз, повторные запуски —
|
|
|
|
|
|
no-op). Отдельной команды "init db" не требуется.
|
|
|
|
|
|
|
|
|
|
|
|
При каждом старте control-api также:
|
|
|
|
|
|
1. Регистрирует в БД всех валидаторов из `validators` конфига (если их
|
|
|
|
|
|
там ещё нет).
|
|
|
|
|
|
2. Добавляет в очередь все адреса из `ip_addresses`, которых там ещё нет
|
|
|
|
|
|
(уже обработанные ранее адреса повторно не добавляются и не
|
|
|
|
|
|
сбрасываются — см. [USAGE.md](USAGE.md#добавление-новых-ip-в-очередь)).
|
|
|
|
|
|
|
|
|
|
|
|
Проверить, что процесс поднялся:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
curl -s http://localhost:8080/healthz
|
|
|
|
|
|
# {"ok":true}
|
|
|
|
|
|
journalctl -u control-api -f
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## Развёртывание validator-agent на ВМ-валидаторах
|
|
|
|
|
|
|
|
|
|
|
|
Повторить на каждой ВМ-валидаторе:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cp bin/validator-agent /usr/local/bin/validator-agent
|
|
|
|
|
|
cp deploy/systemd/validator-agent.service /etc/systemd/system/
|
|
|
|
|
|
mkdir -p /etc/cloud-ip-validator
|
|
|
|
|
|
# скопировать сюда заполненный validator-agent.yaml с уникальным validator_id
|
|
|
|
|
|
|
|
|
|
|
|
systemctl daemon-reload
|
|
|
|
|
|
systemctl enable --now validator-agent
|
|
|
|
|
|
journalctl -u validator-agent -f
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Юнит выдаёт процессу capability `CAP_NET_RAW` (без root) — она нужна для
|
|
|
|
|
|
отправки ICMP echo в рамках проверок.
|
|
|
|
|
|
|
|
|
|
|
|
## Развёртывание prober на внешних площадках
|
|
|
|
|
|
|
|
|
|
|
|
Аналогично, на каждой из трёх площадок:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cp bin/prober /usr/local/bin/prober
|
|
|
|
|
|
cp deploy/systemd/prober.service /etc/systemd/system/
|
|
|
|
|
|
mkdir -p /etc/cloud-ip-validator
|
|
|
|
|
|
# скопировать сюда prober.yaml с уникальным site_id для этой площадки
|
|
|
|
|
|
|
|
|
|
|
|
systemctl daemon-reload
|
|
|
|
|
|
systemctl enable --now prober
|
|
|
|
|
|
journalctl -u prober -f
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## Проверка после запуска
|
|
|
|
|
|
|
|
|
|
|
|
После того как control-api, все валидаторы и все три пробера запущены:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
curl -s http://<control-api>:8080/api/v1/admin/status | python3 -m json.tool
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Ожидаемая картина сразу после старта: часть адресов в состоянии `queued`,
|
|
|
|
|
|
часть уже переходит в `assigning_fip`/`awaiting_self_check`/`checking` по
|
|
|
|
|
|
мере того, как освобождаются валидаторы. Через некоторое время появляются
|
|
|
|
|
|
записи в `done`/`failed`. Подробнее о том, как читать этот вывод и что
|
|
|
|
|
|
делать дальше — в [USAGE.md](USAGE.md).
|
|
|
|
|
|
|
|
|
|
|
|
Также стоит убедиться, что все валидаторы видны и не «зависли»:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
curl -s http://<control-api>:8080/api/v1/admin/validators | python3 -m json.tool
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Все зарегистрированные валидаторы должны рано или поздно оказываться в
|
|
|
|
|
|
состоянии `idle` (между заданиями) — если валидатор надолго застрял в
|
|
|
|
|
|
`unreachable`, проверьте сетевую связность до control-api и логи агента
|
|
|
|
|
|
(`journalctl -u validator-agent`).
|
|
|
|
|
|
|
|
|
|
|
|
## Сетевые доступы
|
|
|
|
|
|
|
|
|
|
|
|
Минимально необходимая связность:
|
|
|
|
|
|
|
|
|
|
|
|
- `validator-agent` → `control-api`: TCP, порт из `server.listen_addr`
|
|
|
|
|
|
(обычно 8080).
|
|
|
|
|
|
- `prober` (на каждой из 3 площадок) → `control-api`: тот же порт, обычно
|
|
|
|
|
|
через интернет.
|
|
|
|
|
|
- `prober` → адрес, который в данный момент проверяется (динамический,
|
|
|
|
|
|
меняется по ходу работы очереди): TCP 22/80/443/8080 + ICMP —
|
|
|
|
|
|
собственно и есть проверяемый трафик, его нельзя заранее ограничить
|
|
|
|
|
|
одним IP.
|
|
|
|
|
|
- `validator-agent` → интернет: HTTPS/ICMP до целей из `targets` конфига
|
|
|
|
|
|
(по умолчанию hub.docker.com, github.com, packages.ubuntu.com) — именно
|
|
|
|
|
|
через floating IP, который в данный момент привязан к валидатору.
|
|
|
|
|
|
- `control-api` → OpenStack Keystone/Neutron API (`OS_AUTH_URL` и далее по
|
|
|
|
|
|
каталогу сервисов).
|
|
|
|
|
|
|
|
|
|
|
|
API control-api сейчас не аутентифицирован (см. предупреждение в начале
|
|
|
|
|
|
[API.md](API.md)) — ограничивайте доступ к порту control-api на уровне
|
|
|
|
|
|
сети/firewall теми хостами, где реально работают валидаторы и проберы.
|