что такое докер файл

Docker для самых маленьких автоматизаторов

что такое докер файл. Смотреть фото что такое докер файл. Смотреть картинку что такое докер файл. Картинка про что такое докер файл. Фото что такое докер файл

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

Что такое CI/CD

Это одна из практик devops. Она позволяет разработчикам сосредоточиться на реализации бизнес-требований, качестве кода и безопасности.

что такое докер файл. Смотреть фото что такое докер файл. Смотреть картинку что такое докер файл. Картинка про что такое докер файл. Фото что такое докер файл

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

И все это выполняется автоматически по скриптам. Никаких ручных действий и танцев с бубном. Если на каком-то этапе тесты не проходят, мы даже не деплоим. В итоге сокращается время доставки изменений. Сборка приложения занимает минут 20, еще столько же проходит набор регрессионных тестов в 20-30 потоков. Еще 20 минут требуется на деплой. В итоге мы за час проходим весь процесс от билда до деплоя.

Docker

Важную роль в нашем процессе работы играет Docker.

Я воспринимаю Docker как контейнер, который может жить где угодно. Я могу поставить контейнер, накидать туда все, что хочу, и перетаскивать его целиком. Что-то оттуда доставать, что-то туда класть.

что такое докер файл. Смотреть фото что такое докер файл. Смотреть картинку что такое докер файл. Картинка про что такое докер файл. Фото что такое докер файл

Поясню, как это происходит, на примере случая с тестовым заданием, которое мы даем ручным тестировщикам. Локально тестовое задание у меня отлично запускалось, но не так давно один из кандидатов пожаловался, что у себя запустить не может. Я сообщил все необходимые версии, но задание все равно не запустилось. Выяснилось, что несмотря на попытки кандидата установить нужную версию Java, использовалась другая. Это распространенная ситуация. Но если бы мы завернули тестовый сервис в некую защищенную оболочку, которая работает почти везде, и отдавали бы кандидатам образы, все было бы проще. За редким исключением кандидату было бы достаточно предустановить Docker. Это в разы сократило бы потраченное время.

Но вернемся к Docker.

Dockerfile

В docker-файле используются разного рода инструкции. Вот список тех, что мы используем в повседневной работе (но это не все инструкции):

Управление контейнерами и образами

Общая схема команды для управления контейнерами выглядит следующим образом:

Вместо my_command можно подставить:

Схема команды для управления образами:

Вместо my_command1 можно подставить:

Немного практики

Предположим, у нас есть сервис, который запускается командой:

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

Создадим образ

Для начала в корневой папке проекта создадим текстовый docker-файл. Я нашел базовый образ с уже предустановленной java8 и maven. Возьмем его за основу инструкцией FROM и обозначим рабочую директорию:

Скопируем все файлы нашего проекта в контейнер:

И запустим команду, которая установит Allure:

Здесь мы как раз объединили все в одну большую RUN команду, используя символ переноса строки для удобства чтения. Один RUN создает только один слой вместо нескольких.

Мы качаем архив с Allure, распаковываем его (в данном случае в каталоге allure).

Можно сохранять docker-файл и создавать образ:

Мы не указываем путь к docker-файл, поскольку изначально разместили его в корневом каталоге.

При создании образа ему будет присвоен ID.

Создадим контейнер

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

Запустим автотесты

Итак, сервис запущен в контейнере. Чтобы запустить автотесты снаружи контейнера, которые в нашем случае присутствуют на локальном порту 28080, необходимо использовать команду:

В итоге мы получаем результат в allure-results.

Тесты можно запустить и внутри контейнера. Для этого нам надо попасть внутрь при помощи команды, которая открывает bash:

Запускаем наши тесты внутри контейнера:

В рабочей директории rest-client (мы ее обозначили рабочей в dockerfile) есть папка allure. Когда тесты пройдут, внутри появится папка target. Для получения отчета Allure на локальном хосте можно запустить внутри контейнера Allure Report:

Результаты будут доступны на localhost:28081.

