Создание образа Docker с нуля

Creating Docker Image From Scratch



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

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







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



Анатомия образа Docker

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



Приложения состоят из слоев программного обеспечения. Образ контейнера WordPress создается с использованием образа контейнера httpd, который, в свою очередь, создается поверх образа Ubuntu. Образ, на основе которого создается новый образ, в терминологии Docker известен как РОДИТЕЛЬСКИЙ ОБРАЗ. В Dockerfile (мы поговорим о том, что означает Dockerfile, немного позже), этот родительский образ упоминается в верхней части файла, как показано ниже:





ИЗ Ubuntu: 18.04
## Остальная часть Dockerfile

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

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



Создание образа Docker с нуля

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

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

С нуля
## Остальная часть файла Dcokerfile

Сначала мы создадим простое приложение hello-world, а затем выясним, какой будет остальная часть файла Dockerfile. Хост-системой является Ubuntu: 18.04 LTS, и мы используем Docker версии 17.12.1-ce для эксперимента.

Создание статического двоичного файла

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

Но большинство приложений высокого уровня зависят от множества системных библиотек (например, glibc, musl, klibc и т. д. ) и множество зависимостей времени выполнения, таких как Python, Node.js или Java Runtime. Бинарный файл приложения не содержит всех доступных библиотек, но когда он начинает выполнение, он вызывает эти библиотеки из операционной системы хоста.

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

Начнем с создания папки MyDockerImage и внутри нее файла hello.cc.

$mkdirMyDockerImage
$CDMyDockerImage
$трогатьhello.cc

Откройте hello.cc с помощью вашего любимого текстового редактора и добавьте в него следующие строки.

#включают
используя пространство имен std;
intглавный(){
Стоимость<< 'Привет! Это сообщение приходит из контейнера п';
возвращение 0;

}

Это простая программа на C ++, которая печатает Hello! Это сообщение …

По причинам, обсуждавшимся ранее, мы скомпилируем это, используя статический флаг. Используемый компилятор g ++ (Ubuntu 7.3.0-16ubuntu3) 7.3.0.

Чтобы скомпилировать программу, в том же каталоге выполните следующую команду:

$ г++ -о привет-статическийПривет.ОКРУГ КОЛУМБИЯ

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

$./Привет

Теперь мы готовы поместить эту простую программу в контейнер.

Dockerfile

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

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

$трогатьDockerfile

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

С нуля
ДОБАВИТЬ привет/
CMD['/Привет']

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

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

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

$сборка докеров--ярлыкПривет .

В –Tag hello флаг устанавливает имя изображения на Привет и точка ( . ) в конце говорит сборка докеров для поиска файла Dockerfile и связанного с ним содержимого в текущем каталоге.

Запуск контейнера Docker

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

$образы докеров

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

$Docker Run привет

Вот и все! Вы создали свой первый минималистичный контейнер с нуля.

Другие варианты

Хотя создание образов с нуля всегда возможно, люди часто склонны создавать образы из других легких дистрибутивов Linux. Например, изображения типа alpine и busybox - это действительно легкие среды с меньшими библиотеками, такими как musl вместо glibc.

Используя их в качестве родительского изображения, используя ОТ альпийского: последний также приведет к уменьшению изображений. Так как базовые образы имеют размер всего 2-5 МБ. Сообщите нам, есть ли какие-либо темы, связанные с Docker, которые вы, возможно, захотите осветить в следующий раз. Вы можете связаться с нами по Твиттер , Facebook или подпишитесь на нас по электронной почте.