Вступление

В этой статье я хочу рассказать историю о переходе на новое окружение – большой задаче, которую пришлось решать, будучи в роли Tech lead команды в одном из продуктов МТС. Статья может быть полезна как «новичкам»-руководителям, которые не знают, как подойти к решению больших и многоэтапных задач, так и просто сочувствующим.

Предыстория

Я был бэкенд разработчиком и после ухода предыдущего технического лидера, меня назначили его преемником. Фактически, роль была похожа на швейцарский нож: CTO, технический лидер, team lead команды бекенда и project manager. И одним из первых «испытаний» которое предстояло решить с командой в очень короткий промежуток времени — это переход на новое окружение. Прежде чем рассказать, о чём именно идет речь, начну с небольшой предыстории.

Изначально наша команда занималась продуктом А, но в какой-то момент продукт был поглощён крупной командой, которая должна была переписать его на свой лад, а затем – закрыть. Примерные сроки всего мероприятия составляли 12 месяцев.

Нас же перевели на новый продукт – продукт Б, и, поскольку его нужно было быстро разработать и запустить, а юридически и технически (на тот момент) мы оставались командой, занимающейся продуктом А, было принято решение разворачивать продукт Б на тех же ресурсах, с теми же учетными записями, токенами и сертификатами, что и продукт А.

Схема работы продуктов
Схема работы продуктов

И вот тут начинается история.

Определение проблемы и поиск решения

Первый вопрос, который мне задали наши DevOps инженеры утром следующего дня после назначения: «нужно что-то делать».

Слайд с нашей встречи
Слайд с нашей встречи

Действительно, до конца дедлайна оставалось два месяца, а понимания того, что нужно делать, – не было. Для начала мы решили сформулировать проблему, оценить её критичность и понять, как её можно решить.

Как можно понять из предыстории, у нас была следующая ситуация: два несвязанных с точки зрения бизнеса продукта, работающих на одних и тех же серверах, использующих одни и те же микросервисы и учетные записи. При этом юридически — это разные продукты, с разными бюджетами, доступами и уровнями критичности. Так же присутствовал риск, что ресурсы продукта Б заберут несмотря на то, что там работает продукт А.

Отсюда напрашивалось очевидное решение – переезд на собственные ресурсы, за которые мы платим, обслуживаем и отвечаем. Другими словами, переход на новое окружение.

Что включает в себя переход на новое окружение

На одной из встреч совместно с DevOps инженерами был составлен первый вариант плана перехода. Я решил, что лучший способ понять, что нам нужно, – представить, что мы прямо сейчас совершаем переход. То есть исходить из того, что у нас есть два окружения, и мы начинаем переносить весь продукт на новые ресурсы.

При составлении плана учитывали каждое действие, например, сборка и доставка кода на стенд, миграция данных, проверка интеграции с внешними системами, тестирование, запуск нового продуктового стенда. Так же мы опирались на следующие требования:

  • Развертывание нового стенда должно быть параллельным старому, чтобы была возможность прекратить переход и вернуться к старому окружению;

  • Определить все точки входа для изменения данных;

  • Срок переноса продуктового стенда – не более 8 часов;

  • Код в репозитории продукта А и продукта Б должен быть одинаковый на момент перехода, то есть вся конфигурация должна происходить через Vault.

В результате был составлен длинный список шагов и список вопросов, на которые предстояло найти ответы.

Концептуально план перехода выглядел так:

  1. Ставим заглушки на сайт, останавливаем микросервисы, которые могут изменить сущности в базе данных на старом окружении;

  2. Мигрируем код, Vault, базу данных;

  3. Переключаем тумблер работы с базой данных на новом окружении;

  4. Раскатываем микросервисы на новое окружение;

  5. Тестируем новое окружение;

  6. Запускаем все микросервисы, которые могут изменять сущности базы данных на новом окружении;

  7. Снимаем заглушку с сайта.

Резюмируя полученные данные, можно разделить переход на новое окружение на три основных этапа:

  • миграция в MTC Ocean;

  • отделение продукта Б от продукта А;

  • переход с Microsoft SQL Server на PostgreSQL (далее расскажу зачем).

Следующим шагом, мы начали декомпозировать каждый этап.

Миграция в MTC Ocean

Главная цель перехода – перенос работы продукта на новые ресурсы. Учитывая бюджет и оперативность получения ресурсов, а так же такие параметры как соответствие по безопасности, SLA, инструментарий и патриотизм, наш выбор пал на MTC Ocean – собственное облачное решение, что-то вроде Yandex.Cloud.

