Образы Docker

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

Что такое образ Docker?

Возможно, вы уже знакомы с термином «образ» в контексте виртуализации с виртуальными машинами (ВМ). Обычно образ ВМ представляет собой копию операционной системы. Образ ВМ может содержать и другие установленные компоненты, такие как базы данных и веб-серверы. Этот термин появился в те времена, когда программное обеспечение распространялось на оптических носителях информации, таких как CD-ROM и DVD. Если вы хотели создать локальную копию носителя данных, вам нужно было создать «образ» с помощью специального программного обеспечения.

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

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

Контейнеры Docker и образы Docker — это тесно связанные понятия. По существу, не только контейнер Docker может быть создан из образа Docker, но и новый образ может быть создан из работающего контейнера. Именно поэтому мы говорим, что между образами Docker и контейнерами Docker существует связь «курица и яйцо»:

Команда Docker

Описание

Аналогия с курицей и яйцом

docker run <image-id>

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

Цыпленок вылупляется из яйца

docker commit <container-id>

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

Курица откладывает новое яйцо

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

Образ Docker — это неизменяемый шаблон, который можно многократно использовать для создания контейнеров Docker. Образ содержит всю информацию и зависимости, необходимые для запуска контейнера, включая все основные программные библиотеки и пользовательские интерфейсы. Обычно на борту имеется среда командной строки («оболочка») и реализация стандартной библиотеки C. Ниже приведен обзор официального образа «Alpine Linux»:

Ядро Linux

Стандартная библиотека C

Команда Unix

С хоста

musl libc

BusyBox

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

Область применения

Программные компоненты

Языки программирования

PHP, Python, Ruby, Java, JavaScript

Инструменты разработки

node/npm, React, Laravel

Системы баз данных

MySQL, Postgres, MongoDB, Redis

Веб-серверы

Apache, nginx, lighttpd

Кэши и прокси-серверы

Varnish, Squid

Системы управления контентом

WordPress, Magento, Ruby on Rails

Чем образ Docker отличается от контейнера Docker?

Как мы видели, образы Docker и контейнеры Docker тесно связаны между собой. Чем же отличаются эти два понятия?

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

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

Если это описание кажется слишком абстрактным, воспользуйтесь примером из вашей повседневной жизни: Представьте себе образ Docker как DVD-диск. Сам DVD-диск инертен — он сидит в своем корпусе и ничего не делает. Он постоянно занимает одно и то же ограниченное пространство в комнате. Содержимое становится «живым» только тогда, когда DVD воспроизводится в специальной среде (DVD-плеер).

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

Концепция Docker

Аналогия

Режим

Состояние

Потребление ресурсов

Образ Docker

DVD

Инертный

«Только для чтения»/неизменяемый

Фиксированный

Докер-контейнер

«живой»

Воспроизведение фильма

Изменяется со временем

Изменяется в зависимости от использования

Как и где используются образы Docker?

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

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

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

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

Образы Docker в сервис-ориентированной архитектуре (SOA)

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

Образы Docker для хостинг-провайдеров/PaaS

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

Как создается образ Docker?

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

  • Слои образа содержат данные, добавленные в результате операций, выполняемых в файловой системе. Слои накладываются друг на друга, а затем сводятся к единому уровню объединенной файловой системой.
  • Родительский образ подготавливает основные функции образа и закрепляет его в главном файловом каталоге экосистемы Docker.
  • Манифест образа описывает состав образа и идентифицирует слои образа.

Что делать, если вы хотите преобразовать образ Docker в один файл? Это можно сделать с помощью команды «docker save» в командной строке. При этом создается файл сохранения .tar, который затем можно легко перемещать между системами. С помощью следующей команды образ Docker с именем «busybox» будет записан в файл «busybox.tar»:

docker save busybox > busybox.tar

Часто вывод команды «docker save» передается в Gzip в командной строке. Таким образом, данные сжимаются после вывода в файл .tar:

docker save myimage:latest | gzip > myimage_latest.tar.gz

Файл образа, созданный с помощью команды «docker save», может быть загружен на локальный хост Docker в качестве образа Docker с помощью команды «docker load»:

docker load busybox.tar

Слои изображений

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

Мы можем отобразить слои образа Docker, используя команду «Docker image inspect» в командной строке. Эта команда возвращает документ JSON, который мы можем обработать с помощью стандартного инструмента jq:

Docker image inspect <image-id> | jq -r '.[].RootFS.Layers[]'

Для повторного объединения изменений в слоях используется специальная файловая система. Эта объединенная файловая система накладывает все слои друг на друга, чтобы создать последовательную структуру папок и файлов на интерфейсе. Исторически для реализации объединенной файловой системы использовались различные технологии, известные как «драйверы хранения». Сегодня в большинстве случаев рекомендуется использовать драйвер хранения «overlay2»:

Драйвер хранилища

Комментарий

overlay2

Рекомендуется для использования сегодня

aufs, overlay

Использовался в более ранних версиях

Можно вывести используемый драйвер хранения образа Docker. Для этого мы можем использовать команду «Docker image inspect» в командной строке. Она возвращает документ в формате JSON, который мы можем затем обработать с помощью стандартного инструмента jq:

Docker image inspect <image-id> | jq -r '.[].GraphDriver.Name'

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

Родительские образы

Образ Docker обычно имеет базовый «родительский образ». В большинстве случаев родительский образ определяется директивой FROM в файле docker. Родительский образ определяет основу, на которой базируются производные образы. На существующие слои изображения накладываются дополнительные слои.

