Миграция S3 через Rclone: копирование, проверка и переключение
Миграция S3 через Rclone: копирование, проверка и переключение
Источники проверены 12 октября 2026 года. Это редакционный рецепт для Linux/Bash и двух S3-совместимых хранилищ. Реальная миграция, тесты S3 API и измерения производительности при подготовке не выполнялись. Перед использованием зафиксируйте установленную версию rclone version, ОС, endpoint и настройки обоих провайдеров в закрытом журнале.
Повод и границы рецепта
11 октября в 12:30 МСК Selectel сообщил о высокой нагрузке на сервис миграции данных в S3 и рекомендовал Rclone либо другой инструмент переноса. На выборочную проверку 12 октября карточка содержит Issue. Это не сообщение об отказе всего S3, потере объектов или невозможности обычного GET/PUT. Хронология ограничений хранится в октябрьском дополнении к журналу Selectel.
Официальный пример Selectel обновлён 5 октября: дата инструкции не является датой инцидента. Ниже добавлены контрольные точки SEO Recipes, а не обещание провайдера о результате переноса.
Рецепт переносит текущие версии объектов выбранного бакета или префикса. Это не полноценная репликация истории версий, delete markers, политик доступа и настроек бакета. Перенос файлов работающей БД не создаёт согласованный backup БД. Агентный Cloud Backup внешнего VPS решает другую задачу.
1. Подготовить отдельную цель и доступы
Создайте отдельный приватный целевой бакет заранее. Убедитесь, что выбранная локация принимает новые ресурсы и доступна именно из узла миграции. Проверьте стоимость исходящего трафика источника, операций API, хранения, чтения архивных классов и повторных проверок. Обещанный лимит квоты не доказывает наличие ёмкости.
В rclone config заведите две конфигурации S3 — source и destination. Endpoint, region и способ адресации берите из документации конкретного хранилища, не копируйте их между провайдерами. Проверьте, что разные имена конфигураций действительно указывают на разные бакеты: сравнение строк этого не гарантирует.
Для источника используйте разрешения чтения и перечисления нужных объектов; для назначения — минимальные права перечисления, чтения и загрузки, включая необходимые операции multipart. Не предоставляйте удаление источника. Не отключайте проверку TLS. Ключи вводите через защищённую конфигурацию, не через аргументы команды, публичный issue или shell history.
Сохраните настройки отдельно: bucket policy, CORS, lifecycle, versioning, Object Lock/retention, шифрование и доступ к KMS, уведомления, CDN и пользовательские домены. Их перенос требует собственной процедуры. Возможности сохранения метаданных зависят от S3 backend Rclone и обеих реализаций API; флаг --metadata не заменяет эту проверку.
2. Сначала проверить план
Следующие блоки выполняются по одному в одной сессии Bash, после подстановки своих имён. Первый блок не копирует объекты, но перечисление может вызывать оплачиваемые API-запросы. Конфигурационный файл должен уже существовать; команды не создают бакеты.
set -euo pipefail
umask 077
command -v rclone >/dev/null
CFG="$HOME/.config/rclone/seo-recipes-migration.conf"
SRC='source:SOURCE_BUCKET/PREFIX'
DST='destination:DESTINATION_BUCKET/PREFIX'
[[ -f "$CFG" ]] || { echo 'Сначала настройте отдельный config Rclone' >&2; exit 1; }
[[ "$SRC" != *SOURCE_BUCKET* && "$DST" != *DESTINATION_BUCKET* ]] || {
echo 'Замените имена бакетов и префиксы' >&2; exit 1;
}
[[ "$SRC" != "$DST" ]] || { echo 'Источник совпадает с назначением' >&2; exit 1; }
chmod 600 "$CFG"
RUN=$(mktemp -d "${TMPDIR:-/tmp}/s3-migration.XXXXXX")
rclone version > "$RUN/version.txt"
date -u '+%Y-%m-%dT%H:%M:%SZ' > "$RUN/started-at.txt"
rclone copy "$SRC" "$DST" --config "$CFG" --metadata \
--transfers 2 --checkers 2 --s3-upload-concurrency 2 \
--dry-run --log-level INFO --log-file "$RUN/plan.log"
printf 'Закрытый журнал: %s\n' "$RUN"
Значение PREFIX замените своим или уберите вместе с предшествующим / для целого бакета. Просмотрите план: направление, ключи объектов, фильтры, объём и предполагаемые перезаписи. Отсутствие объектов или неполный листинг источника — причина остановиться и проверить доступ, а не переходить к sync.
По документации copy, лишние объекты назначения не удаляются, но изменившиеся объекты с теми же ключами могут перезаписываться. Поэтому цель должна быть изолирована от рабочих записей. --dry-run не доказывает возможность загрузки и сохранность данных.
Параллелизм 2 здесь — осторожная стартовая настройка, не результат бенчмарка. В примере Selectel указано 10 с рекомендацией уменьшать значение при тайм-аутах. Учитывайте также multipart-потоки, rate limits и нагрузку приложения; повышение числа потоков не исправляет недоступный источник.
3. Копировать только после согласования
Сначала испытайте небольшой набор синтетических объектов в выделенных тестовых бакетах: пустой объект, Unicode-ключ, небольшой файл, объект multipart-размера и разные HTTP-метаданные. Успех такого теста не заменяет финальную проверку всего рабочего набора.
После проверки плана следующий блок создаёт и может перезаписывать объекты назначения. Вся передача между независимыми хранилищами может проходить через машину с Rclone: проверьте её сеть, доверенность и расходы. Не запускайте этот блок автоматически по появлению новости.
: "${SRC:?}" "${DST:?}" "${CFG:?}" "${RUN:?}"
read -r -p 'План проверен; разрешить запись в целевой бакет? Введите COPY: ' answer
[[ "$answer" == 'COPY' ]] || { echo 'Копирование отменено' >&2; exit 1; }
rclone copy "$SRC" "$DST" --config "$CFG" --metadata \
--transfers 2 --checkers 2 --s3-upload-concurrency 2 \
--log-level INFO --log-file "$RUN/copy.log"
Ненулевой код выхода и ошибки чтения/записи не превращайте в успех через || true. До повторного запуска выясните причину; не запускайте одновременно несколько конкурирующих переносов. Логи могут содержать чувствительные ключи объектов — храните их вне публичного репозитория.
4. Зафиксировать конечное состояние источника
До окончательной проверки остановите изменения исходного набора: приложение, фоновые задания, удаления, lifecycle-действия и незавершённые загрузки. Согласуйте окно read-only и зависимости между объектами и записями БД. Одна смена прав ключа миграции не останавливает других писателей.
Повторите план и copy после заморозки. Объекты, удалённые в источнике между первым и последним проходом, могут остаться в цели; это нужно выявить до переключения. Если API источника не позволяет получить полный стабильный список или прочитать данные, не объявляйте миграцию завершённой.
rclone sync может удалять объекты назначения, которых нет в источнике — это принципиально отличается от copy. Не используйте его как безусловный «следующий шаг». Точное зеркало допускается только после отдельного согласования удалений, проверки полного источника, резервирования цели и просмотра sync --dry-run; здесь команда с реальным удалением намеренно не приводится. Не применяйте --ignore-errors или --delete-excluded для обхода этой проверки. Семантика — в официальной документации sync.
5. Проверить данные, затем свойства и приложение
Равенство числа объектов и общего размера не доказывает целостность. Для multipart и некоторых способов шифрования ETag не является MD5 всего объекта. Даже --checksum при отсутствии общего хеша может свестись к сравнению размера; не представляйте такой результат как побайтовую проверку.
После согласования стоимости полный check --download читает содержимое с обеих сторон. Это дополнительные чтения и трафик; для большого набора сначала оцените бюджет. Пример не использует --one-way, чтобы не скрывать лишние объекты назначения.
: "${SRC:?}" "${DST:?}" "${CFG:?}" "${RUN:?}"
read -r -p 'Разрешить полное чтение обоих наборов для проверки? Введите CHECK: ' answer
[[ "$answer" == 'CHECK' ]] || { echo 'Проверка отменена' >&2; exit 1; }
rclone check "$SRC" "$DST" --config "$CFG" --download \
--checkers 2 --combined "$RUN/check-results.txt" \
--log-level INFO --log-file "$RUN/check.log"
check не изменяет хранилища. Любое расхождение, отсутствующий объект или ошибка чтения блокирует переключение до разбора. Если copy пропустил объект из-за сравнения размера/времени, исправьте именно подтверждённые расхождения и повторите проверку. Не скрывайте их флагом --size-only.
Отдельно проверьте Content-Type, Cache-Control, Content-Encoding, пользовательские метаданные, требуемые теги и права: сравнение содержимого этого не делает. Проверьте приватность, CORS, подпись временных URL, диапазонные запросы и получение файлов через приложение/CDN. Подтвердите отсутствие случайного публичного доступа. Версии объектов, retention и история удалений требуют отдельной приёмки либо явной отметки «не переносились».
6. Переключение и возможность восстановления
Назначьте ответственного и согласуйте переход приложения на новое хранилище только после принятия данных и настроек. Убедитесь, что остался один источник записи; проверьте загрузку, чтение и удаление отдельного тестового объекта с разрешения владельца, обработку фоновых задач и фактическое содержимое страниц сайта.
Старое хранилище сохраняйте в read-only на согласованный срок. После появления новых данных в цели обратное переключение без сверки состояний может потерять изменения; обратный sync не является безопасным автоматическим откатом. План очистки источника согласуется отдельно, его команды не входят в рецепт.
Критерии приёмки: принятый состав данных, успешная проверка содержимого, проверенные свойства и права, рабочие бизнес-сценарии, независимый backup и записанные остаточные ограничения. Неизмеренные параметры отмечаются как «не проверено», а не нулём или успехом.
Источники и границы проверки
- Selectel: высокая нагрузка на S3 Migration, 11 октября
- Selectel: пример миграции через Rclone, редакция 5 октября
- Rclone copy
- Rclone sync
- Rclone check
- Rclone S3: хеши, метаданные и настройки backend
Дата чтения этих источников — 12 октября 2026 года. Это не утверждение о новом релизе Rclone. Бинарник Rclone в редакционной среде отсутствует: интеграционный сценарий на S3 и совместимость конкретной версии должны быть проверены владельцем на тестовых данных; успешная миграция здесь не заявляется.
