Run from the jump host: on each validator it updates the git clone in /opt/cloud-ip-validator, builds the image there, stops and removes the current container and starts a new one from the new image. Run parameters live in an env file (deploy/ansible/env/validator-agent.env, git-ignored, template committed). The image is built before the running container is touched, so a failed build leaves the old container running. Hosts are updated in waves (1, 4, rest) and any failure stops the run. validator_id comes from the inventory and is checked against the running container before it is replaced. Only ansible.builtin modules are used, so the validators need no extra packages. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
10 KiB
Доставка validator-agent на валидаторы (Ansible)
Сценарий запускается с jump-хоста и на каждой ВМ-валидаторе: обновляет git-клон в /opt/cloud-ip-validator,
собирает образ на самом хосте, останавливает и удаляет старый контейнер cloud-ip-validator-validator-agent
и поднимает на его месте новый. Параметры запуска агента вынесены в env-файл.
Порядок безопасен: сначала проверки, обновление кода и сборка образа, и только потом замена контейнера. Если что-то
упало до замены, старый контейнер продолжает работать. Простой валидатора — секунды (stop + rm + run).
Требования
| Где | Что |
|---|---|
| jump-хост (Debian 13) | apt install ansible-core; SSH-доступ по ключу ко всем валидаторам |
| валидаторы | Docker, git, клон репозитория в /opt/cloud-ip-validator, sudo без пароля для SSH-пользователя, доступ к Gitea и Docker Hub (alpine:3.20), архитектура x86_64 |
Только модули ansible.builtin: Python Docker SDK и дополнительные коллекции на валидаторах не нужны.
Go на валидаторах не нужен: образ копирует закоммиченный bin/validator-agent (его сумма проверяется по bin/SHA256SUMS).
Подготовка (один раз)
cd deploy/ansible
cp env/validator-agent.env.example env/validator-agent.env
chmod 600 env/validator-agent.env
$EDITOR env/validator-agent.env # адрес control-api, токен, способы самопроверки, таймауты
ansible validators -m ping # проверка связи (20 хостов: validator-1 ... validator-20)
- В
inventory/hosts.yml20 хостовvalidator-1 … validator-20с адресами (ansible_host) и переменнойvalidator_id(vkiplab-v1 … vkiplab-v20, как в control-api). Соответствиеvalidator-N→vkiplab-vNзадано по порядку номеров; сценарий сверяетvalidator_idс тем, что записано в работающем контейнере на хосте, и при расхождении останавливается до замены контейнера.VALIDATOR_AGENT_VALIDATOR_IDв env-файл писать не нужно: сценарий подставляет его из inventory. - Отпечатки хостов запоминаются при первом подключении (
StrictHostKeyChecking=accept-newвansible.cfg); сменившийся отпечаток известного хоста — ошибка. - SSH: пользователь
debianи ключ~/.ssh/vk_cloud_priv.keyна jump-хосте (права 0600) — одинаковые на всех хостах; меняются вinventory/group_vars/validators.yml(ansible_user,ansible_ssh_private_key_file). Для docker и записи env-файла сценарий повышает права черезsudo. - Токен в env-файле можно зашифровать:
ansible-vault encrypt env/validator-agent.env, запускать с--ask-vault-pass. Рабочийenv/validator-agent.envв git не попадает (.gitignore).
Запуск
cd deploy/ansible
ansible-playbook playbooks/deploy-validator-agent.yml --limit vkiplab-v1 # канарейка: один валидатор
ansible-playbook playbooks/deploy-validator-agent.yml # все валидаторы волнами
ansible-playbook playbooks/deploy-validator-agent.yml --check # только проверки (preflight), без изменений
Волны по умолчанию: 1 хост, затем 4, затем все остальные (deploy_serial: [1, 4, "100%"]). Любой сбой в волне останавливает
прогон: следующая волна не начнётся. Все сразу: -e '{"deploy_serial": ["100%"]}'.
Что выкатывается — deploy_ref (по умолчанию main): ветка, тег или коммит. Выкатить нужно запушенный коммит:
валидаторы берут код из репозитория, а не с jump-хоста. После правок кода сначала пересоберите bin/validator-agent
(см. SETUP.md) и закоммитьте его вместе с bin/SHA256SUMS.
Откат
ansible-playbook playbooks/deploy-validator-agent.yml -e deploy_ref=<предыдущий коммит или тег>
Для тега или коммита клон переходит в detached HEAD; следующий запуск с deploy_ref=main возвращает его на ветку.
Что делает сценарий на каждом хосте
- preflight — env-файл на jump-хосте существует и в нём задан
VALIDATOR_AGENT_CONTROL_API_URL(адрес-примерexample.comне принимается); на валидаторе отвечает Docker, есть git и клон, архитектура x86_64;validator_idиз inventory совпадает сvalidator_idработающего контейнера. Показывает текущий контейнер. - git —
fetch, затем клон сбрасывается наdeploy_ref(checkout --force). Черезgit, а не модульgit: учётные данные, уже настроенные в клоне, не трогаются. Локальные правки отслеживаемых файлов в клоне будут сброшены; неотслеживаемые и игнорируемые (.env.*) — нет. - build — проверка
bin/validator-agentпоbin/SHA256SUMS;docker build --platform linux/amd64с контекстом в корне репозитория, образ получает метку ревизии (cloud-ip-validator-validator-agent:<хеш>) иlatest. - replace — env-файл копируется в
/opt/cloud-ip-validator/deploy/docker/.env.validator(0600; путь закрыт.gitignore), затемdocker stop→docker rm -f→docker run -d --restart unless-stopped --cap-add NET_RAW --env-file …. - verify — ждёт строку
registeredв логе агента (регистрация в control-api), проверяет, что контейнер запущен, без перезапусков и на только что собранном образе. При неудаче хост падает с последними строками лога, следующие волны не стартуют. Затем остаются 3 последних образа с метками ревизий (keep_images), остальные и «висячие» удаляются.
Все шаги можно запускать по тегам: --tags preflight|git|build|replace|verify.
Параметры
env/validator-agent.env — запуск агента (читает deploy/docker/validator-agent/docker-entrypoint.sh):
VALIDATOR_AGENT_CONTROL_API_URL, CONTROL_API_AGENT_TOKEN, VALIDATOR_AGENT_SELF_CHECK_METHODS,
VALIDATOR_AGENT_SELF_CHECK_TIMEOUT_SECONDS, VALIDATOR_AGENT_POLL_INTERVAL_SECONDS, VALIDATOR_AGENT_HTTPS_TIMEOUT_SECONDS,
VALIDATOR_AGENT_ICMP_TIMEOUT_SECONDS, VALIDATOR_AGENT_ICMP_COUNT, VALIDATOR_AGENT_SSH_ENABLED, VALIDATOR_AGENT_SSH_TIMEOUT_SECONDS.
Смена только env-файла не требует изменения кода: достаточно запустить сценарий (контейнер пересоздаётся с новыми значениями).
inventory/group_vars/validators.yml — доставка: repo_dir, repo_remote, deploy_ref, git_user (пользователь, у которого в клоне
настроен доступ к репозиторию; пусто — SSH-пользователь), image_name, container_name, platform, keep_images, restart_policy,
capabilities, log_max_size, log_max_file, stop_timeout, verify_retries, verify_delay, local_env_file. Любой параметр
переопределяется ключом -e.
Разбор сбоев
- «Нет env-файла» / «не задан VALIDATOR_AGENT_CONTROL_API_URL» — см. «Подготовка».
- «в запущенном контейнере validator_id=…, а в inventory …» — соответствие
validator-Nиvalidator_idвinventory/hosts.ymlневерно для этого хоста: исправьте inventory (контейнер при этом не тронут). - Контейнер не прошёл проверку — в сообщении последние строки лога.
registration failed— control-api недоступен с валидатора илиvalidator_idне заведён в control-api. Контейнер остаётся на хосте для разбора (docker logs). dubious ownership,could not read Username— клон принадлежит другому пользователю или учётные данные git есть у другого: задайтеgit_user.bin/validator-agentне совпадает с суммой — в репозитории устарелbin/SHA256SUMS: пересоберите бинарник и обновите сумму.- Сборка падает на
FROM alpine:3.20/apk add— с валидатора нет доступа к Docker Hub / репозиториям Alpine. - Старый образ другого имени остаётся — сценарий чистит только образы
image_name; образ с прежним именем удалите вручную (docker rmi).