Мы создали докер-образ, запустили на его основе докер-контейнер, пробросили порты. Мы получили доступ к сервису из контейнера на хост-машину и можем запускать тесты как локально, так и непосредственно в контейнере. Также мы запустили Allure Report на определенном порту и получили доступ к результатам локально.

Источник

Изучаем Docker, часть 3: файлы Dockerfile

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

что такое докер файл. Смотреть фото что такое докер файл. Смотреть картинку что такое докер файл. Картинка про что такое докер файл. Фото что такое докер файл

Образы Docker

Вспомните о том, что контейнер Docker — это образ Docker, вызванный к жизни. Это — самодостаточная операционная система, в которой имеется только самое необходимое и код приложения.

Образы Docker являются результатом процесса их сборки, а контейнеры Docker — это выполняющиеся образы. В самом сердце Docker находятся файлы Dockerfile. Подобные файлы сообщают Docker о том, как собирать образы, на основе которых создаются контейнеры.

Контейнеры, как мы выяснили в первом материале этой серии, состоят из слоёв. Каждый слой, кроме последнего, находящегося поверх всех остальных, предназначен только для чтения. Dockerfile сообщает системе Docker о том, какие слои и в каком порядке надо добавить в образ.

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

Базовый образ — это то, что является исходным слоем (или слоями) создаваемого образа. Базовый образ ещё называют родительским образом.

что такое докер файл. Смотреть фото что такое докер файл. Смотреть картинку что такое докер файл. Картинка про что такое докер файл. Фото что такое докер файл

Базовый образ — это то, с чего начинается образ Docker

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

Файлы Dockerfile

В файлах Dockerfile содержатся инструкции по созданию образа. С них, набранных заглавными буквами, начинаются строки этого файла. После инструкций идут их аргументы. Инструкции, при сборке образа, обрабатываются сверху вниз. Вот как это выглядит:

Здесь мы исходим из предположения, в соответствии с которым используется образ Docker, основанный на Unix-подобной ОС. Конечно, тут можно воспользоваться и образом, основанным на Windows, но использование Windows — это менее распространённая практика, работать с такими образами сложнее. В результате, если у вас есть такая возможность, пользуйтесь Unix.

Для начала приведём список инструкций Dockerfile с краткими комментариями.

Дюжина инструкций Dockerfile

Инструкции и примеры их использования

▍Простой Dockerfile

Dockerfile может быть чрезвычайно простым и коротким. Например — таким:

▍Инструкция FROM

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

В этом примере базовый образ хранится в репозитории ubuntu. Ubuntu — это название официального репозитория Docker, предоставляющего базовую версию популярной ОС семейства Linux, которая называется Ubuntu.

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

что такое докер файл. Смотреть фото что такое докер файл. Смотреть картинку что такое докер файл. Картинка про что такое докер файл. Фото что такое докер файл

Структура контейнера (взято из документации)

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

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

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

▍Более сложный Dockerfile

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

Возможно, на первый взгляд этот файл может показаться довольно сложным. Поэтому давайте с ним разберёмся.

Базой этого образа является официальный образ Python с тегом 3.7.2-alpine3.8. Проанализировав этот код можно увидеть, что данный базовый образ включает в себя Linux, Python, и, по большому счёту, этим его состав и ограничивается. Образы ОС Alpine весьма популярны в мире Docker. Дело в том, что они отличаются маленькими размерами, высокой скоростью работы и безопасностью. Однако образы Alpine не отличаются широкими возможностями, характерными для обычных операционных систем. Поэтому для того, чтобы собрать на основе такого образа что-то полезное, создателю образа нужно установить в него необходимые ему пакеты.

▍Инструкция LABEL

что такое докер файл. Смотреть фото что такое докер файл. Смотреть картинку что такое докер файл. Картинка про что такое докер файл. Фото что такое докер файл

