- Docker. Зачем и как
- Проблемы
- Обычные решения
- Установочный скрипт
- Облачные сервисы
- Виртуальные машины
- Подход докера — контейнеризация
- Как работает docker
- Создание образа
- Создание контейнера
- Union filesystem
- Container registry
- Использование контейнеров
- Взаимодействие между контейнерами
- Выводы
- Что такое Docker и как его использовать в разработке
- Что такое Docker
- Преимущества использования Docker
- Компоненты Docker
- Что такое Docker Engine
- Элементы Docker Engine
- Как работает Docker
- Схема работы
- Как работают образы
- Как работают контейнеры
- Что происходит при запуске контейнера
- Docker Compose
- Docker Swarm
- Некоторые возможности утилиты
- Примеры применения
- Заключение
Docker. Зачем и как
Есть множество прекрасных публикаций для тех, кто уже пользуется docker-ом. Есть хорошие статьи для тех, кто хочет этому научиться. Я пишу для тех, кто не только не знает, что такое docker, но и не уверен стоит ли ему это знать.
Я сознательно опускаю некоторые технические подробности, а кое где допускаю упрощения. Если вы увидите, что docker – то, что вам нужно, вы легко найдете более полную и точную информацию в других статьях.
Начну я с описания нескольких типичных проблем.
Проблемы
Первая проблема — как передать продукт клиенту.
Предположим у вас есть серверный проект, который вы закончили и теперь его необходимо передать пользователю. Вы готовите много разных файликов, скриптов и пишите инструкцию по установке. А потом тратите уйму времени на решения проблем клиента вроде: «у меня ничего не работает», «ваш скрипт упал на середине — что теперь делать», «я перепутал порядок шагов в инструкции и теперь не могу идти дальше» и т. п.
Всё усугубляется если продукт тиражируемый и вместо одного клиента у вас сотни или тысячи покупателей. И становится еще сложнее, если вспомнить о необходимости установки новых версий продукта.
Вторая проблема — тиражируемость. Пусть вам нужно поднять 5 (или 50) почти одинаковых серверов. Делать это вручную долго, дорого и подвержено ошибкам.
Наконец, третья проблема — переиспользуемость. Предположим у вас есть отдел, который делает браузерные игры. Предположим, что их у вас уже несколько. И все они используют один и тот же технологический стэк (например — java-tomcat-nginx-postgre). Но при этом, чтобы поставить новую игру вы вынуждены заново подготавливать на новом сервере почти одинаковую конфигурацию. Вы не можете просто так взять и сказать — «хочу сервер, как в игре странники но только с другим веб архивом»
Обычные решения
Как обычно решаются эти проблемы.
Установочный скрипт
Первый подход я уже упомянул — вы можете написать скрипт, который установит всё, что вам нужно и запускать его на всех нужных серверах. ( Скрипт может быть как простым sh файлом, так и чем-то сложным, созданным с использованием специальных инструментов).
Недостатки этого подхода — хрупкость и неустойчивость к ошибкам. Как бы хорошо не был написан скрипт, рано или поздно на какой-то машине он упадёт. И после этого падения машина фактически окажется «испорченной» — просто так «откатить» те действия, которые скрипт успел выполнить, у вашего клиента не получится.
Облачные сервисы
Второй подход — использование облачных сервисов. Вы вручную устанавливаете на виртуальный сервер всё, что вам нужно. Затем делаете его image. И далее клонируете его столько раз, сколько вам надо.
Недостатка здесь два. Во-первых, vendor-lock-in. Вы не можете запускать свое решение вне выбранного облака, что не всегда удобно и может привести к потерям несогласных с этим выбором клиентов. Во-вторых, облака медленны. Виртуальные (и даже «bare-metal») сервера предоставляемые облаками на сегодняшний день сильно уступают по производительности dedicated серверам.
Виртуальные машины
Третий подход — использование виртуальных машин. Здесь тоже есть недостатки:
Размер — не всегда удобно качать образ виртуальной машины, который может быть довольно большим. При этом, любое изменение внутри образа виртуальной машины требует скачать весь образ заново.
Сложное управление совместным использованием серверных ресурсов — не все виртуальные машины вообще поддерживают совместное использование памяти или CPU. Те что поддерживают, требуют тонкой настройки.
Подход докера — контейнеризация
И вот тут появляется docker, в котором
- есть контролируемая среда (как в виртуальных машинах)
- есть эффективное управление серверными ресурсами
- и нет vendor lock-in
Подобно виртуальной машине докер запускает свои процессы в собственной, заранее настроенной операционной системе. Но при этом все процессы докера работают на физическом host сервере деля все процессоры и всю доступную память со всеми другими процессами, запущенными в host системе. Подход, используемый докером находится посередине между запуском всего на физическом сервере и полной виртуализацией, предлагаемой виртуальными машинами. Этот подход называется контейнеризацией.
Как работает docker
Создание образа
Сначала создается docker image (или образ). Он создается при помощи скрипта, который вы для этого пишете.
Образы наследуются и, обычно, для создания своего первого образа мы берём готовый образ и наследуемся от него.
Чаще всего мы берем образ в котором содержится та или иная версия linux. Скрипт тогда начинается как-то так:
Далее при помощи директивы RUN мы можем исполнять любые команды, которые поддерживает этот линукс.
Например RUN apt-get install -y mc установит в наш образ midnight commander.
Кроме этого, мы можем копировать в наш образ любые локальные файлы при помощи директивы COPY.
Докер поддерживает гораздо больше различных директив. Например, директива USER roman говорит докеру что все следующие директивы нужно выполнять из под пользователя roman. А директива ENTRYPOINT [“/opt/tomcat/catalina.sh”] задает исполняемый файл, который будет запускаться при старте.
Я не буду перечислять все остальные директивы — в этом нет смысла. Здесь главное — принцип: вы создаёте вот такой скрипт, называете его Dockerfile и запускаете команду docker build, docker выполняет скрипт и создает image.
Если в процессе возникают какие-то ошибки, докер о них сообщает и вы их исправляете. То есть исправление скрипта происходит на этапе создания image. На этапе установки скрипт уже не используется.
Создание контейнера
Когда у вас уже есть docker image вы можете создать из него контейнер на любом физическом сервере, где установлен докер. Если image – это тиражируемый образ некоторой «машины», то container это уже сама «машина», которую можно запускать и останавливать.
Важный момент — при создании контейнера из image, его можно параметризовать. Вы можете передавать докеру переменные окружения, которые он использует при создании контейнера из image. Так вы сможете создавать немного разные машины из одного образа. Например, передать образу web-сервера его доменное имя.
Хорошей практикой в докере считается «упаковка» в один контейнер ровно одного постоянно работающего серверного процесса. Как я уже упоминал, этот процесс работает на уровне физического сервера и честно регулируется установленной там операционной системой. Поэтому, в отличие от виртуальных машин, контейнеры докера не требуют специального управления памятью и процессорами. Использование ресурсов становится простым и эффективным.
Union filesystem
Ок — память и процессор используется эффективно. А как насчёт файловой системы? Ведь если у каждого контейнера докера своя собственная копия операционной системы, то мы получим ту же проблему, что и с виртуальными машинами — тяжеловесные образы, которые содержат одно и тоже.
На самом деле в докере это не так. Если вы используете 100500 контейнеров, основанных на одном и том же образе операционной системы, то файлы этой системы будут скачаны докером ровно один раз. Это достигается за счёт использования докером union file system.
Union file system состоит из слоёв (layers). Слои как бы наложены друг на друга. Некоторые слои защищены от записи. Например, все наши контейнеры используют общие защищенные от записи слои, в которых находятся неизменяемые файлы операционной системы.
Для изменяемых файлов каждый из контейнеров будет иметь собственный слой. Естественно, докер использует такой подход не только для операционной системы, но и для любых общих частей контейнеров, которые были созданы на основе общих «предков» их образов.
Container registry
Получается, что docker image состоит из слоёв. И хорошо было бы уметь скачивать на наш сервер только те слои, которых на нём пока нет. Иначе для установки 100 контейнеров, основанных на Ubuntu мы скачаем Ubuntu внутри их образов 100 раз. Зачем?
Хорошая новость в том, что докер решает эту проблему. Докер предоставляет специальный сервис, называемый docker registry. Docker registry предназначен для хранения и дистрибуции готовых образов. Собрав новый образ (или новую версию образа) вы можете закачать его в docker registry. Соответственно, потом его можно скачать оттуда на любой сервер. Главная фишка здесь в том, что физически качаться будут только те слои, которые нужны.
Например, если вы создали новую версию образа, в котором поменяли несколько файлов, то в registry будут отправлены только слои, содержащие эти файлы.
Аналогично, если сервер качает из registry какой-то образ, скачаны будут только слои, отсутствующие на сервере.
Docker registry существует и как общедоступный сервис и как open source проект, доступный для скачивания и установки на собственной инфрастуктуре.
Использование контейнеров
Созданные контейнеры можно запускать, останавливать, проверять их статус и т д. При создании контейнера можно дополнительно передать докеру некоторые параметры. Например, попросить докер автоматически рестартовать контейнер, если тот упадёт.
Взаимодействие между контейнерами
Если контейнеров на сервере несколько, управлять ими вручную становится проблематично. Для этого есть технология docker compose. Она существует поверх докера и просто позволяет управлять контейнерами на основе единого конфигурационного файла, в котором описаны контейнеры, их параметры и их взаимосвязи (например контейнер A имеет право соединяться с портом 5432 контейнера B)
Выводы
Таким образом докер очень хорошо подходит для решения перечисленных выше задач:
- удобная передача серверного проекта клиенту
- обеспечение тиражируемости серверов
- обеспечение переиспользуемости ранее созданных серверных конфигураций
Отдельно хочу отметить, что докер также крайне удобен для обновления ранее установленных версий продукта и для создания тестовых серверов, полностью идентичных «натуральным».
Источник
Что такое Docker и как его использовать в разработке
Содержание
Контейнеризация является отличной альтернативой аппаратной виртуализации. Все процессы в ней протекают на уровне операционной системы, что позволяет существенно экономить ресурсы и увеличивать эффективность работы с приложениями.
Одним из наиболее популярных инструментов для программной виртуализации является Docker — автоматизированное средство управления виртуальными контейнерами. Он решает множество задач, связанных с созданием контейнеров, размещением в них приложений, управлением процессами, а также тестированием ПО и его отдельных компонентов.
Что такое Docker и как его следует применять для веб-разработки, описано в этой статье.
Что такое Docker
Docker (Докер) — программное обеспечение с открытым исходным кодом, применяемое для разработки, тестирования, доставки и запуска веб-приложений в средах с поддержкой контейнеризации. Он нужен для более эффективного использование системы и ресурсов, быстрого развертывания готовых программных продуктов, а также для их масштабирования и переноса в другие среды с гарантированным сохранением стабильной работы.
Разработка Docker была начата в 2008 году, а в 2013 году он был опубликован как свободно распространяемое ПО под лицензией Apache 2.0. В качестве тестового приложения Docker был включен в дистрибутив Red Hat Enterprise Linux 6.5. В 2017 году была выпущена коммерческая версия Docker с расширенными возможностями.
Docker работает в Linux, ядро которых поддерживает cgroups, а также изоляцию пространства имен. Для инсталляции и использования на платформах, отличных от Linux, существуют специальные утилиты Kitematic или Docker Machine.
Основной принцип работы Docker — контейнеризация приложений. Этот тип виртуализации позволяет упаковывать программное обеспечение по изолированным средам — контейнерам. Каждый из этих виртуальных блоков содержит все нужные элементы для работы приложения. Это дает возможность одновременного запуска большого количества контейнеров на одном хосте.
Docker-контейнеры работают в разных средах: локальном центре обработки информации, облаке, персональных компьютерах и т. д.
Преимущества использования Docker
- Минимальное потребление ресурсов — контейнеры не виртуализируют всю операционную систему (ОС), а используют ядро хоста и изолируют программу на уровне процесса. Последний потребляет намного меньше ресурсов локального компьютера, чем виртуальная машина.
- Скоростное развертывание — вспомогательные компоненты можно не устанавливать, а использовать уже готовые docker-образы (шаблоны). Например, не имеет смысла постоянно устанавливать и настраивать Linux Ubuntu. Достаточно 1 раз ее инсталлировать, создать образ и постоянно использовать, лишь обновляя версию при необходимости.
- Удобное скрытие процессов — для каждого контейнера можно использовать разные методы обработки данных, скрывая фоновые процессы.
- Работа с небезопасным кодом — технология изоляции контейнеров позволяет запускать любой код без вреда для ОС.
- Простое масштабирование — любой проект можно расширить, внедрив новые контейнеры.
- Удобный запуск — приложение, находящееся внутри контейнера, можно запустить на любом docker-хосте.
- Оптимизация файловой системы — образ состоит из слоев, которые позволяют очень эффективно использовать файловую систему.
Компоненты Docker
Для начинающих разработчиков необходимо знать как работает Docker, его основные компоненты и связь между ними.
- Docker-демон (Docker-daemon) — сервер контейнеров, входящий в состав программных средств Docker. Демон управляет Docker-объектами (сети, хранилища, образы и контейнеры). Демон также может связываться с другими демонами для управления сервисами Docker.
- Docker-клиент (Docker-client / CLI) — интерфейс взаимодействия пользователя с Docker-демоном. Клиент и Демон — важнейшие компоненты «движка» Докера (Docker Engine). Клиент Docker может взаимодействовать с несколькими демонами.
- Docker-образ (Docker-image) — файл, включающий зависимости, сведения, конфигурацию для дальнейшего развертывания и инициализации контейнера.
- Docker-файл (Docker-file) — описание правил по сборке образа, в котором первая строка указывает на базовый образ. Последующие команды выполняют копирование файлов и установку программ для создания определенной среды для разработки.
- Docker-контейнер (Docker-container) — это легкий, автономный исполняемый пакет программного обеспечения, который включает в себя все необходимое для запуска приложения: код, среду выполнения, системные инструменты, системные библиотеки и настройки.
- Том (Volume) — эмуляция файловой системы для осуществления операций чтения и записи. Она создается автоматически с контейнером, поскольку некоторые приложения осуществляют сохранение данных.
- Реестр (Docker-registry) — зарезервированный сервер, используемый для хранения docker-образов. Примеры реестров:
- Центр Docker — реестр, используемый для загрузки docker-image. Он обеспечивает их размещение и интеграцию с GitHub и Bitbucket.
- Контейнеры Azure — предназначен для работы с образами и их компонентами в директории Azure (Azure Active Directory).
- Доверенный реестр Docker или DTR — служба docker-реестра для инсталляции на локальном компьютере или сети компании.
- Docker-хаб (Docker-hub) или хранилище данных — репозиторий, предназначенный для хранения образов с различным программным обеспечением. Наличие готовых элементов влияет на скорость разработки.
- Docker-хост (Docker-host) — машинная среда для запуска контейнеров с программным обеспечением.
- Docker-сети (Docker-networks) — применяются для организации сетевого интерфейса между приложениями, развернутыми в контейнерах.
Что такое Docker Engine
Docker Engine («Движок» Docker) — ядро механизма Докера. «Движок» отвечает за функционирование и обеспечение связи между основными Docker-объектами (реестром, образами и контейнерами).
Элементы Docker Engine
- Сервер выполняет инициализацию демона (фоновой программы), который применяется для управления и модификации контейнеров, образов и томов.
- RESTAPI — механизм, отвечающий за организацию взаимодействия Докер-клиента и Докер-демона.
- Клиент — позволяет пользователю взаимодействовать с сервером при помощи команд, набираемых в интерфейсе (CLI).
Как работает Docker
Работа Docker основана на принципах клиент-серверной архитектуры, которая основана на взаимодействии клиента с веб-сервером (хостом). Первый отправляет запросы на получение данных, а второй их предоставляет.
Схема работы
- Пользователь отдает команду с помощью клиентского интерфейса Docker-демону, развернутому на Docker-хосте. Например, скачать готовый образ из реестра (хранилища Docker-образов) с помощью команды docker pull . Взаимодействие между клиентом и демоном обеспечивает REST API. Демон может использовать публичный (Docker Hub) или частный реестры.
- Исходя из команды, заданной клиентом, демон выполняет различные операции с образами на основе инструкций, прописанных в файле Dockerfile. Например, производит их автоматическую сборку с помощью команды docker build .
- Работа образа в контейнере. Например, запуск docker-image, посредством команды docker run или удаление контейнера через команду docker kill .
Как работают образы
Docker-image — шаблон только для чтения (read-only) с набором некоторых инструкций, предназначенных для создания контейнера. Он состоит из слоев, которые Docker комбинирует в один образ при помощи вспомогательной файловой системы UnionFS. Так решается проблема нерационального использования дисковой памяти. Параметры образа определяются в Docker-file.
Для многократного применения Docker-image следует пользоваться реестром образов или Докер-реестром (Docker-registry), позволяющим закачивать готовые образы с внешнего репозитория сервиса и хранить их в реестре Докер-хоста. Рекомендуемый вариант — официальный реестр компании Docker Trusted Registry (DTR).
Если требуется файл, то скачиваться будут только нужные слои. Например, разработчик решил доработать программное обеспечение и модифицировать образ, изменив несколько файлов. После загрузки на сервер будут отправлены слои, содержащие только модифицированные данные.
Как работают контейнеры
Каждый контейнер строится на основе Docker-образов. Контейнеры запускаются напрямую из ядра операционной системы Linux. Благодаря этому, они потребляют гораздо меньше ресурсов, чем при аппаратной виртуализации.
Изоляция рабочей среды осуществляется при помощи технологии namespace. Для каждого изолированного пространства (контейнера) создается уникальное пространство имен, которое и обеспечивает к нему доступ. Любой процесс, выполняемый внутри контейнера, ограничивается namespace.
В ОС Linux посредством Docker Engine используется немного другая технология — контрольные группы (cgroups). При этом приложение ограничивается некоторым набором ресурсов. Сgroups осуществляют обмен доступных аппаратных ресурсов с контейнерами, на которые дополнительно устанавливаются необходимые ограничения (использование памяти, прав доступа к другому ресурсу и т. д.).
Движок Docker объединяет пространство имен (namespace), контрольные группы (cgroups) и файловую систему (UnionFS) в формат контейнера. В будущем планируется поддержка других форматов посредством интеграции технологий BSD Jails или Solaris Zones.
Что происходит при запуске контейнера
- Происходит запуск образа (Docker-image). Docker Engine проверяет существование образа. Если образ уже существует локально, Docker использует его для нового контейнера. При его отсутствии выполняется скачивание с Docker Hub.
- Создание контейнера из образа.
- Разметка файловой системы и добавление слоя для записи.
- Создание сетевого интерфейса.
- Поиск и присвоение IP-адреса.
- Запуск указанного процесса.
- Захват ввода/вывода приложения.
Docker Compose
Для управления несколькими контейнерами, из которых состоит проект, используют пакетный менеджер — Docker Compose.
Он применяется не во всех случаях. Если проект является простым приложением, не требующим использования сторонних сервисов, то для его развертывания можно ограничиться только Docker. Docker Compose рекомендуется использовать при проектировании сложных программных продуктов, включающих в себя множество процессов и сервисов.
Docker Swarm
При преобразовании хостов в кластер нужно воспользоваться утилитой кластеризации Docker Swarm. Хост, находящийся в его составе, называется «узлом» (node), который бывает управляющим или рабочим. Один кластер содержит только один управляющий «узел».
Некоторые возможности утилиты
- Управление нагрузочными характеристиками — осуществляется оптимизация рассылки запросов между хостами, обеспечивая на них равномерную нагрузку.
- Динамическое управление — допускается добавление элементов в swarm-кластер без дальнейшего его перезапуска.
- Возможность масштабирования — позволяет добавлять или удалять docker-образ для автоматического создания контейнера.
- Восстановление «узла» после сбоя — работоспособность каждого хоста постоянно контролируется управляющим «узлом». При сбое кластера происходит его восстановление и перезапуск.
- Rolling-update — выполняет обновление контейнеров. Процедура может выполняться в определенной последовательности и с временной задержкой для запуска другого контейнера. Параметр указывается в настройках. Если произойдет сбой обновления, то Docker Swarm выдаст ошибку и процесс повторится заново.
Примеры применения
Окружение для разработки Docker применяется во множестве сфер — от обработки больших массивов данных, до работы с микросервисами, основанных на распределенной архитектуре.
Чтобы понять, как можно применять Докер на практике, разберем основные примеры использования для чайников.
- Быстрая доставка приложений (команды docker pull и docker push ) позволяет организовать коллективную работу над проектом. Разработчики могут работать удаленно на локальных компьютерах и выполнять пересылку фрагментов кода в контейнер для тестов.
- Развертывание и масштабирование — контейнеры работоспособны на локальных компьютерах, серверах, в облачных онлайн-сервисах. Их можно загружать на хостинг для дальнейшего тестирования, создавать ( docker run ), останавливать ( docker stop ), запускать ( docker start ), приостанавливать и возобновлять ( docker pause и docker unpause соответственно).
- Множественные нагрузки — осуществление запуска большого количества контейнеров на одном и том же оборудовании, поскольку Docker занимает небольшой объем дисковой памяти.
- Диспетчер процессов — возможность мониторинга процессов в Docker посредством команд docker ps и docker top , имеющими схожий синтаксис с Linux.
- Удобный поиск — в реестрах Docker он осуществляется очень просто. Для этого следует использовать команду docker search .
Заключение
Docker является важным инструментом для каждого современного разработчика, как основа аппаратной виртуализации приложений. Эта технология обладает широким функционалом и возможностями для контроля процессов. Докер позволяет не только развертывать контейнеры, но и оперативно масштабировать их экземпляры, работать с многоконтейнерными приложениями (Docker Compose), а также объединять несколько Докер-хостов в единый кластер (Docker Swarm).
Докер характеризуется достаточно простым синтаксисом. Поэтому он довольно прост в освоении как для опытных IT-специалистов, так и для новичков. Программное обеспечение совместимо со всеми версиями операционных систем Linux и Windows, поэтому область применения Docker практически не ограничена.
Чтобы использовать возможности контейнеризации на 100%, Docker нужна подходящая рабочая среда. Правильное решение — VPS от Eternalhost. Мощные виртуальные сервера с возможностью быстрого масштабирования ресурсов!
Источник