Статьи

Как Docker упрощает развертывание производства

Больше всего на свете основное внимание современной разработки часто основано на трех основных концепциях:

  • эффективность
  • надежность
  • стабильность

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

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

Для меня Docker — это технология; особенно если вы заинтересованы в предсказуемом рационализации развертываний от разработки в различных средах тестирования и анализа до производства.

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

1 — поддерживает упакованные приложения

Когда я впервые пришел в Докер несколько месяцев назад, это было то, что поразило меня больше всего. Основная идея Docker заключается в том, что он позволяет вам контейнировать приложение. Или это позволяет вам упаковать ваше приложение и развернуть его.

Это предположение работает лучше всего, когда ваше приложение представляет собой один двоичный файл, например, программное обеспечение, написанное на Go, или файл JAR Java. Но он может одинаково хорошо работать для приложений, использующих динамические языки, такие как PHP, Python и Ruby.

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

Чтобы проиллюстрировать, что я имею в виду, взгляните на следующее изображение. Он представляет собой базовое PHP-приложение (с которым я больше всего знаком), которое содержит три компонента:

  • Среда выполнения PHP, которая включает в себя код приложения
  • Веб-сервер (NGINX, Apache, Lighttpd и т. Д.)
  • Источник данных (MariaDb, PostgreSQL, SQLite и т. Д.)

многоуровневая-архитектура-схема,

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

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

Чтобы поместить это в надлежащий контекст, возьмите упрощенный Dockerfile ниже. Это упакует гипотетическое PHP-приложение, над которым я работал, в специальный контейнер Docker:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
FROM php:7.0-fpm
EXPOSE 9000
 
RUN mkdir -p /var/www/html
COPY . /var/www/html
WORKDIR /var/www/html
 
RUN docker-php-ext-install pdo_mysql \
    && docker-php-ext-install json
 
RUN apt-get update \
    && apt-get --yes --force-yes install git \
    && apt-get --yes --force-yes install zip \
    && apt-get --yes --force-yes install unzip
 
RUN ./composer.phar install

Прорабатывая его сверху донизу, мы видим, что он начинается с создания контейнера на официальном образе Docker PHP 7 FPM , так как для кодовой базы требуется минимальная версия PHP 7.0.

Затем внутри контейнера он создает корневой каталог проекта, копирует туда код и устанавливает его в качестве рабочего каталога.

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

После этого он использует менеджер пакетов PHP Composer для включения сторонних библиотечных зависимостей, в которых нуждается кодовая база; зависимости, определенные в файле конфигурации пакета приложения composer.json .

Была ли это первая, десятая, сотая или даже миллионная сборка, шаги для сборки контейнера одинаковы. Более того, они очень четкие и очень точные. У них также есть бонус быть кратким; что-то, что я не могу сказать для других подходов.

Этот подход устраняет огромную изменчивость из уравнения. Время выполнения PHP, независимо от того, используется ли оно в разработке (или в любой другой среде), будет одинаковым. Он будет основан на той же версии PHP, будет иметь те же расширения (в тех же основных, второстепенных и точечных выпусках) и будет иметь все остальные необходимые ему двоичные файлы в тех же версиях.

Как я недавно утверждал здесь, в блоге Codeship, это значительно снижает технический риск , а также повышает уверенность в качестве продукта.

Ленивые аргументы, такие как «это работает на моем компьютере», практически невозможны. Как может сбой сборки из-за различий между средами, когда различий не должно быть?

Здесь я передам слово своему другу и одному из постоянных экспертов Docker в сообществе PHP Крису Танкерсли , когда он скажет:

Поскольку каждая сборка объединена в образ [контейнер], вы уверены, что каждый раз, когда сборка отправляется на сервер, она является точной и полной.

И вот что должен сказать другой, Дэвид Маккей из Докера Глазго :

Поскольку вы создали артефакт, у вас есть уверенность в том, что то же самое, с чем вы выполняли свои тесты, — это то, что вы используете.

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

! Новый призыв к действию

2 — Поддерживает «Построить один раз, развернуть много раз» в нескольких местах

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

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

Этапы сборки могут меняться со временем; они могут стать более изощренными, они не могут. Но, учитывая ясность инструкций по сборке, их невероятно легко повторить, что делает их чрезвычайно предсказуемыми и надежными.

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

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

Хотите использовать локальный контейнер Redis при разработке (или кеш на основе файловой системы, если вы так склонны), но в работе вы хотите использовать удаленный сервис, такой как Redis Cloud ? Не проблема. В соответствующих средах измените переменные среды и просмотрите приложение, чтобы использовать различные настройки службы.

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

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

Подумайте об упрощении, которое представляет.

Как говорит другой эксперт Докер, Крис Фидао :

Это выполняет обещание, которое обещали нам виртуальные машины, но не смогли обеспечить

3 — Поддерживает легкий откат

В то время как основное внимание при развертывании уделяется развертыванию следующего выпуска, все может пойти не так. Это на самом деле нормально — время от времени.

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

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

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

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

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

Как я уже сказал, у меня нет конкретной реализации, на которую можно указать. Но, в дополнение к настройке существующего конвейера CI, не потребовалось бы много усилий, чтобы сделать это доступным.

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

Вывод

Есть три веских причины, по которым я считаю, что Docker оптимизирует производственные развертывания:

  1. Он поддерживает упакованные приложения.
  2. Он поддерживает «построить один раз, развернуть много раз» в нескольких местах.
  3. Он поддерживает легкий откат.

Используя Docker, инструмент, который позволяет вам контейнировать ваше приложение, вы можете упростить развертывание вашего приложения во всех средах — от разработки до производства.

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