В самом переносе продукта на другие сервера было несколько основных проблем:

  1. На старом окружении продукт работал на Windows VM, что тянуло за собой IIS и прочие специфические вещи, влияющие на миграцию, тогда как на новом ожидалась работа на Linux серверах.

  2. Настройка Microsoft SQL Server (старше 2017) на Linux серверах (а также в условиях урезанных лицензий) оказалась проблематичной задачей. Поэтому появилась потребность в миграции на PostgreSQL.

  3. Старое окружение нельзя было изменять, поэтому на новом требовалось всё заводить заново: AD-группы, политики доступа, инфраструктурные сервисы и технических пользователей.

  4. Специфика работы некоторого функционала, например, работа с .pfx сертификатами, нуждалась в доработке, так как на VM создавалась общая папка со всеми сертификатами, куда могли обращаться микросервисы. На Linux так делать было нельзя.

В основном, этап включал инфраструктурные задачи, которыми занимались DevOps инженеры: заявки на выделение ресурсов, конфигурация серверов, написание нового CI/CD и разворачивание различных инфраструктурных сервисов (Vault, Prometheus, OpenSearch, ArgoCD).

Результатом этапа стало новое окружение, поднятое на более мощных серверах с максимально приближенным к Infrastructure as a Code подходу, чего не было на старом окружении.

Отделение продукта А от продукта Б

Следующий этап – отделение продукта А от продукта Б. Проблема заключалась в том, что при использовании общих сертификатов и аккаунтов, а также общих методов и микросервисов, перенести продукт Б на другие ресурсы без влияния на продукт А было невозможно. Например, некоторые микросервисы работали с callback’ами, которые регистрировались во внешних системах и привязывались к аккаунту, другие аккаунты были привязаны к кошелькам с деньгами, откуда списывались средства за различные услуги. Также имелись общие jobs в планировщике задач и общее подключение к коммунальной Kafka.

Общие аккаунты так же присутствовали во многих критических частях продукта, например, в микросервисах для оплаты или для SMS-рассылки. Это создавало определённые риски, включая финансовые.

Поэтому в рамках этапа было выполнено ряд задач, связанных с отделением функционала, так же была оформлена документация об общих «участках» продуктов А и Б, где были четко описаны пересечения до и после реализации этапа, что позволило гарантировать, что в случае перехода, микросервисы не будут влиять друг на друга.

Переход с Microsoft SQL Server на PostgreSQL

Последний этап подготовки к переезду – это настройка PostgreSQL. Почему мы выбрали именно его – это внутреннее решение, исходя из потенциальных потребностей. Изначально планировалось, что мы самостоятельно поднимем свой PostgreSQL: настроим бэкапы, доступы и балансировку. Однако, оценив объём работы, было предложено воспользоваться Managed PostgreSQL в MTC Ocean, тем самым передав всю поддержку базы данных команде МТС, а самим сосредоточиться на миграции данных. Это решение оказалось правильным, хотя из-за специфики работы ролей и пользователей базы данных пришлось решать дополнительные задачи.

После того, как вопрос с развертыванием PostgreSQL был решён, осталось еще два:

  1. Как мигрировать данные и проверять их целостность;

  2. Убедиться, что микросервисы работают с PostgreSQL так же, как с Microsoft SQL Server.

Что касается миграции, после исследования объёма данных и отсечения баз данных и таблиц, принадлежащих продукту Б, объём оказался сравнительно небольшим – порядка <400 ГБ, поэтому, перенос осуществлялся с помощью скриптов, без привлечения сторонних провайдеров и библиотек.

Однако поддержка PostgreSQL синтаксиса во всех микросервисах стала проблемой. В нашем проекте использовалась мини-ORM Dapper, работающая с SQL скриптами. Синтаксис Microsoft SQL Server и PostgreSQL отличается, что потребовало большого объема доработок со стороны разработчиков. Универсального решения, которое можно было бы применить сразу на все микросервисы не нашлось, поэтому для каждого микросервиса были выполнены доработки связанные работой с обеими базами данных, а также добавлена возможность использования флага, переключающего репозитории в зависимости от окружения. Эта задача оказалась самой объёмной, заняв около месяца.

Из упущений этапа – это отсутствие валидации данных по итогам миграции, но в остальном процесс прошел гладко.

Интеграции

Отдельно хочу рассказать про интеграции. Наш продукт взаимодействовал с большим количеством внешних систем – порядка 14 интеграций, треть из которых инициировала запросы к нам, а не наоборот.

Чтобы определить, что нам нужно предусмотреть в плане интеграций, аналитики подготовили документацию со списком всех внешних систем, который включал в себя: контакты представителей, способы взаимодействия, бизнес-кейсы, авторизационные данные, IP-адреса.

После этого мы связались со всеми внешними системами, оповестили их о предстоящих работах и уточнили потенциальные проблемы при взаимодействии с новым окружением. Для нескольких систем завели новые учетные записи, перевыпустили токены и сертификаты, что позволило безболезненно реинтегрироваться с критически важными системами.

