Миграция в облако: с on-premise и между провайдерами
Production-сервер с 8-летней историей: три поколения разработчиков, никакой документации, crontab -l выдаёт 47 задач, половина из которых непонятно зачем. MySQL 5.6, EOL более двух лет назад. PHP 7.2. Пачка bash-скриптов в /opt/scripts/ без git. Задача — перенести это в Yandex Cloud за два месяца без остановки сервиса. Вот с чего мы начинаем.
Аудит перед миграцией: что реально живёт на сервере
Первое, что делаем — полная инвентаризация. Не по памяти тимлида, а инструментами.
# Что запущено и слушает порты ss -tlnp # Все процессы с их cmdline ps auxf # Cron всех пользователей for user in $(cut -f1 -d: /etc/passwd); do echo "=== $user ==="; crontab -u $user -l 2>/dev/null; done # Зависимости PHP-приложения composer show --installed # Установленные пакеты с датой dpkg-query -W -f='${Package} ${Version} ${Status}\n' | grep installed # Хардкод localhost в конфигах grep -r "127.0.0.1\|localhost" /etc/app/ /var/www/ --include='*.{php,yml,conf,env}' Systemd units, initd-скрипты, supervisor-конфиги, nginx виртуальные хосты — всё фиксируем. Неочевидный момент: ss -tlnp часто показывает сервисы, о которых никто из команды не знает. Memcached на нестандартном порту, внутренний HTTP-сервер метрик, старый Zookeeper. Каждый такой сервис — зависимость, которую нужно либо мигрировать, либо сознательно выключить.
Профиль нагрузки. Нас интересуют пиковые значения за последние 90 дней — не средние. Если Grafana или Zabbix не настроены, смотрим sar (если sysstat установлен), /var/log/mysql/slow_query.log, vmstat 1 60 во время пиковой нагрузки. Без понимания пиков — невозможно выбрать правильный размер облачных инстансов.
Зависимости между сервисами. На монолитных серверах всё связано напрямую через localhost. В облаке сервисы разъедутся по разным IP — нужна схема: кто к кому обращается, какие порты, есть ли хардкод 127.0.0.1 в конфигах. grep -r находит это быстро, но проверяй и env-файлы, и config/*.php, и application.yml.
Как выбрать стратегию миграции?
Два основных подхода — lift-and-shift и re-platform. Выбор между ними — архитектурное решение, а не технический вопрос.
Lift-and-shift — берём то, что есть, и переносим «как есть» на облачные VMs. Быстро, малорискованно, минимальные изменения кода. Результат — тот же монолит, только в облаке. Не получаем автоскейлинг, managed-сервисы, elastic pricing. Оправдано, если: дедлайн жёсткий, кодовая база не менялась годами, команда маленькая.
Re-platform — на этапе миграции переключаемся с самоуправляемых компонентов на managed-сервисы. MySQL 5.6 → Yandex Managed PostgreSQL 15. Redis на VM → Yandex Managed Redis. Файловое хранилище → Object Storage. Это занимает больше времени, но результат — реально облачная архитектура. Риск: несовместимости при смене БД, изменения в коде, которые нужно тестировать.
Третий вариант — re-architect (контейнеризация, микросервисы) — в рамках миграции нецелесообразен. Это отдельный проект. Совмещать облачный переезд с переписыванием архитектуры — прямой путь к провалу обоих.
Сравнение подходов:
| Критерий | Lift-and-shift | Re-platform |
|---|---|---|
| Время выполнения | 2-3 недели | 4-8 недель |
| Изменения в коде | Минимальные | Умеренные (смена драйверов БД, путей к файлам) |
| Риски | Низкие | Средние (несовместимости СУБД) |
| Выгода от облака | Низкая (те же VM) | Высокая (managed-сервисы, автоскейлинг) |
| Типичная экономия | 10-20% | 30-50% на инфраструктуре |
Паттерны миграции данных
Это самая сложная часть. Данные — единственное, что нельзя откатить.
Strangler Fig для постепенного переноса
Паттерн Strangler Fig (описан в книге «Шаблоны корпоративных приложений» Мартина Фаулера): новые запросы постепенно перенаправляются на новую инфраструктуру, старая работает параллельно. Балансировщик (nginx, HAProxy) направляет часть трафика на новые серверы, часть — на старые. Соотношение меняется по мере проверки работоспособности.
upstream backend_old { server 192.168.1.100:8080 weight=9; } upstream backend_new { server 10.0.1.50:8080 weight=1; } # canary: 10% на новый, 90% на старый split_clients "${remote_addr}${date_gmt}" $backend { 10% backend_new; * backend_old; } Для stateless-сервисов это работает хорошо. Для stateful — нужна репликация данных в обоих направлениях на период параллельной работы.
MySQL → managed PostgreSQL: реальные грабли
Прямой дамп не работает между разными СУБД. Инструменты: pgloader, AWS Schema Conversion Tool (работает и не с AWS), ручная конвертация DDL.
pgloader умеет читать из MySQL и писать в PostgreSQL напрямую:
LOAD DATABASE FROM mysql://user:pass@old-server/mydb INTO postgresql://user:pass@new-server/mydb WITH include drop, create tables, create indexes, reset sequences, foreign keys SET MySQL PARAMETERS net_read_timeout = '120', net_write_timeout = '120' CAST type bigint to bigint drop typemod, type varchar to text; Но pgloader не обрабатывает специфику MySQL, которая несовместима с PostgreSQL:
-
ENUMв MySQL конвертируется вTEXTили кастомный тип — надо решить до миграции - MySQL-специфичные функции в stored procedures (
GROUP_CONCAT,IFNULL,DATE_FORMAT) — переписываем вручную на PostgreSQL-аналоги -
utf8mb4в MySQL =utf8в PostgreSQL (PostgreSQL всегда использует 4-byte UTF-8), ноCOLLATIONнужно явно задать - Автоинкрементные поля: в PostgreSQL это
SERIALилиGENERATED ALWAYS AS IDENTITY— после импорта нужно сбросить sequences черезsetval
Проверка после миграции: SELECT COUNT(*) FROM для каждой таблицы на обоих серверах, сравнение хэшей ключевых записей. Расхождение в 1 строку из миллиона — катастрофа, если это заказ или транзакция.
Синхронизация в реальном времени во время cut-over
Cut-over — момент переключения DNS/балансировщика с старого на новый сервер. Цель: минимизировать окно, когда данные на старом сервере изменяются, а на новый не попадают.
Для MySQL → MySQL (lift-and-shift): настраиваем репликацию old-master → new-slave на период миграции. Cut-over:
- Включаем maintenance mode в приложении (или переключаем балансировщик на страницу «технические работы»)
- Ждём, пока
SHOW SLAVE STATUSна новом сервере покажетSeconds_Behind_Master: 0 - На старом:
FLUSH TABLES WITH READ LOCK - Проверяем
SHOW MASTER STATUS— позиция лога - На новом:
STOP SLAVEпосле достижения той же позиции - Меняем connection string в приложении → перезапускаем
-
UNLOCK TABLESна старом - Переключаем DNS/балансировщик
Окно read-lock — секунды, не минуты. Если дольше — что-то пошло не так, откатываемся.
Миграция файлов и объектного хранилища
Статика, загрузки пользователей, бекапы — обычно гигабайты или терабайты. rsync с прогрессом и checksumming:
rsync -avz --checksum --progress \ --exclude='*.tmp' \ /var/www/uploads/ \ user@new-server:/var/www/uploads/ Для терабайтных объёмов — rsync с --bwlimit чтобы не перегрузить канал на старом сервере во время работы. Первый прогон делаем заранее (за день-два до cut-over), второй — непосредственно перед переключением, только дельту.
При переносе в Object Storage используем rclone sync с 16 параллельными потоками. После переноса — CDN перед Object Storage. Yandex Cloud CDN настраивается на бакет как origin. Публичный URL приложения меняется: https://cdn.example.com/uploads/file.jpg вместо /uploads/file.jpg. Это изменение кода, которое нужно тестировать.
Как мигрировать между облачными провайдерами?
Переход с AWS на Hetzner или между российскими провайдерами — отдельный сценарий. Kubernetes workloads переезжают относительно чисто: экспорт манифестов через kubectl get all -A -o yaml, замена cloud-специфичных аннотаций (StorageClass, LoadBalancer annotations), деплой на новый кластер.
Velero для backup+restore Kubernetes ресурсов:
# Backup на источнике velero backup create full-backup \ --include-namespaces=production,staging \ --storage-location=aws-s3 # Restore на целевом кластере velero restore create --from-backup full-backup \ --namespace-mappings "production:production" PersistentVolumes — сложнее. Velero делает volume snapshots через CSI-драйвер, но снапшоты привязаны к провайдеру. Между провайдерами: остановить поды, скопировать данные через временный rsync-под, создать PVC на новом кластере, восстановить данные, запустить поды.
Managed-сервисы (RDS, ElastiCache, managed Kafka) при смене провайдера становятся самоуправляемыми или другими managed-аналогами. Это не техническая задача — это архитектурное решение с анализом feature parity.
Почему rollback plan обязателен?
Любая миграция без плана отката — авантюра. Rollback plan пишем до начала работ, не в процессе. Минимальный rollback plan:
- Условия отката: что именно должно сломаться, чтобы откатываться
- Точка невозврата: после каких действий откат невозможен или стоит дороже, чем решить проблему
- Конкретные команды для переключения обратно на старый сервер
- Ответственный за принятие решения об откате
- Временной лимит: если через X часов проблема не решена — откат автоматически
Пример чек-листа для cut-over
- [ ] Полный backup данных (дамп БД + файлы) перед началом
- [ ] Проверка репликации:
Seconds_Behind_Master: 0 - [ ] Включение maintenance page
- [ ] Выполнение
FLUSH TABLES WITH READ LOCK - [ ] Снятие позиции бинлога
- [ ] Переключение connection string в приложении
- [ ] Снятие read lock
- [ ] Переключение DNS TTL на 60 секунд (заранее)
- [ ] Проверка функциональности на новом сервере (smoke-test)
- [ ] Отключение старого сервера от сети (не выключение, а изоляция)
- [ ] Наблюдение в течение 24 часов
Типичные сроки
| Тип миграции | Масштаб | Сроки |
|---|---|---|
| Lift-and-shift, 1-3 сервиса | Малый (< 50 GB данных) | 2-3 недели |
| Re-platform, смена СУБД | Средний (50-500 GB) | 4-8 недель |
| Полная инфраструктура с Kubernetes | Крупный | 2-4 месяца |
| Миграция между облачными провайдерами | Любой | +30-50% к базовому |
Стоимость рассчитывается после аудита текущей инфраструктуры. Ключевые факторы: объём данных, количество зависимостей, допустимое окно простоя и требования к rollback.
Что входит в работу
- Детальный аудит текущей инфраструктуры с документированием всех зависимостей
- Выбор стратегии миграции (lift-and-shift или re-platform) с обоснованием
- Поэтапный перенос данных с верификацией целостности
- Конфигурация managed-сервисов (СУБД, Redis, Object Storage, CDN)
- Обновление connection strings, env-файлов и CI/CD пайплайнов
- Разработка и тестирование rollback plan
- Мониторинг после cut-over в течение 48 часов
- Документация новой инфраструктуры (диаграммы, runbook)
- Обучение команды заказчика работе с облачными сервисами
Наш опыт и гарантии
Над миграциями работают инженеры с сертификатами AWS Solutions Architect, CKA и Terraform Associate. Средний опыт в облачной инфраструктуре — 7+ лет. За последние 5 лет провели более 60 успешных переносов, включая проекты с отказоустойчивостью 99.99%. Гарантируем:
- Целостность данных на каждом этапе (проверка хэшей, контрольные суммы)
- Время простоя не более согласованного окна (обычно 15–30 минут)
- Полную поддержку в течение 2 недель после завершения миграции
Оценим ваш проект — пришлите описание текущей инфраструктуры, и мы предложим стратегию с примерными сроками.
Закажите аудит текущей инфраструктуры — выявим все скрытые зависимости и подготовим детальный план облачного переезда. Получите консультацию по выбору провайдера и стратегии.







