Для совместного запуска всех компонентов теперь есть docker-compose:
docker-compose.yml (база) + docker-compose.override.yml (dev, подхватывается
автоматически) + docker-compose.prod.yml (прод). Быстрый старт:

  cp .env.example .env
  cp control-api/control-api.docker.example.yaml control-api/control-api.docker.yaml
  docker compose up -d --build

Подробности — в README.md, раздел "Развёртывание в Docker". Команды ниже
документируют то же самое на уровне отдельного docker build/docker run —
пригодятся для точечной отладки одного компонента без compose.

===============================================================================

Сборка образа (из корня репозитория):

docker build --platform linux/amd64 -t cloud-ip-validator-prober -f deploy/docker/prober/Dockerfile .

Запуск контейнера-пробера:

docker run -d --platform linux/amd64 --cap-add NET_RAW --name prober \
  -e PROBER_SITE_ID=<site_id> \
  -e PROBER_CONTROL_API_URL=<http://control-api-host:port> \
  -e PROBER_POLL_INTERVAL_SECONDS=5 \
  -e PROBER_TCP_TIMEOUT_SECONDS=5 \
  -e PROBER_ICMP_TIMEOUT_SECONDS=5 \
  -e PROBER_ICMP_COUNT=3 \
  -e CONTROL_API_AGENT_TOKEN=<agent_token> \
  cloud-ip-validator-prober

Рабочий пример (стенд 62.176.10.113):

docker run -d --platform linux/amd64 --cap-add NET_RAW --name prober \
  -e PROBER_SITE_ID=sbas \
  -e PROBER_CONTROL_API_URL=http://62.176.10.113:8081 \
  cloud-ip-validator-prober

Переменные окружения:
  PROBER_SITE_ID               обязательная, должна быть зарегистрирована в
                               control-api (PUT /api/v1/admin/config/sites/{index})
  PROBER_CONTROL_API_URL       обязательная
  PROBER_POLL_INTERVAL_SECONDS опциональная, дефолт 5
  PROBER_TCP_TIMEOUT_SECONDS   опциональная, дефолт 5
  PROBER_ICMP_TIMEOUT_SECONDS  опциональная, дефолт 5
  PROBER_ICMP_COUNT            опциональная, дефолт 3
  CONTROL_API_AGENT_TOKEN      опциональная: токен агентов control-api (то же
                               значение, что у control-api); без него результаты
                               проверок будут отклонены, если токен включён

Примечания:
  --platform linux/amd64  бинарник в bin/ собран под Linux x86_64
  --cap-add NET_RAW       нужен проберу для ICMP-проверок

===============================================================================

Сборка образа admin-dashboard (из корня репозитория):

docker build --platform linux/amd64 -t cloud-ip-validator-admin-dashboard -f deploy/docker/admin-dashboard/Dockerfile .

Запуск контейнера admin-dashboard:

docker run -d --platform linux/amd64 -p 8090:8090 --name admin-dashboard \
  -e ADMIN_DASHBOARD_CONTROL_API_URL=<http://control-api-host:port> \
  -e ADMIN_DASHBOARD_LISTEN_ADDR=:8090 \
  -e ADMIN_DASHBOARD_CONTROL_API_TIMEOUT_SECONDS=10 \
  -e ADMIN_DASHBOARD_LAST_COMPLETED_COUNT=20 \
  -e ADMIN_DASHBOARD_POLL_INTERVAL_SECONDS=5 \
  -e ADMIN_DASHBOARD_CONTROL_API_TOKEN=<admin_token> \
  -e ADMIN_DASHBOARD_USERNAME=<login> \
  -e ADMIN_DASHBOARD_PASSWORD=<password> \
  -e ADMIN_DASHBOARD_SESSION_SECRET=<random_hex> \
  cloud-ip-validator-admin-dashboard

Рабочий пример (стенд 62.176.10.113):

docker run -d --platform linux/amd64 -p 8090:8090 --name admin-dashboard \
  -e ADMIN_DASHBOARD_CONTROL_API_URL=http://62.176.10.113:8081 \
  cloud-ip-validator-admin-dashboard

Переменные окружения:
  ADMIN_DASHBOARD_CONTROL_API_URL             обязательная
  ADMIN_DASHBOARD_LISTEN_ADDR                 опциональная, дефолт :8090
  ADMIN_DASHBOARD_CONTROL_API_TIMEOUT_SECONDS опциональная, дефолт 10
  ADMIN_DASHBOARD_LAST_COMPLETED_COUNT        опциональная, дефолт 20
  ADMIN_DASHBOARD_POLL_INTERVAL_SECONDS       опциональная, дефолт 5
  ADMIN_DASHBOARD_CONTROL_API_TOKEN           опциональная: admin-токен control-api
  ADMIN_DASHBOARD_USERNAME / _PASSWORD        опциональные: логин дашборда; если не
                                              заданы оба — вход не требуется (в логе
                                              предупреждение)
  ADMIN_DASHBOARD_SESSION_SECRET              опциональная: ключ подписи cookie сессии;
                                              без неё случайный, сессии сбрасываются
                                              рестартом
  (секреты генерируются так: openssl rand -hex 32)