Из особенностей, которые стоило бы учесть в большой компании – наличие внутреннего firewall, где для доступа к любому ресурсу требовалось заказывать разрешения. Для некоторых IP-адресов заявки были заведены с задержкой, что стало отдельной проблемой.

Организационные моменты

Поскольку в процессе перехода участвовала вся команда, требовалась чёткая координация. Для этого были разработаны инструкции по различным процессам, связанным с переходом. Например, детально расписаны шаги перехода: кто, что и когда должен делать от начала до конца. Также были составлены инструкции по откату – действиям на случай возникновения проблем. Определена «точка невозврата», после которой откат становился невозможен. Были составлены таблицы уровней доступа к ресурсам, ссылки на сами ресурсы и инструкция для отключения старого окружения. Настроены корпоративные доступы и написаны инструкции по работе с новыми инструментами.  

Был подготовлен план тестирования для каждого стенда: на dev-окружении тестировался весь бизнес-функционал, на preprod – только интеграционные сценарии.

С командой были согласованы сроки перехода с учётом отпусков, проводились регулярные обсуждения для сбора вопросов и предложений, а также проводилась консультация команды эксплуатации.

Опыт нашего перехода

Переход прошёл успешно. В связи с недостаточным тестированием сетевых доступов, связанных с интеграциями, мы сдвинулись по срокам, но существенных ошибок получено не было.

Но что бы я сделал иначе, будь у меня этот опыт:

  1. Интеграции. Нужно было уделить больше внимания интеграциям. Нужно было убедиться, что доступ до каждого адреса был получен, перепроверить все IP-адреса и тщательно разобраться в особенностях их работы (в частности, с легаси типа WCF).

  2. Валидация данных при миграции. Хоть проблем с этим и не возникло, но после того, как мы мигрировали данные, проверка валидации была ручным и хаотичным. Стоило об этом задуматься заранее и предусмотреть механизм валидации и целостности данных.

  3. Корпоративные трудности. Работа с внутренними ресурсами, специалистами информационной безопасности, поддержкой МТС Ocean, с корпоративным firewall и WAF требовало много времени. Это нужно учитывать в планировании, что было сделано в недостаточном объеме.

  4. Поэтапный переход. Выполнять сразу три этапа одновременно было ошибкой. Поэтапный подход позволил бы минимизировать ошибки, но из-за сжатых сроков такой вариант был невозможен.

Советы и рекомендации

  • Декомпозиция: если есть возможность разбить большую задачу на части – сделайте это;

  • Пишите инструкции: на каждом этапе должно быть понятно, что и кому делать. Это позволит полностью видеть процесс и вносить в него корректировки до того, как дойдет до дела;

  • Имейте план Б: описывайте инструкцию по откату изменений, определите точку невозврата и что делать, если всё пошло не так, как планировали;

  • Организуйте коммуникацию внутри команды: регулярные встречи, обсуждения сроков и распределение ролей помогут поддерживать прозрачность перехода и избежать недопонимания;

  • Убедитесь в целостности и консистенции данных: при миграции данных требуется быть уверенным в том, что данные не изменятся в момент миграции, поэтому убедитесь, что ни пользователь, ни очередь, ни планировщик задач, ни внешняя система не изменит сущность. Используйте заглушки для пользователей и флаги в конфигах для отключения функционала. Так же валидируйте данные при миграции, чтобы быть уверенным в том, что ничего не потеряли;

  • Тестирование: структурируйте бизнес-кейсы, определите важные, пользовательские, критичные и не критичные. При больших изменениях в коде имейте отдельный «план тестирования», по которому можно отслеживать статус тестирования;

  • Интеграции: имейте полное понимание с кем и как вы интегрируетесь. Зафиксируйте все необходимые данные в документации, будьте на связи с представителями внешних систем;

  • Уделяйте внимание документированию и ведению задач: ведите подробную документацию по всем процессам, включая список ресурсов, инструкции, бизнес-кейсы и планы отката, заводите задачи на каждое действие, отслеживайте их статус;

  • Учитывайте корпоративные процессы и ограничения: заранее планируйте дополнительные временные затраты на согласования, заявки на firewall, отпуска, болезни и другие внутренние процессы команды и компании;

  • Релизы: учитывайте тот факт, что пока идет подготовка к крупным инфраструктурным задачам, развитие продукта не стоит на месте, поэтому команда может переключаться на продуктовые задачи, что может увеличить сроки.

Заключение

В заключении хочу сказать, что это был очень интересный опыт, который позволил с другой стороны посмотреть на работу продукта и на работу команды в целом. Технические детали были опущены в связи со спецификой доменной области, а так же с тем, что я хотел сделать упор на организационный аспект решения задачи.

Команде – спасибо!

Комментарии (1)


  1. allivut
    27.01.2025 05:08

    Баллада об упущениях менеджера, и костылях. Вызовы конечно интересные но зачем?