Инструкция LABEL (метка) позволяет добавлять в образ метаданные. В случае с рассматриваемым сейчас файлом, она включает в себя контактные сведения создателя образа. Объявление меток не замедляет процесс сборки образа и не увеличивает его размер. Они лишь содержат в себе полезную информацию об образе Docker, поэтому их рекомендуется включать в файл. Подробности о работе с метаданными в Dockerfile можно прочитать здесь.

▍Инструкция ENV

что такое докер файл. Смотреть фото что такое докер файл. Смотреть картинку что такое докер файл. Картинка про что такое докер файл. Фото что такое докер файл

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

▍Инструкция RUN

что такое докер файл. Смотреть фото что такое докер файл. Смотреть картинку что такое докер файл. Картинка про что такое докер файл. Фото что такое докер файл

▍Инструкция COPY

что такое докер файл. Смотреть фото что такое докер файл. Смотреть картинку что такое докер файл. Картинка про что такое докер файл. Фото что такое докер файл

▍Инструкция ADD

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

▍Инструкция CMD

что такое докер файл. Смотреть фото что такое докер файл. Смотреть картинку что такое докер файл. Картинка про что такое докер файл. Фото что такое докер файл

Инструкция CMD предоставляет Docker команду, которую нужно выполнить при запуске контейнера. Результаты выполнения этой команды не добавляются в образ во время его сборки. В нашем примере с помощью этой команды запускается скрипт my_script.py во время выполнения контейнера.

Вот ещё кое-что, что нужно знать об инструкции CMD :

▍Ещё более сложный Dockerfile

Рассмотрим ещё один файл Dockerfile, в котором будут использованы некоторые новые команды.

Кроме того, пакеты Python в образ можно устанавливать с помощью pip, wheel и conda. Если речь идёт не о Python, а о других языках программирования, то при подготовке соответствующих образов могут использоваться и другие менеджеры пакетов.

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

▍Инструкция WORKDIR

что такое докер файл. Смотреть фото что такое докер файл. Смотреть картинку что такое докер файл. Картинка про что такое докер файл. Фото что такое докер файл

▍Инструкция ARG

▍Инструкция ENTRYPOINT

что такое докер файл. Смотреть фото что такое докер файл. Смотреть картинку что такое докер файл. Картинка про что такое докер файл. Фото что такое докер файл

Пункт перехода в какое-то место

▍Инструкция EXPOSE

что такое докер файл. Смотреть фото что такое докер файл. Смотреть картинку что такое докер файл. Картинка про что такое докер файл. Фото что такое докер файл

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

▍Инструкция VOLUME

что такое докер файл. Смотреть фото что такое докер файл. Смотреть картинку что такое докер файл. Картинка про что такое докер файл. Фото что такое докер файл

Инструкция VOLUME позволяет указать место, которое контейнер будет использовать для постоянного хранения файлов и для работы с такими файлами. Об этом мы ещё поговорим.

Итоги

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

Уважаемые читатели! Если вы пользуетесь Docker на практике, просим рассказать о том, как вы пишете Docker-файлы.

Источник

Погружаемся в Docker: Dockerfile и коммуникация между контейнерами

В прошлой статье мы рассказали, что такое Docker и как с его помощью можно обойти Vendor–lock. В этой статье мы поговорим о Dockerfile как о правильном способе подготовки образов для Docker. Также мы рассмотрим ситуацию, когда контейнерам нужно взаимодействовать друг с другом.

что такое докер файл. Смотреть фото что такое докер файл. Смотреть картинку что такое докер файл. Картинка про что такое докер файл. Фото что такое докер файл
В InfoboxCloud мы сделали готовый образ Ubuntu 14.04 с Docker. Не забудьте поставить галочку «Разрешить управление ядром ОС» при создании сервера, это требуется для работы Docker.

Dockerfile

Подход docker commit, описанный в предыдущей статье, не является рекомендованным для Docker. Его плюс состоит в том, что мы настраиваем контейнер практически так, как привыкли настраивать стандартный сервер.

