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

342 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Подготовка стенда и первичная инициализация
Документ описывает, как подготовить конфигурацию и запустить стенд с нуля
— от чистой машины до работающего control-api, валидаторов и проберов.
Бинарники брать не обязательно из исходников: в репозитории уже лежат
готовые сборки для Linux x86_64 (`bin/`) — это самый быстрый путь к
развёртыванию, см. [«Получение бинарников»](#получение-бинарников). Если
нужно просто быстро посмотреть систему в работе без реального OpenStack —
сразу переходите к разделу
[«Быстрая проверка без OpenStack»](#быстрая-проверка-без-openstack-offline-режим).
## Содержание
- [Компоненты и роли машин](#компоненты-и-роли-машин)
- [Требования](#требования)
- [Получение бинарников](#получение-бинарников)
- [Вариант A: готовые бинарники из репозитория (рекомендуется)](#вариант-a-готовые-бинарники-из-репозитория-рекомендуется)
- [Вариант B: сборка из исходников](#вариант-b-сборка-из-исходников)
- [Быстрая проверка без 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)).
## Требования
- Целевые серверы (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 —
инструмент их **не создаёт**, только привязывает/отвязывает
существующие.
- Для `validator-agent` и `prober` — возможность отправлять ICMP echo
(нужен root либо capability `CAP_NET_RAW`, см. юниты systemd).
- `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
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
```
Каждый бинарник самодостаточен — скопируйте нужный файл на
соответствующую машину (control-api → управляющая машина, validator-agent
→ каждый валидатор, prober → каждая площадка).
Убедиться, что всё собирается и юнит-тесты проходят:
```bash
go build ./... && go test ./...
```
Пересобирайте из исходников и обновляйте `bin/` с зафиксированными
`SHA256SUMS`, если меняли код — готовые бинарники в репозитории **не
обновляются автоматически**:
```bash
sha256sum bin/control-api bin/validator-agent bin/prober | sed 's#bin/##' > bin/SHA256SUMS
```
## Быстрая проверка без 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 теми хостами, где реально работают валидаторы и проберы.