Какие ассоциации у вас возникают со словом «контейнер»? Пластиковый контейнер для еды? Картонная пачка молока? Стальной бокс на борту грузового судна, плывущего по теплым водам Атлантики?

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

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

package.json в приложении на React

Зависимости

В контейнерах содержатся зависимости приложения. Но что такое зависимости и зачем их объединять с приложением? Оказывается, даже совсем неопытные разработчики имеют опыт взаимодействия с зависимостями.

В каждом проекте Node имеется файл package.json, а в каждом приложении на Ruby  —  файл gem. Для запуска приложений и тот и другой должны быть установлены на локальных компьютерах.

В файле package.json приводятся необходимые для проекта пакеты (и их версии). Самые распространенные зависимости: React Router DOM, библиотека тестов, пользовательский интерфейс (материальный или семантический), скрипт запуска (проверка порта для запуска на нем локального хоста).

В файле gem находится

‘jwt’ gem

или

‘bcrypt’ gem

использующиеся для шифрования паролей пользователей. Зависимости устанавливаются в виде npm-пакета с помощью команды:

<npm install>

непосредственно в командной строке или вручную посредством внесения в файл package.json названия зависимости и ее версии. Зависимости неразрывно связаны с запускаемыми приложением процессами.

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

<npm run build>

для создания папки сборки, из которой службы развертывания считывают данные при запуске приложения. Эта папка сборки аналогична «образу» контейнера.

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

Жизненный цикл контейнера

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

Откуда берутся контейнеры?

Иллюстрация Annie Bishai

Так же как и класс, образ служит моделью для создания экземпляров контейнера.

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

Образ берет свое начало в файле dockerfile  —  среде, представленной в тексте. Каждая строка этого файла представляет собой слой кеширования образа. dockerfile запускается, настраивая образ, который инстанцирует новые экземпляры контейнеров.

Преимущества контейнеров

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

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

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

Легкие, портативные, эффективные и совместимые на разных операционных системах  —  и неудивительно, почему контейнеры используют все больше. Эффективные технологии, которые помогают делиться ресурсами, сейчас как никогда важны. Будущее за тем, что будет гибким и динамичным. В двадцатом веке человечество тяготело к пластику. Однако массовое производство пластика имело разрушительные последствия для окружающей среды. Какое будущее ждет нас с этими виртуальными контейнерами? Надеюсь, их эффективность станет путеводной звездой для виртуального прогресса.

Читайте также:

Читайте нас в TelegramVK и Яндекс.Дзен


Перевод статьи Nicholas Thomson: Can’t Contain Containerization

Предыдущая статьяКак создать самообновляющийся заголовок Twitter с динамическим контентом
Следующая статьяReact Single Page Application и React-Router для начинающих