Докеры, контейнеры и прочие микросервисы. Как DevOps меняет жизненный цикл ПО

ContainersАйтишники довольно сильно разобщены. Разработчики информационных систем, системные администраторы, эксперты по большим и маленьким данным, специалисты, отвечающие за ИТ-процессы и пр. глубоко копают, но каждый в своем направлении. И в каждом из этих направлений регулярно происходят те или иные революционные изменения. Например, в заметке об Open Digital API я немного затронул тему микросервисов. Вроде бы хорошая идея. Но поинтересуйтесь у разработчика, в чем заключается конкретная польза такого подхода, и в ответ вы услышите набор общих фраз. Или другой пример – PaaS. На вопрос, чем частное облако отличается от виртуализации, следует примерно такой ответ: в частном облаке вы выделяете себе виртуальную машину самостоятельно, без участия администратора, а простая виртуализация – это когда вас пару месяцев мурыжат заявками и согласованиями (подробнее см. Призрак Digital на пороге вашего офиса). В принципе, данный ответ верен. Но зачем пользователям самостоятельно создавать себе виртуальные машины? Ответ понятен если вы хостинг-провайдер, но зачем это нужно в обычной корпоративной среде? Для того, чтоб найти ответы надо собрать все вместе и PaaS и microservices и жизненные циклы разработки и эксплуатации программного обеспечения. По отдельности оно не работает

На днях мне пришлось столкнуться с проектом Docker. Вроде бы ничего необычного, ну оформляем код в контейнерах, ну развертываем их чуть более эффективно, чем раньше. Подробнее о решении написано здесь Microservices, Docker and Containers, an Overview, но вопрос тот же самый – зачем это все.   У проекта красивая метафора (см. рисунок), но дело конечно не в ней. Даже не в этом конкретном проекте. Просто метафора Docker-а позволяет легко понять, как меняется жизненный цикл разработки и развертывания ПО.

standard_container

Еще задолго до появления Rational Unified Process(и уж тем более задолго до появления гибких методологий) самым сложным релизом системы считался первый.  Не помню точно кому принадлежит крылатая фраза о том, что невозможно запустить сложную систему. Такую систему можно «вырастить» из простой работающей системы. Все разработчики в это верят. Надо запустить что-нибудь, показать заказчику и затем итерационно и инкрементально наращивать функционал. Мол так снижаются риски и пр. Но давайте от книжек и конференций вернемся в реальность. У релиза с номером 1 есть некоторые преимущества, причем более существенные, чем пока еще не очень рассерженный заказчик. Во-первых, у вас нет исторических данных – операций, пользователей, кривых настроек и пр. Во-вторых, не надо заботиться об обратной совместимости.  (Я не беру в расчет проект, задача которого поменять старую систему на новую, сохранив имеющийся функционал. Эта ситуация находится за гранью добра и зла). И, пожалуй, самое главное, вы можете развертываться на продуктиве. Ну есть(была) в организациях такая традиция. Для нового проекта было принято покупать новые сервера. Порой эти новенькие блестящие, пахнущие свежей краской, железячки сначала отдают программистам, чтоб они использовали их в качестве среды разработки. Те на них все поставят, настроят, отладят и потом позовут тестировщиков. Ну, на чем же еще производить нагрузочное тестирование, как не на серверах, которые пойдут в продуктив. Не проект, а идиллия. Но все хорошее рано или поздно заканчивается. Сначала придут безопасники и все на этих серверах обезопасят. Затем сервера с развернутой системой отдадут администраторам и корабль двинется в открытое море. Наутро все участники процесса вдруг резко сообразят, что у них нет ни тестовой ни разработческой среды. Администраторы, естественно, никого на продуктив не пустят, а разрыв в отношениях между Dev-ами и Ops-ами начнет стремительно нарастать. Еще вчера до корабля можно было дотянуться рукой, а сегодня он превратился в крошечную точку на горизонте. В общем дальше начинается хорошо знакомый всем корпоративным айтишникам процесс создания и синхронизации сред. Почему система прошедшая тестирование не работает на продуктиве? Ответ: среды не совпадают. Можно ли получить копию реальных данных с работающей системы? Нет, нельзя! Это секретная информация. А хотя бы настройки? Тем более нельзя. Одним словом разработка следующего релиза представляет собой стрельбу по невидимой мишени с завязанными глазами. Есть счастливое исключение. Это релиз типа appendix. Иногда вас просят разработать отдельный компонент, который слабо связан с другими модулями системы. Более того, иногда под такой компонент выделяют отдельное железо. Но это счастливое исключение.

