В этой главе мы снизим внутренние трения, связанные с развертыванием в производство, чтобы оно могло выполняться часто и легко, как разработчиками, так и отделом эксплуатации. Мы можем сделать это за счет расширения конвейера развертывания.
Вместо простой непрерывной интеграции кода в среде, близкой к производственной, обеспечим продвижение в производство любой сборки, проходящей автоматизированные тесты и процессы валидации или по запросу (например, нажатием на кнопку), или автоматически (например, любая сборка, которая проходит все тесты, развертывается автоматически).
Поскольку в данной главе описано значительное количество методик, то, чтобы не прерывать представления концепций, будут использоваться обширные сноски, многочисленные примеры и дополнительная информация.
Достижение таких же результатов, как в компании Facebook, требует наличия автоматизированного механизма, развертывающего код в производственную среду. Если процесс развертывания существует много лет, то особенно необходимо в полной мере документировать все его этапы, например в картах процесса создания продукта. Их мы можем собрать в ходе рабочих совещаний или постепенно пополняя документацию (например, в форме wiki).
После того как мы задокументировали процесс, наша цель — упростить и автоматизировать как можно больше выполняемых вручную шагов, а именно:
• упаковка кода подходящим для развертывания образом;
• создание предварительно настроенных образов виртуальных машин или контейнеров;
• автоматизация развертывания и настройки конфигурации промежуточного ПО;
• копирование пакетов или файлов на производственные серверы;
• перезапуск серверов, приложений или служб;
• создание файлов конфигурации из шаблонов;
• запуск автоматизированных smoke-тестов, чтобы убедиться, что система работает и правильно настроена;
• запуск процедур тестирования;
• сценарии и автоматизация миграции базы данных.
Где это возможно, будем перерабатывать архитектуру с целью удаления некоторых шагов, в частности требующих длительного времени. Желая уменьшить опасность ошибок и потери знаний, мы также хотели бы сократить не только сроки выполнения, но и в максимально возможной степени — количество случаев, когда работа передается от одного отдела другому.
Если разработчики сосредоточатся на автоматизации и оптимизации процесса развертывания, это может привести к существенным улучшениям потока развертывания, таким как отсутствие необходимости новых развертываний или создание новых сред при небольших изменениях конфигурации приложений.
Однако для этого необходимо, чтобы разработчики действовали в тесном контакте с отделом эксплуатации для обеспечения того, чтобы все инструменты и процессы, созданные нами, могли использоваться в ходе процесса и чтобы отдел эксплуатации не отчуждался от общего процесса и не надо было заново изобретать колесо.
Многие инструменты, обеспечивающие непрерывную интеграцию и тестирование, также поддерживают возможность расширить конвейер развертывания, так что проверенные сборки могут быть введены в производство, обычно после приемочных испытаний (например, Jenkins Build Pipeline plugin, ThoughtWorks Go.cd and Snap CI, Microsoft Visual Studio Team Services и Pivotal Concourse).
Среди требований к нашему конвейеру развертывания следующие:
• развертывание одинаковым образом в любой среде: с помощью одного и того же механизма развертывания для всех сред (например, разработки, тестирования и производственной) наше развертывание в производство может быть гораздо более успешным, поскольку мы знаем, что оно уже было успешно выполнено не один раз в начале конвейера;
• smoke-тестирование наших развертываний: в ходе процесса развертывания мы должны протестировать, что можем подключаться к любой системе поддержки (например, базам данных, шинам сообщений, внешним сервисам), и запустить одну тестовую транзакцию через систему, чтобы убедиться, что наша система работает так, как задумано. Если любой из этих тестов не пройден, то мы должны остановить развертывание;
• поддержание согласованных сред: на предыдущих шагах мы создали процесс сборки среды за один шаг, с тем чтобы среды разработки, тестирования и производственные имели общий механизм их создания. Мы должны постоянно обеспечивать синхронизированность сред.
Конечно, в случае возникновения каких-либо проблем в ходе развертывания мы потянем шнур-андон и дружно набросимся на проблему, пока она не будет решена. Так же мы поступаем, если конвейер развертывания сбоит на любом из предыдущих шагов.