Вторая площадка: зеркала и переход при потере главного
Профиль для двух независимых серверов на разных площадках: A — главный, B — копия. Это не HA: переход выполняет оператор, запись на время перехода останавливается, а изменения, которые B ещё не успел забрать, теряются. Механизм — зеркала репозиториев (ADR 0058) и резервные копии (BACKUP_RECOVERY).
| Что защищено | Чем | Восстановление |
|---|---|---|
| Опубликованные файлы, каталог и образы | Зеркала всех репозиториев A на B | Сразу: B раздаёт; после отсоединения — и пишет |
| Пользователи, группы, ключи, права | Свои на B, выпускаются заранее | Не нужно: потребители уже знают адрес и ключ B |
| Полное состояние A на момент T | Резервная копия A в vault вне площадки | Восстановление в пустую установку, часы на 4 ТБ |
Подготовка
Установите B той же версией, что A. Отдельная PostgreSQL и свой диск хранения — общих ресурсов у A и B нет.
На A создайте сервисный аккаунт
mirror-bс ключом только для чтения на все репозитории:artifact.list,artifact.read,content.read,annotation.read,asset.read,package.read.На B подключите зеркало каждого репозитория A (CORE_RUNBOOK):
shsudo arkvory configure --root /opt/proanima-arkvory --mirror releases \ --mirror-upstream https://arkvory-a.example --mirror-token-file /root/mirror-b.keyЕсли сертификат A выпущен корпоративным или самоподписанным УЦ, добавьте
--mirror-ca-file /root/arkvory-a-ca.pem: B будет доверять ему наравне со стандартными, проверка TLS не отключается.На B заранее выпустите потребителям (CI/CD, агенты развёртывания) свои ключи на чтение, а тем, кто будет писать после перехода, — и на запись. Запись в зеркало до перехода всё равно отклоняется (409
mirror_read_only). Права на B не копируются с A — это сознательное решение: компрометация A не даёт доступа к B.Настройте потребителей на запасной адрес B: скачивание сразу с B снимает нагрузку с канала до A. Зеркала не переносят ссылки удержания, вложения, журналы и политики хранения. Репозиторий, созданный на A позже, сам на B не появляется — подключите его зеркалом так же.
Резервные копии A — по плану, vault на томе вне площадки A (PRODUCTION).
Мониторинг B: правила
ArkvoryMirrorStale,ArkvoryMirrorFailingиArkvoryMirrorConflicts(arkvory-alerts.yml) и состояниеGET /api/v1/repositories/{r}/mirror.
Переход при потере A
Убедитесь, что A действительно недоступен для клиентов и не вернётся сам: две площадки, принимающие запись в один логический репозиторий, потом не сводятся.
Остановите запись на A, если он частично доступен (остановить службы или закрыть порт).
Посмотрите на B, когда каждое зеркало синхронизировалось последний раз (
syncedAt): изменения A после этого момента на B отсутствуют.Отсоедините зеркала на B — репозитории становятся обычными и принимают запись:
shsudo arkvory configure --root /opt/proanima-arkvory --mirror-detach releasesПереключите потребителей записи на B (DNS или настройка CI).
Проверьте на B контрольное скачивание и загрузку.
Возврат
Обратной синхронизации нет. A возвращается как новая копия B: очистите A (или установите заново) и подключите на нём зеркала репозиториев B. Затем, при желании, поменяйте роли тем же переходом в окне обслуживания. Запускать старый A параллельно с B нельзя.
Учения
Раз в квартал и после обновлений:
- на тестовом стенде или на копии B выполните переход (отсоединение одного репозитория);
- проверьте
syncedAt, скачивание, загрузку; - отдельно — восстановление резервной копии A в пустую установку (CORE_RUNBOOK).
Дату и результат учений ведёт оператор.
Автоматическая проверка
Гейт deployment-stand (tests/deployment/two-site-stand.mjs) проходит этот профиль на двух Linux-хостах с systemd в одной Docker-сети. На каждом — своя установка из .deb со своей PostgreSQL. Сценарий:
- A включает HTTPS с сертификатом своего УЦ на имя
arkvory-a. - На A создаётся ключ
mirror-bтолько для чтения. - B подключает зеркало через
arkvory configure --mirror. Без--mirror-ca-fileустановщик отказывает, ничего не меняя; с ним подключает. - B засевается, затем следует за A, включая образы контейнеров, объекты Git LFS и npm-пакеты (блокировки LFS не переносятся). Запись в зеркало отклоняется.
- A отключается от сети: B продолжает раздавать и показывает ошибку в статусе.
- После
--mirror-detachB принимает запись, его копии на месте.
Гейт выполняется в lane linux-system локального конвейера и в задании stand GitHub Actions. Учения на настоящих серверах он не заменяет: сеть между площадками, DNS и балансировщик остаются за оператором.