Вместо этого подхода мы рекомендуем использовать подход Dockerfile и команду docker build. Dockerfile использует обычный DSL с инструкциями для построения образов Docker. После этого выполняется команда docker build для построения нового образа с инструкциями в Dockerfile.

Написание Dockerfile

Давайте создадим простой образ с веб-сервером с помощью Dockerfile. Для начала создадим директорию и сам Dockerfile.

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

Добавим в Dockerfile информацию по построению образа:

Также Dockerfile поддерживает комментарии. Любая строчка, начинающаяся с # означает комментарий.

Первая инструкция в Dockerfile всегда должна быть FROM, указывающая, из какого образа нужно построить образ. В нашем примере мы строим образ из базового образа ubuntu версии 14:04.

Далее мы указываем инструкцию MAINTAINER, сообщающую Docker автора образа и его email. Это полезно, чтобы пользователи образа могли связаться с автором при необходимости.

Инструкция RUN исполняет команду в конкретном образе. В нашем примере с помощью ее мы обновляем APT репозитории и устанавливаем пакет с NGINX, затем создаем файл /usr/share/nginx/html/index.html.

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

Далее мы указываем инструкцию EXPOSE, которая говорит Docker, что приложение в контейнере должно использовать определенный порт в контейнере. Это не означает, что вы можете автоматически получать доступ к сервису, запущенному на порту контейнера (в нашем примере порт 80). По соображениям безопасности Docker не открывает порт автоматически, но ожидает, когда это сделает пользователь в команде docker run. Вы можете указать множество инструкций EXPOSE для указания, какие порты должны быть открыты. Также инструкция EXPOSE полезна для проброса портов между контейнерами.

Строим образ из нашего файла

, где trukhinyuri – название репозитория, где будет храниться образ, nginx – имя образа. Последний параметр — путь к папке с Dockerfile. Если вы не укажете название образа, он автоматически получит название latest. Также вы можете указать git репозиторий, где находится Dockerfile.

В данном примере мы строим образ из Dockerfile, расположенном в корневой директории Docker.

Что произойдет, если инструкция не исполнится?

Давайте переименуем в Dockerfile nginx в ngin и посмотрим.

что такое докер файл. Смотреть фото что такое докер файл. Смотреть картинку что такое докер файл. Картинка про что такое докер файл. Фото что такое докер файл

Использования кеша сборок для шаблонизации

Используя кеш сборок можно строить образы из Dockerfile в форме простых шаблонов. Например шаблон для обновления APT-кеша в Ubuntu:

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

Инструкции Dockerfile

Давайте рассмотрим и другие инструкции Dockerfile. Полный список можно посмотреть тут.

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

ENTRYPOINT

Часто команду CMD путают с ENTRYPOINT. Разница в том, что вы не можете перегружать ENTRYPOINT при запуске контейнера.

При запуске контейнера параметры передаются команде, указанной в ENTRYPOINT.

Можно комбинировать ENTRYPOINT и CMD.

WORKDIR

С помощью WORKDIR можно установить рабочую директорию, откуда будут запускаться команды ENTRYPOINT и CMD.

Специфицирует пользователя, под которым должен быть запущен образ. Мы можем указать имя пользователя или UID и группу или GID.

VOLUME

Инструкция VOLUME добавляет тома в образ. Том — папка в одном или более контейнерах или папка хоста, проброшенная через Union File System (UFS).
Тома могут быть расшарены или повторно использованы между контейнерами. Это позволяет добавлять и изменять данные без коммита в образ.

В примере выше создается точка монтирования /opt/project для любого контейнера, созданного из образа. Таким образом вы можете указывать и несколько томов в массиве.

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

Источником может быть URL, имя файла или директория.

В последнем примере архив tar.gz будет распакован в /var/www/wordpress. Если путь назначения не указан — будет использован полный путь включая директории.

Инструкция COPY отличается от ADD тем, что предназначена для копирования локальных файлов из билд-контекста и не поддерживает распаковки файлов:

ONBUILD

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

Коммуникация между контейнерами