При «наследовании» от родительского образа образ Docker помещается в каталог файлов, содержащий все существующие образы. Возможно, вам интересно, где начинается главный каталог файлов? Его корни определяются несколькими специальными «базовыми образами». В большинстве случаев базовый образ задается с помощью директивы «FROM scratch» в файле docker. Однако существуют и другие способы создания базового образа. Подробнее об этом вы можете узнать в разделе «Откуда берутся образы Docker?».

Манифесты образов

Как мы уже видели, образ Docker состоит из нескольких слоев. Вы можете использовать команду «Docker image pull» для получения образа Docker из онлайн-реестра. В этом случае не загружается отдельный файл. Вместо этого локальный демон Docker загружает отдельные слои и сохраняет их. Откуда же берется информация об отдельных слоях?

Информация о том, из каких слоев состоит образ Docker, содержится в манифесте образа. Манифест образа — это JSON-файл, который полностью описывает образ Docker и содержит следующее:

  • Информация о версии, схеме и размере
  • Криптографические хэши используемых слоев образа
  • Информация о доступных процессорных архитектурах

Для четкой идентификации образа Docker создается криптографический хэш манифеста образа. При использовании команды «Docker image pull» загружается файл манифеста. Затем локальный демон Docker получает отдельные слои образа.

Откуда берутся образы Docker?

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

  1. Извлечение существующих образов Docker из реестра
  2. Создание новых образов Docker

Извлечение существующих образов Docker из реестра

Часто проект Docker начинается с извлечения существующего образа Docker из реестра. Это платформа, доступная по сети, которая предоставляет образы Docker. Локальный узел Docker взаимодействует с реестром для загрузки образа Docker после выполнения команды «Docker image pull».

Существуют общедоступные онлайн-реестры, которые предлагают широкий выбор существующих образов Docker для использования. На момент написания этой статьи в официальном реестре Docker «Docker Hub» было более восьми миллионов свободно доступных образов Docker. В дополнение к образам Docker, «Azure Container Registry» компании Microsoft включает другие образы контейнеров в различных форматах. Вы также можете использовать платформу для создания собственных частных реестров контейнеров.

Помимо вышеупомянутых онлайн-реестров, вы также можете самостоятельно разместить локальный реестр. Например, крупные организации часто используют эту возможность, чтобы предоставить своим командам защищенный доступ к самостоятельно созданным образам Docker. Компания Docker создала Docker Trusted Registry (DTR) именно для этой цели. Это локальное решение для создания собственного реестра в вашем собственном вычислительном центре.

Создание новых образов Docker

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

  1. Построить на основе родительского образа с помощью Dockerfile
  2. Сгенерировать образ из запущенного контейнера
  3. Создать новый базовый образ

Наиболее распространенным способом создания нового образа Docker является написание Dockerfile. Dockerfile содержит специальные команды, которые определяют родительский образ и все необходимые изменения. Вызов команды «Docker image build» создаст новый образ Docker на основе Dockerfile. Вот краткий пример:

# Create Dockerfile on the command line
cat <<EOF > ./Dockerfile
FROM busybox
RUN echo "hello world"
EOF

# Create a Docker image from a Dockerfile
Docker image build

Исторически термин «образ» происходит от «создания изображения» носителя данных. В контексте виртуальных машин (ВМ) можно создать моментальный снимок образа работающей ВМ. Аналогичный процесс можно выполнить с помощью Docker. С помощью команды «docker commit» мы можем создать образ работающего контейнера в виде нового образа Docker. Все изменения, внесенные в контейнер, будут сохранены:

docker commit <container-id>

Кроме того, с помощью команды «docker commit» мы можем передать инструкции Dockerfile. Модификации, закодированные в инструкциях, становятся частью нового образа Docker:

docker commit --change <dockerfile instructions> <container-id> 

Мы можем использовать команду «Docker image history», чтобы отследить, какие изменения были внесены в образ Docker позже:

Docker image history <image-id>

Как мы видели, мы можем основывать новый образ Docker на родительском образе или на статусе запущенного контейнера. Но как создать новый образ Docker с нуля? Есть два разных способа сделать это. Вы можете использовать Dockerfile со специальной директивой «FROM scratch», как описано выше. При этом создается новый минимальный базовый образ.

Если вы предпочитаете не использовать образ Docker scratch, вы должны использовать специальный инструмент, например debootstrap, и подготовить дистрибутив Linux. Затем он будет упакован в файл tarball с помощью команды tar и импортирован в локальный хост Docker с помощью команды «Docker image import».

Наиболее важные команды работы с образами Docker

Команда образа Docker

Объяснение

Сборка образа Docker

Создает образ Docker из Docker-файла.

История создания образа Docker

Показывает шаги, предпринятые для создания образа Docker

Импорт образа Docker

Создает образ Docker из tarball-файла

Проверка образа Docker

Показывает подробную информацию об образе Docker

Загрузка образа Docker

Загружает файл образа, созданный с помощью команды «Docker image save».

Docker image ls / Docker images

Перечисляет образы, доступные на хосте Docker

Docker image prune

Удаляет неиспользуемые образы Docker с хоста Docker

Docker image pull

Извлекает образ Docker из реестра

Docker image push

Отправляет образ Docker в реестр

Docker image rm

Удаляет образ Docker с локального узла Docker.

Сохранение образа Docker

Создает файл образа

Метка образа Docker

Пометить образ Docker

Оцените статью
cdelat.ru
Добавить комментарий