Айтишники довольно сильно разобщены. Разработчики информационных систем, системные администраторы, эксперты по большим и маленьким данным, специалисты, отвечающие за ИТ-процессы и пр. глубоко копают, но каждый в своем направлении. И в каждом из этих направлений регулярно происходят те или иные революционные изменения. Например, в заметке об Open Digital API я немного затронул тему микросервисов. Вроде бы хорошая идея. Но поинтересуйтесь у разработчика, в чем заключается конкретная польза такого подхода, и в ответ вы услышите набор общих фраз. Или другой пример – PaaS. На вопрос, чем частное облако отличается от виртуализации, следует примерно такой ответ: в частном облаке вы выделяете себе виртуальную машину самостоятельно, без участия администратора, а простая виртуализация – это когда вас пару месяцев мурыжат заявками и согласованиями (подробнее см. Призрак Digital на пороге вашего офиса). В принципе, данный ответ верен. Но зачем пользователям самостоятельно создавать себе виртуальные машины? Ответ понятен если вы хостинг-провайдер, но зачем это нужно в обычной корпоративной среде? Для того, чтоб найти ответы надо собрать все вместе и PaaS и microservices и жизненные циклы разработки и эксплуатации программного обеспечения. По отдельности оно не работает
На днях мне пришлось столкнуться с проектом Docker. Вроде бы ничего необычного, ну оформляем код в контейнерах, ну развертываем их чуть более эффективно, чем раньше. Подробнее о решении написано здесь Microservices, Docker and Containers, an Overview, но вопрос тот же самый – зачем это все. У проекта красивая метафора (см. рисунок), но дело конечно не в ней. Даже не в этом конкретном проекте. Просто метафора Docker-а позволяет легко понять, как меняется жизненный цикл разработки и развертывания ПО.
Еще задолго до появления Rational Unified Process(и уж тем более задолго до появления гибких методологий) самым сложным релизом системы считался первый. Не помню точно кому принадлежит крылатая фраза о том, что невозможно запустить сложную систему. Такую систему можно «вырастить» из простой работающей системы. Все разработчики в это верят. Надо запустить что-нибудь, показать заказчику и затем итерационно и инкрементально наращивать функционал. Мол так снижаются риски и пр. Но давайте от книжек и конференций вернемся в реальность. У релиза с номером 1 есть некоторые преимущества, причем более существенные, чем пока еще не очень рассерженный заказчик. Во-первых, у вас нет исторических данных – операций, пользователей, кривых настроек и пр. Во-вторых, не надо заботиться об обратной совместимости. (Я не беру в расчет проект, задача которого поменять старую систему на новую, сохранив имеющийся функционал. Эта ситуация находится за гранью добра и зла). И, пожалуй, самое главное, вы можете развертываться на продуктиве. Ну есть(была) в организациях такая традиция. Для нового проекта было принято покупать новые сервера. Порой эти новенькие блестящие, пахнущие свежей краской, железячки сначала отдают программистам, чтоб они использовали их в качестве среды разработки. Те на них все поставят, настроят, отладят и потом позовут тестировщиков. Ну, на чем же еще производить нагрузочное тестирование, как не на серверах, которые пойдут в продуктив. Не проект, а идиллия. Но все хорошее рано или поздно заканчивается. Сначала придут безопасники и все на этих серверах обезопасят. Затем сервера с развернутой системой отдадут администраторам и корабль двинется в открытое море. Наутро все участники процесса вдруг резко сообразят, что у них нет ни тестовой ни разработческой среды. Администраторы, естественно, никого на продуктив не пустят, а разрыв в отношениях между Dev-ами и Ops-ами начнет стремительно нарастать. Еще вчера до корабля можно было дотянуться рукой, а сегодня он превратился в крошечную точку на горизонте. В общем дальше начинается хорошо знакомый всем корпоративным айтишникам процесс создания и синхронизации сред. Почему система прошедшая тестирование не работает на продуктиве? Ответ: среды не совпадают. Можно ли получить копию реальных данных с работающей системы? Нет, нельзя! Это секретная информация. А хотя бы настройки? Тем более нельзя. Одним словом разработка следующего релиза представляет собой стрельбу по невидимой мишени с завязанными глазами. Есть счастливое исключение. Это релиз типа appendix. Иногда вас просят разработать отдельный компонент, который слабо связан с другими модулями системы. Более того, иногда под такой компонент выделяют отдельное железо. Но это счастливое исключение.
Вспоминаем о контейнерах. В PaaS парадигме код не переезжает из одной среды в следующую. Релиз начинается с того, что вы получаете контейнер, который впоследствии станет кусочком продуктива. В этом контейнере уже установлено прикладное ПО: СУБД, фреймвоки, конфигурации, модули программной платформы и прочие нужные вещи(картриджи). Именно вместе с этими версиями 3d party software контейнер поедет в тестирование, а затем и в эксплуатацию. С теми самыми, которые уже сейчас у вас под рукой. Администратор не будет читать по бумажке руководство по установке и настройке программного обеспечения, держа его в одной руке и нажимая другой рукой кнопки на клавиатуре. Он вообще ничего не будет делать. Ну, может, посмотрит лениво на сообщение о завершении процесса изменения статуса вашего контейнера, да и то вряд ли. Предыдущий релиз вашего компонента никто не будет выключать. Он останется в продуктиве и будет работать еще некоторое время, пока с него полностью не переключат нагрузку на новый модуль. Потенциально в продуктиве могут работать несколько версий одного и того же модуля.
Возможно ли такое в реальной жизни? У всех по-разному. Рассмотрим несколько потенциальных возражений:
- У нас продуктив – это большая дорогая железка, а среда разработки представляет собой простенький стенд, собранный на нескольких писюках. Вам не повезло. В реальной жизни и продуктивная и тестовая и разработческая среда представляют собой виртуальные машины. Когда контейнер «переезжает из одной среды в другую ему просто увеличивают объем виртуальных ресурсов.
- Нельзя заменить небольшой фрагмент системы, не затронув другие модули. Это зависит от архитектуры. Еще в прошлом веке разработчики любили писать модули, которые читают записи из БД, удовлетворяющие некоторому условию, что-нибудь с ними делают и обновляют статус в базе. Потом их научили очередям сообщений, снабдили брокерами, раскладывающими сообщения по разным очередям и т.д. Теперь их подсадили на микросервисы – виртуальные машины, реализующие один набор API и использующие другой. Внутри такой машины может быть что угодно: свой фреймворк, свои хранилища, данные и пр.
- А как же данные? Зависит от того, собираетесь ли вы их читать или писать. Здесь было много разговоров о CQRS и Event Sourcing. Это о том, что не надо в одном методе одновременно читать и изменять данные. Если вам надо читать данные, то потенциально эта функция доступна и разработческой и в тестовой среде. Для обеспечения конфиденциальности, данные могут маскироваться на лету. В крайнем случае, можно создать отдельный контейнер с витриной данных и отдать его вам для разработки и тестирования. Если данные надо писать, то делать это лучше асинхронно, через очередь сообщений. В общем, отправляете сообщения в очередь и отправляете. Все эти паттерны подробно обсуждались еще во времена event-driven architecture. Есть еще пул добрых советов по разделению данных на транзакционные, референсные и мастер данные, использованию Data Integration Hub и т.д.
- В наших процедурах предусмотрен другой порядок развертывания. Ну, конечно. Мне всегда было интересно, как в ходе спринта пользователю доставляется работающий функционал. В Scrum ничего об этом не сказано. Выбираем из бэклога пользовательские истории, разрабатываем софт, затем случается магия и в завершении спринта пользователь уже работает с новым функционалом. А если магия не случилась, то возвращаемся к итерационной или водопадной модели, так?
Конечно, не все так просто. Для старых систем такой жизненный цикл не применим. Да и в новых системах будет огромное количество архитектурных вопросов и компромиссов. Но, как и в истории с контейнерными перевозками (см. мелкий шрифт на предыдущем рисунке), мир уже никогда больше не будет таким как прежде.
Update: Планирую сделать десяток слайдов на эту тему. Если тема показалась интересной, то буду рад приглашению на вебинар или очное выступление.
Максим, не находите, что ваша статья немного разрозненная. Сначала нужно было дать прелюдию в виде Agile и чем она мешает ITIL.
Да. Может быть. Спешил 🙂 Надо бы вебинар сделать на эту тему.
Надеюсь пригласите 🙂
Скажите, Максим, а «продуктив» — это устоявшийся термин в российском ИТ? Если да, то куда ударение ставить? ПродУктив или ПродуктИв?
Мы, поскольку находимся в другой языковой среде, используем просто кальку «продАкшн» или просто «прод», как часть цепи «дев»-«тест»-«прод».
Мне кажется, что докер — это один из методов понуждения к компонентной архитектуре, в которой каждый компонент — действительно изолированный компонент.
В этом смысле жизненный цикл системы дробится на жизненные циклы компонентов, что для сложных систем может быть полезно.
«ПродуктИв», «продакшн», «прод» — все слова используются.
Макс, ты не поверишь! Разработчики по-прежнему пишут программы которые читают и пишут в базу! Да, да,в 21 веке! 🙂
Поверю 🙂
Ссылка на статью «Microservices, Docker and Containers, an Overview» некорректная, обрезалось расширение .html
Спасибо. Подправил