В предыдущей статье было показано, как запускать изолированные контейнеры Docker и как пробрасывать файловую систему в них. Но что, если приложениям нужно связываться друг с другом. Есть 2 способа: связь через проброс портов и линковку контейнеров.

Проброс портов

Такой способ связи уже был показан ранее. Посмотрим на варианты проброса портов чуть шире.
Когда мы используем EXPOSE в Dockerfile или параметр -p номер_порта – порт контейнера привязывается к произвольному порту хоста. Посмотреть этот порт можно командой docker ps или docker port имя_контейнера номер_порта_в_контейнере. В момент создания образа мы можем не знать, какой порт будет свободен на машине в момент запуска контейнера.

Можно привязать UDP порты, указав /udp:

Линковка контейнеров

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

Префикс DB_ был взят из alias контейнера.

Можно просто использовать информацию из hosts, например команда ping db (где db – alias) будет работать.

Заключение

В этой статье мы научились использовать Dockerfile и организовывать связь между контейнерами. Это только вершина айсберга, очень многое осталось за кадром и будет рассмотрено в будущем. Для дополнительного чтения рекомендуем книгу The Docker Book.

Готовый образ с Docker доступен в облаке InfoboxCloud.

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

Источник

Docker. Зачем и как

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

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

Начну я с описания нескольких типичных проблем.

Проблемы

Первая проблема — как передать продукт клиенту.

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

Всё усугубляется если продукт тиражируемый и вместо одного клиента у вас сотни или тысячи покупателей. И становится еще сложнее, если вспомнить о необходимости установки новых версий продукта.

Вторая проблема — тиражируемость. Пусть вам нужно поднять 5 (или 50) почти одинаковых серверов. Делать это вручную долго, дорого и подвержено ошибкам.

Наконец, третья проблема — переиспользуемость. Предположим у вас есть отдел, который делает браузерные игры. Предположим, что их у вас уже несколько. И все они используют один и тот же технологический стэк (например — java-tomcat-nginx-postgre). Но при этом, чтобы поставить новую игру вы вынуждены заново подготавливать на новом сервере почти одинаковую конфигурацию. Вы не можете просто так взять и сказать — «хочу сервер, как в игре странники но только с другим веб архивом»

Обычные решения

Как обычно решаются эти проблемы.

Установочный скрипт

Первый подход я уже упомянул — вы можете написать скрипт, который установит всё, что вам нужно и запускать его на всех нужных серверах. ( Скрипт может быть как простым sh файлом, так и чем-то сложным, созданным с использованием специальных инструментов).

Недостатки этого подхода — хрупкость и неустойчивость к ошибкам. Как бы хорошо не был написан скрипт, рано или поздно на какой-то машине он упадёт. И после этого падения машина фактически окажется «испорченной» — просто так «откатить» те действия, которые скрипт успел выполнить, у вашего клиента не получится.

Облачные сервисы

Второй подход — использование облачных сервисов. Вы вручную устанавливаете на виртуальный сервер всё, что вам нужно. Затем делаете его image. И далее клонируете его столько раз, сколько вам надо.

Недостатка здесь два. Во-первых, vendor-lock-in. Вы не можете запускать свое решение вне выбранного облака, что не всегда удобно и может привести к потерям несогласных с этим выбором клиентов. Во-вторых, облака медленны. Виртуальные (и даже «bare-metal») сервера предоставляемые облаками на сегодняшний день сильно уступают по производительности dedicated серверам.

Виртуальные машины

Третий подход — использование виртуальных машин. Здесь тоже есть недостатки:

Размер — не всегда удобно качать образ виртуальной машины, который может быть довольно большим. При этом, любое изменение внутри образа виртуальной машины требует скачать весь образ заново.

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

Подход докера — контейнеризация

И вот тут появляется docker, в котором

Как работает docker

Создание образа

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

Кроме этого, мы можем копировать в наш образ любые локальные файлы при помощи директивы 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)

Выводы

Таким образом докер очень хорошо подходит для решения перечисленных выше задач:

Источник

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

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