Примечания:
  --platform linux/amd64  бинарник в bin/ собран под Linux x86_64
  -p 8090:8090            проброс порта дашборда наружу

===============================================================================

Сборка образа control-api (из корня репозитория):

docker build --platform linux/amd64 -t cloud-ip-validator-control-api -f deploy/docker/control-api/Dockerfile .

У control-api конфиг содержит списки (validators/sites/check_types/targets/
ip_addresses) и имена env-переменных для OpenStack-креденшлов — это не
шаблонизируется через docker run -e, как у остальных компонентов. Конфиг
монтируется файлом (по образцу configs/control-api.example.yaml, который
также лежит в образе как /etc/cloud-ip-validator/control-api.yaml.example),
а сама база данных — volume'ом для персистентности.

Запуск контейнера control-api:

docker run -d --platform linux/amd64 -p 8080:8080 --name control-api \
  -v /path/to/control-api.yaml:/etc/cloud-ip-validator/control-api.yaml:ro \
  -v cloud-ip-validator-db:/var/lib/cloud-ip-validator \
  -e OS_AUTH_URL=<keystone_url> \
  -e OS_PROJECT_ID=<project_id> \
  -e OS_REGION_NAME=<region> \
  -e OS_TOKEN=<token> \
  -e CONTROL_API_ADMIN_TOKEN=<admin_token> \
  -e CONTROL_API_AGENT_TOKEN=<agent_token> \
  cloud-ip-validator-control-api

(при auth_method: password — вместо OS_TOKEN передать OS_USERNAME,
OS_USER_DOMAIN_NAME, OS_PASSWORD; для openstack.mode: mock креденшлы не
нужны)

CONTROL_API_ADMIN_TOKEN закрывает /api/v1/admin/*, CONTROL_API_AGENT_TOKEN —
запись результатов/событий агентами и пробером; не заданный токен оставляет
соответствующий уровень открытым (в логе предупреждение).

Примечания:
  --platform linux/amd64  бинарник в bin/ собран под Linux x86_64
  -p 8080:8080             проброс порта control-api наружу
  -v .../control-api.yaml  обязателен: конфиг с validators/sites/targets/ip_addresses
  -v cloud-ip-validator-db  volume для /var/lib/cloud-ip-validator/control-api.db

===============================================================================

Сборка образа validator-agent (из корня репозитория):

docker build --platform linux/amd64 -t cloud-ip-validator-validator-agent -f deploy/docker/validator-agent/Dockerfile .

Запуск контейнера validator-agent:

docker run -d --platform linux/amd64 --cap-add NET_RAW --name validator-agent \
  -e VALIDATOR_AGENT_VALIDATOR_ID=<validator_id> \
  -e VALIDATOR_AGENT_CONTROL_API_URL=<http://control-api-host:port> \
  -e VALIDATOR_AGENT_POLL_INTERVAL_SECONDS=5 \
  -e VALIDATOR_AGENT_SELF_CHECK_TIMEOUT_SECONDS=10 \
  -e VALIDATOR_AGENT_HTTPS_TIMEOUT_SECONDS=10 \
  -e VALIDATOR_AGENT_ICMP_TIMEOUT_SECONDS=5 \
  -e VALIDATOR_AGENT_ICMP_COUNT=3 \
  -e VALIDATOR_AGENT_SSH_ENABLED=false \
  -e VALIDATOR_AGENT_SSH_TIMEOUT_SECONDS=5 \
  -e CONTROL_API_AGENT_TOKEN=<agent_token> \
  cloud-ip-validator-validator-agent

Переменные окружения:
  VALIDATOR_AGENT_VALIDATOR_ID             обязательная, должен совпадать с
                                           control-api config's validators[].validator_id
  VALIDATOR_AGENT_CONTROL_API_URL          обязательная
  VALIDATOR_AGENT_POLL_INTERVAL_SECONDS    опциональная, дефолт 5
  VALIDATOR_AGENT_SELF_CHECK_TIMEOUT_SECONDS опциональная, дефолт 10
  VALIDATOR_AGENT_HTTPS_TIMEOUT_SECONDS    опциональная, дефолт 10
  VALIDATOR_AGENT_ICMP_TIMEOUT_SECONDS     опциональная, дефолт 5
  VALIDATOR_AGENT_ICMP_COUNT               опциональная, дефолт 3
  VALIDATOR_AGENT_SSH_ENABLED              опциональная, дефолт false
  VALIDATOR_AGENT_SSH_TIMEOUT_SECONDS      опциональная, дефолт 5
  CONTROL_API_AGENT_TOKEN                  опциональная: токен агентов control-api
                                           (то же значение, что у control-api)

Примечания:
  --platform linux/amd64  бинарник в bin/ собран под Linux x86_64
  --cap-add NET_RAW       нужен агенту для ICMP-проверок
  ip_echo_urls            в шаблон не выведены — при отсутствии в конфиге
                          агент сам подставляет дефолт (api.ipify.org,
                          ifconfig.me/ip); свой список задавайте через
                          смонтированный конфиг вместо шаблона при необходимости