Вспоминаем о контейнерах. В PaaS парадигме код не переезжает из одной среды в следующую. Релиз начинается с того, что вы получаете контейнер, который впоследствии станет кусочком продуктива. В этом контейнере уже установлено прикладное ПО: СУБД, фреймвоки, конфигурации, модули программной платформы и прочие нужные вещи(картриджи). Именно вместе с этими версиями 3d party software контейнер поедет в тестирование, а затем и в эксплуатацию. С теми самыми, которые уже сейчас у вас под рукой. Администратор не будет читать по бумажке руководство по установке и настройке программного обеспечения, держа его в одной руке и нажимая другой рукой кнопки на клавиатуре. Он вообще ничего не будет делать. Ну, может, посмотрит лениво на сообщение о завершении процесса изменения статуса вашего контейнера, да и то вряд ли. Предыдущий релиз вашего компонента никто не будет выключать. Он останется в продуктиве и будет работать еще некоторое время, пока с него полностью не переключат нагрузку на новый модуль. Потенциально в продуктиве могут работать несколько версий одного и того же модуля.

Возможно ли такое в реальной жизни? У всех по-разному. Рассмотрим несколько потенциальных возражений:

  1. У нас продуктив – это большая дорогая железка, а среда разработки представляет собой простенький стенд, собранный на нескольких писюках. Вам не повезло. В реальной жизни и продуктивная и тестовая и разработческая среда представляют собой виртуальные машины. Когда контейнер «переезжает из одной среды в другую ему просто увеличивают объем виртуальных ресурсов.
  2. Нельзя заменить небольшой фрагмент системы, не затронув другие модули. Это зависит от архитектуры. Еще в прошлом веке разработчики любили писать модули, которые читают записи из БД, удовлетворяющие некоторому условию, что-нибудь с ними делают и обновляют статус в базе. Потом их научили очередям сообщений, снабдили брокерами, раскладывающими сообщения по разным очередям и т.д. Теперь их подсадили на микросервисы – виртуальные машины, реализующие один набор API и использующие другой. Внутри такой машины может быть что угодно: свой фреймворк, свои хранилища, данные и пр.
  3. А как же данные? Зависит от того, собираетесь ли вы их читать или писать. Здесь было много разговоров о CQRS и Event Sourcing. Это о том, что не надо в одном методе одновременно читать и изменять данные. Если вам надо читать данные, то потенциально эта функция доступна и разработческой и в тестовой среде. Для обеспечения конфиденциальности, данные могут маскироваться на лету. В крайнем случае, можно создать отдельный контейнер с витриной данных и отдать его вам для разработки и тестирования. Если данные надо писать, то делать это лучше асинхронно, через очередь сообщений. В общем, отправляете сообщения в очередь и отправляете. Все эти паттерны подробно обсуждались еще во времена event-driven architecture. Есть еще пул добрых советов по разделению данных на транзакционные, референсные и мастер данные, использованию Data Integration Hub и т.д.
  1. В наших процедурах предусмотрен другой порядок развертывания. Ну, конечно. Мне всегда было интересно, как в ходе спринта пользователю доставляется работающий функционал. В Scrum ничего об этом не сказано. Выбираем из бэклога пользовательские истории, разрабатываем софт, затем случается магия и в завершении спринта пользователь уже работает с новым функционалом. А если магия не случилась, то возвращаемся к итерационной или водопадной модели, так?

 

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

docker_container

 

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

Докеры, контейнеры и прочие микросервисы. Как DevOps меняет жизненный цикл ПО: 15 комментариев

  1. Скажите, Максим, а “продуктив” — это устоявшийся термин в российском ИТ? Если да, то куда ударение ставить? ПродУктив или ПродуктИв?
    Мы, поскольку находимся в другой языковой среде, используем просто кальку “продАкшн” или просто “прод”, как часть цепи “дев”-“тест”-“прод”.
    Мне кажется, что докер — это один из методов понуждения к компонентной архитектуре, в которой каждый компонент — действительно изолированный компонент.
    В этом смысле жизненный цикл системы дробится на жизненные циклы компонентов, что для сложных систем может быть полезно.

  2. Макс, ты не поверишь! Разработчики по-прежнему пишут программы которые читают и пишут в базу! Да, да,в 21 веке! 🙂

  3. Ссылка на статью “Microservices, Docker and Containers, an Overview” некорректная, обрезалось расширение .html

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *