Skip to content

Вторая площадка: зеркала и переход при потере главного ​

Профиль для двух независимых серверов на разных площадках: A — главный, B — копия. Это не HA: переход выполняет оператор, запись на время перехода останавливается, а изменения, которые B ещё не успел забрать, теряются. Механизм — зеркала репозиториев (ADR 0058) и резервные копии (BACKUP_RECOVERY).

Что защищеноЧемВосстановление
Опубликованные файлы, каталог и образыЗеркала всех репозиториев A на BСразу: B раздаёт; после отсоединения — и пишет
Пользователи, группы, ключи, праваСвои на B, выпускаются заранееНе нужно: потребители уже знают адрес и ключ B
Полное состояние A на момент TРезервная копия A в vault вне площадкиВосстановление в пустую установку, часы на 4 ТБ

Подготовка ​

  1. Установите B той же версией, что A. Отдельная PostgreSQL и свой диск хранения — общих ресурсов у A и B нет.

  2. На A создайте сервисный аккаунт mirror-b с ключом только для чтения на все репозитории: artifact.list, artifact.read, content.read, annotation.read, asset.read, package.read.

  3. На B подключите зеркало каждого репозитория A (CORE_RUNBOOK):

    sh
    sudo 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 не отключается.

  4. На B заранее выпустите потребителям (CI/CD, агенты развёртывания) свои ключи на чтение, а тем, кто будет писать после перехода, — и на запись. Запись в зеркало до перехода всё равно отклоняется (409 mirror_read_only). Права на B не копируются с A — это сознательное решение: компрометация A не даёт доступа к B.

  5. Настройте потребителей на запасной адрес B: скачивание сразу с B снимает нагрузку с канала до A. Зеркала не переносят ссылки удержания, вложения, журналы и политики хранения. Репозиторий, созданный на A позже, сам на B не появляется — подключите его зеркалом так же.

  6. Резервные копии A — по плану, vault на томе вне площадки A (PRODUCTION).

  7. Мониторинг B: правила ArkvoryMirrorStale, ArkvoryMirrorFailing и ArkvoryMirrorConflicts (arkvory-alerts.yml) и состояние GET /api/v1/repositories/{r}/mirror.

Переход при потере A ​

  1. Убедитесь, что A действительно недоступен для клиентов и не вернётся сам: две площадки, принимающие запись в один логический репозиторий, потом не сводятся.

  2. Остановите запись на A, если он частично доступен (остановить службы или закрыть порт).

  3. Посмотрите на B, когда каждое зеркало синхронизировалось последний раз (syncedAt): изменения A после этого момента на B отсутствуют.

  4. Отсоедините зеркала на B — репозитории становятся обычными и принимают запись:

    sh
    sudo arkvory configure --root /opt/proanima-arkvory --mirror-detach releases
  5. Переключите потребителей записи на B (DNS или настройка CI).

  6. Проверьте на 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. Сценарий:

  1. A включает HTTPS с сертификатом своего УЦ на имя arkvory-a.
  2. На A создаётся ключ mirror-b только для чтения.
  3. B подключает зеркало через arkvory configure --mirror. Без --mirror-ca-file установщик отказывает, ничего не меняя; с ним подключает.
  4. B засевается, затем следует за A, включая образы контейнеров, объекты Git LFS и npm-пакеты (блокировки LFS не переносятся). Запись в зеркало отклоняется.
  5. A отключается от сети: B продолжает раздавать и показывает ошибку в статусе.
  6. После --mirror-detach B принимает запись, его копии на месте.

Гейт выполняется в lane linux-system локального конвейера и в задании stand GitHub Actions. Учения на настоящих серверах он не заменяет: сеть между площадками, DNS и балансировщик остаются за оператором.

Arkvory · ProAnimaStudio