22 KiB
Подготовка стенда и первичная инициализация
Документ описывает, как подготовить конфигурацию и запустить стенд с нуля
— от чистой машины до работающего control-api, валидаторов и проберов.
Бинарники брать не обязательно из исходников: в репозитории уже лежат
готовые сборки для Linux x86_64 (bin/) — это самый быстрый путь к
развёртыванию, см. «Получение бинарников». Если
нужно просто быстро посмотреть систему в работе без реального OpenStack —
сразу переходите к разделу
«Быстрая проверка без OpenStack».
Содержание
- Компоненты и роли машин
- Требования
- Получение бинарников
- Быстрая проверка без OpenStack (offline-режим)
- Подготовка конфигурации для реального стенда
- Развёртывание control-api
- Развёртывание validator-agent на ВМ-валидаторах
- Развёртывание prober на внешних площадках
- Проверка после запуска
- Сетевые доступы
Компоненты и роли машин
| Компонент | Где запускается | Кол-во |
|---|---|---|
control-api |
Отдельная управляющая машина/ВМ с доступом к OpenStack API | 1 (без HA) |
validator-agent |
Каждая ВМ-валидатор в сервисном проекте облака | по числу валидаторов |
prober |
По одному на каждой из внешних тестовых площадок | 3 (по числу площадок) |
control-api — единственный компонент с состоянием (SQLite). Валидаторы и
проберы не хранят локального состояния и полностью управляются через опрос
control-api (см. 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 либо capabilityCAP_NET_RAW, см. юниты systemd). curl,sqlite3(опционально, для ручной инспекции БД) на машине с control-api пригодятся для диагностики.
Получение бинарников
Вариант A: готовые бинарники из репозитория (рекомендуется)
В директории bin/ репозитория уже лежат три готовых бинарника —
собирать их на целевых серверах не нужно, разворачивание сразу
начинается с копирования и запуска (раздел
«Развёртывание control-api» и далее).
bin/
├── control-api # ~11 МБ
├── validator-agent # ~7 МБ
├── prober # ~7 МБ
└── SHA256SUMS
Характеристики сборки:
- Платформа:
GOOS=linux GOARCH=amd64. CGO_ENABLED=0— статическая линковка, без cgo (используется чистый Go-драйвер SQLitemodernc.org/sqlite). Дополнительные.so-библиотеки и конкретная версия glibc на целевом сервере не требуются.- Собрано флагами
-trimpath -ldflags="-s -w"(без путей сборки и отладочной информации — компактнее и без утечки информации о машине сборки).
Убедиться в отсутствии динамических зависимостей и целостности файлов после переноса на целевой сервер:
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
Перенос на целевые серверы, например:
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: сборка из исходников
Из корня репозитория:
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 → каждая площадка).
Убедиться, что всё собирается и юнит-тесты проходят:
go build ./... && go test ./...
Пересобирайте из исходников и обновляйте bin/ с зафиксированными
SHA256SUMS, если меняли код — готовые бинарники в репозитории не
обновляются автоматически:
sha256sum bin/control-api bin/validator-agent bin/prober | sed 's#bin/##' > bin/SHA256SUMS
Быстрая проверка без OpenStack (offline-режим)
Прежде чем разворачивать реальный стенд, рекомендуется убедиться, что всё собирается и работает корректно на локальной машине — без облака и внешних площадок:
scripts/run-local-e2e.sh
Скрипт сам поднимает control-api (в режиме openstack.mode: mock),
одного validator-agent и трёх проберов как локальные процессы, прогоняет
один тестовый адрес через полный цикл проверки и печатает итоговый
результат. Подробности — в docs/LOCAL_E2E.md. Это же
хороший способ разобраться в поведении системы перед первым боевым
запуском.
Подготовка конфигурации для реального стенда
Все три компонента конфигурируются YAML-файлами. Шаблоны лежат в
configs/*.example.yaml — скопируйте их и заполните под ваш стенд.
1. control-api.yaml
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. Есть два режима аутентификации, выбираются полем
openstack.auth_method в control-api.yaml:
auth_method: "token" (по умолчанию) — вы предоставляете уже
готовый, заранее scoped на нужный проект токен (например, полученный
через openstack --os-project-id=<id> token issue). Control-api
использует его как есть, ни на что не обменивает. Просто, но токен не
самообновляется: когда он истечёт, control-api начнёт получать ошибки
от OpenStack API, пока вы вручную не перевыпустите токен, не обновите
переменную и не перезапустите процесс.
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=<токен администратора, уже scoped на сервисный проект>
OS_PROJECT_ID=<id сервисного проекта>
OS_REGION_NAME=<регион>
EOF
auth_method: "password" — вы предоставляете обычные логин/пароль;
control-api сам получает токен через Keystone и автоматически
переполучает новый при истечении текущего (весь срок жизни процесса, без
ручного вмешательства). Компромисс — в файле окружения лежит долгоживущий
пароль, а не токен.
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_PROJECT_ID=<id сервисного проекта>
OS_REGION_NAME=<регион>
OS_USERNAME=<логин>
OS_USER_DOMAIN_NAME=<домен пользователя>
OS_PASSWORD=<пароль>
EOF
и в control-api.yaml: openstack.auth_method: "password".
Опционально в обоих режимах — OS_INTERFACE (public/internal/admin,
по умолчанию public): выбирает, какой из адресов Neutron в каталоге
сервисов использовать, если у эндпоинта их несколько.
Имена переменных должны совпадать с тем, что указано в
control-api.yaml в секции openstack (auth_url_env, token_env и
т.д.) — в шаблоне это ровно OS_AUTH_URL, OS_PROJECT_ID,
OS_REGION_NAME, OS_INTERFACE, и, в зависимости от режима, либо
OS_TOKEN, либо OS_USERNAME/OS_USER_DOMAIN_NAME/OS_PASSWORD — это
стандартные имена, принятые в python-openstackclient/RC-файлах, менять их
обычно не требуется.
3. validator-agent.yaml (свой на каждом валидаторе)
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 (свой на каждой площадке)
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
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 также:
- Регистрирует в БД всех валидаторов из
validatorsконфига (если их там ещё нет). - Добавляет в очередь все адреса из
ip_addresses, которых там ещё нет (уже обработанные ранее адреса повторно не добавляются и не сбрасываются — см. USAGE.md).
Проверить, что процесс поднялся:
curl -s http://localhost:8080/healthz
# {"ok":true}
journalctl -u control-api -f
Развёртывание validator-agent на ВМ-валидаторах
Повторить на каждой ВМ-валидаторе:
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 на внешних площадках
Аналогично, на каждой из трёх площадок:
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, все валидаторы и все три пробера запущены:
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.
Также стоит убедиться, что все валидаторы видны и не «зависли»:
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, который в данный момент привязан к валидатору.validator-agent→ внешние IP-echo сервисы изself_check.ip_echo_urls(по умолчаниюapi.ipify.org,ifconfig.me) — обязательно вне облака: это и есть механизм self-check (см. DIAGRAMS.md). Если валидатор не может достучаться ни до одного из этих адресов, self-check никогда не пройдёт и IP будет бесконечно возвращаться в очередь — см. USAGE.md.control-api→ OpenStack Keystone/Neutron API (OS_AUTH_URLи далее по каталогу сервисов).
API control-api сейчас не аутентифицирован (см. предупреждение в начале API.md) — ограничивайте доступ к порту control-api на уровне сети/firewall теми хостами, где реально работают валидаторы и проберы.